问题 Structuremap不适用于MVC4


我用过 StructureMap 在MVC2 / 3中多次没有任何顾虑,但我想在MVC4中处理IoC是不同的。 我用的时候 StructureMap 为了处理MVC4中的IoC我得到以下异常:

没有为此对象定义无参数构造函数

为什么? 我没有在谷歌找到任何正确的结果,除了这个: IoC不适用于MVC4 这些是我的IoC课程:

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;
    }

而SmDependencyResolver是:

    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>();
    }
}

我的错误是:

没有为此对象定义无参数构造函数。       描述:执行当前Web请求期间发生未处理的异常。请查看堆栈   跟踪以获取有关错误及其来源的更多信息   代码。

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

来源错误:

在执行期间生成了未处理的异常   当前的网络请求。有关的来源和位置的信息   可以使用下面的异常堆栈跟踪来识别异常。

堆栈跟踪:

[MissingMethodException:没有为此定义无参数构造函数   object。] System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,   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:尝试创建时出错   控制器类型   'Parsian.Web.Areas.Dashboard.Controllers.MemberController'。确保   控制器有一个无参数的公共构造函数。]
  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个功能)   +124 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,AsyncCallback回调,对象状态)+98
  System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext,   AsyncCallback回调,对象状态)+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

谢谢你的正确答案。


8786
2018-03-04 18:11


起源

你能发布完整的错误信息吗?你设置了吗? SmDependencyResolver 如 DependencyResolver 在Global.asax或 PreApplicationStartMethod?。因为我刚刚创建了一个MVC4项目 StructureMap.MVC3 nuget包,它作为例外... - nemesv
我不想使用这个包,我只添加了structmap包(dll)与nuget项目。 - Arash Karami
只需使用DefaultControllerFactory。 - Rookian
这是什么意思?这是怎么做到的? - Arash Karami
确保在global.asax中连接DependencyResolver,并在SM设置中映射相应的解析器。这个错误通常是你不做这两件事之一时得到的。 - Ely


答案:


ooops.I找到了一个紧急解决方案:)尝试从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;
        }
}

然后将其注册到IoC类:

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

然后享受它。 祝你好运


9
2018-03-05 20:43



Structuremap不需要这样做。看到 这个博客 发布为什么IControllerActivator扩展点在MVC3 +中。 - PHeiberg
而 IControllerActivator 在技​​术上不需要,你可能仍然需要一个,至少在开发过程中。为什么?好吧,因为如果你没有和你的DI容器抛出错误,那么MVC会吃错误,然后再试一次 Activator.CreateInstance,这可能会产生如上所述的错误。这使得很难确定出了什么问题。 :-( - Kevin Cathcart


如果删除任何旧的structuremap配置并安装 来自nuget的structurmap.mvc4 然后配置你的IoC容器,你没有任何问题。


3
2017-10-19 20:57





尝试将此类添加为您的ControllerFactory,我实际上已经在MVC3中看到了上面的错误,这通常会为我修复它

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;
        }
    }
}

2
2018-03-05 13:19



这是在MVC中实现依赖注入的一种非常古老的方式... Crica MVC1-2。 MVC 3和4将IDependencyResolver实现为IOC容器的接口。 - reach4thelasers
@ reach4thelasers IDependencyResolver是否负责将依赖项注入我的控制器构造函数? - Rookian


运用 StructureMap.MVC5.Update 我必须这样做,否则嵌套的IContainer已被处理(奇怪):

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

0
2018-03-16 17:32