12
votes

I've used StructureMap in MVC2/3 many times without any concern, but I guess handling IoC is different in MVC4. When i used StructureMap for handling IoC in MVC4 I get the following exception.:

No parameterless constructor defined for this object

Why? I have not found any correct result in google except this: IoC Not Working In MVC4 These is my IoC classes:

public static class IoC {
    public static IContainer Initialize() {
        ObjectFactory.Initialize(x =>
                    {
                        x.Scan(scan =>
                        {
                            //scan.Assembly("DLL.Core");
                            scan.Assembly("DLL.CMS");
                            scan.TheCallingAssembly();
                            scan.WithDefaultConventions();
                        });
                        x.For<IDbContext>().Use<ModelEntities>();
                        x.For(typeof(IRepository<>)).Use(typeof(Repository<>));
                        x.For<IHttpControllerActivator>();
                        x.For<IController>();
                    });

        return ObjectFactory.Container;
    }

And SmDependencyResolver is:

    public class SmDependencyResolver : IDependencyResolver
{
    private readonly IContainer _container;

    public SmDependencyResolver(IContainer container)
    {
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        if (serviceType == null) return null;
        try
        {
            return serviceType.IsAbstract || serviceType.IsInterface
                     ? _container.TryGetInstance(serviceType)
                     : _container.GetInstance(serviceType);
        }
        catch
        {

            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances(serviceType).Cast<object>();
    }
}

And my error is:

No parameterless constructor defined for this object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[MissingMethodException: No parameterless constructor defined for this object.] System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241 System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67

[InvalidOperationException: An error occurred when trying to create a controller of type 'Parsian.Web.Areas.Dashboard.Controllers.MemberController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +196 System.Web.Mvc.<>c__DisplayClass6.b__2() +49 System.Web.Mvc.<>c__DisplayClassb1.<ProcessInApplicationTrust>b__a() +13 System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7 System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func
1 func) +124 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862676 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

Thanks for correct answers.

4
Can you post the full error message? Do you set the SmDependencyResolver as DependencyResolver in the Global.asax or in the PreApplicationStartMethod?. Because I've just created a MVC4 project with the StructureMap.MVC3 nuget package and it works as excepted...nemesv
i dont want use this package, I add only structuremap package (dll) to project with nuget.Arash Karami
Just use the DefaultControllerFactory.Rookian
What is the meaning?How do this?Arash Karami
Make sure you are wiring up the DependencyResolver in your global.asax, and that you are mapping the appropriate resolvers in your SM setup. That error is usually what you get when you don't do one of those two things.Ely

4 Answers

10
votes

oops.I found an emergency solution :) Try to implement a class from IControllerActivator

public class StructureMapControllerActivator : IControllerActivator
{
   private IContainer _container;
    
   public StructureMapControllerActivator(IContainer container)
   {
       _container = container;
   }
    
   public IController Create(RequestContext requestContext, Type controllerType)
   {
       return _container.GetInstance(controllerType) as IController;
   }
}

and then register it to the IoC class:

 x.For<IControllerActivator>().Use<StructureMapControllerActivator>();

and then enjoy it. Good luck

3
votes

If you remove any old configuration for structuremap and install structurmap.mvc4 from nuget then configure your IoC container, you don't have any problems.

2
votes

try adding this class as your ControllerFactory, I've actually seen the error above in MVC3 and this usually fixed it for me

public class StructureMapControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        try
        {
            return (controllerType == null)
                       ? base.GetControllerInstance(requestContext, controllerType)
                       : ObjectFactory.GetInstance(controllerType) as IController;
        }
        catch (Exception ex)
        {
            return null;
        }
    }
}
0
votes

Using StructureMap.MVC5.Update I had to do this or else the nested IContainer was already disposed (weird) :

public class StructureMapControllerActivator : IControllerActivator
{
    public IController Create(RequestContext requestContext, Type controllerType)
    {
        return StructuremapMvc.StructureMapDependencyScope.GetInstance(controllerType) as IController;
    }
}