【问题标题】:Parameterless Controller Constructor Autofac无参数控制器构造函数 Autofac
【发布时间】:2013-07-01 12:36:50
【问题描述】:

我遇到了一个 MVC4 项目的问题,该项目在一台计算机 (VS 2012) 上运行良好,但在另一台计算机 (VS 2010) 上运行良好。

(我希望VS版本冲突不是问题,但是项目最初来自VS2010计算机,我在2012年做了一些工作,现在我试图把它放回2010年。)

我收到“确保控制器具有无参数的公共构造函数”错误,但我确实认为我的控制器具有默认值:

public class HomeController : AuthorizedControllerBase
{
    public ViewResult Index()
    {
        return View();
    }
}

引发错误的代码在我的 ControllerFactory 中:

public class ControllerFactory : DefaultControllerFactory
{
    private readonly IStateProvider _sessionStateProvider;

    public ControllerFactory(IStateProvider aStateProvider)
    {
        _sessionStateProvider = aStateProvider;
    }

    public override IController CreateController
    (System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        IController controller = base.CreateController(requestContext, controllerName);
        if (controller is BaseController)
        {
            var baseController = (BaseController)controller; // ***This line***
            baseController.SessionData = _sessionStateProvider;
        }
        return controller;
    }
}

我看到一个类似的问题,接口实现者没有公共构造函数,但我认为我的确实有默认构造函数:

public class SessionStateProvider : IStateProvider
{
    public object this[string key]
    {
        get
        {
            return HttpContext.Current.Session[key];
        }
        set
        {
            HttpContext.Current.Session[key] = value;
        }
    }

    public void Remove(string key)
    {
        HttpContext.Current.Session.Remove(key);
    }
}

根据对其他问题的回答和堆栈跟踪,我正在调查 Autofac 问题。我刚刚做了Install-Package Autofac 并且在项目中有最新的(3.0.2),stacktrace 看起来像这样:

InnerException: Autofac.Core.DependencyResolutionException
   Message=An exception was thrown while executing a resolve operation. See the InnerException for details. ---> Common Language Runtime detected an invalid program. (See inner exception for details.)
   Source=Autofac
   StackTrace:
        at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
        at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
        at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
        at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
        at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
        at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)
        at Autofac.Integration.Mvc.AutofacDependencyResolver.GetService(Type serviceType)
        at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
   InnerException: System.InvalidProgramException
        Message=Common Language Runtime detected an invalid program.
        Source=Autofac
        StackTrace:
             at Autofac.Core.Activators.Reflection.ConstructorParameterBinding..ctor(ConstructorInfo ci, IEnumerable`1 availableParameters, IComponentContext context)
             at Autofac.Core.Activators.Reflection.ReflectionActivator.<>c__DisplayClass5.<GetConstructorBindings>b__4(ConstructorInfo ci)
             at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
             at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
             at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
             at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
             at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
             at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
             at Autofac.Core.Resolving.InstanceLookup.Execute()
             at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
             at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
             at Autofac.Core.Registration.ExternalRegistrySource.<>c__DisplayClass8.<RegistrationsFor>b__3(IComponentContext c, IEnumerable`1 p)
             at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
             at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
             at Autofac.Core.Resolving.InstanceLookup.Execute()
             at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
             at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
             at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)

即使我确实像这样注册 IStateProvider,也会发生这种情况:builder.Register(context =&gt; new SessionStateProvider()).As&lt;IStateProvider&gt;(); in ContainerBuilder.BuildContainer()。在 Global.asax 中,我还注册了 ControllerFactory:

protected void Application_Start()
{
    Container = ContainerBuilder.BuildContainer();
    var autofacDependencyResolver = new AutofacDependencyResolver(Container);
    DependencyResolver.SetResolver(autofacDependencyResolver);
    ControllerBuilder.Current.SetControllerFactory(new ControllerFactory(Container.Resolve<IStateProvider>()));
    Application_Start_MVC();
}

我不确定尝试解决此问题的下一个可能步骤是什么(我已经超出了解析 Autofac 堆栈跟踪的深度),如果有任何帮助,我将不胜感激。

【问题讨论】:

  • VS2010 带有 .net 4.0 但 vs2012 带有 .net 4.5,因此导致问题的框架版本差异不是 Visual Studio。您可以尝试在 vs2010 机器上安装 .net 4.5,也可以尝试使用旧版本的 Autofac(如 2.6)来查看它是否适用于两种环境。
  • InvalidProgramException -- 当 Autofac 尝试构建解析器时,这似乎是一个 .NET Framework 错误。
  • @nemesv 您可以添加 Microsoft Bcl 包以访问 4.0 下的大部分 4.5 功能。 (但要注意,使用源代码控制时它们会弄得一团糟)

标签: c# asp.net-mvc autofac


【解决方案1】:

嗨,我没有在 VS 2010 中测试它,因为我没有它。但在我的 VS 2013 中工作正常。

 public static class DependencyInjection
    {
        public static void Init()
        {
            // Create the container builder.
            var builder = new ContainerBuilder();

            //Register controllers
            builder.RegisterControllers(Assembly.GetExecutingAssembly());

            // Register other dependencies.
            builder.RegisterType<SessionStateProvider>().As<IStateProvider>().InstancePerHttpRequest();

            // Build the container.
            var container = builder.Build();

            //Configure ASP.NET MVC the dependency resolver
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        }
    }

 public class SessionStateProvider:IStateProvider
{
    public object this[string key]
    {
        get
        {
            return HttpContext.Current.Session[key];
        }
        set
        {
            HttpContext.Current.Session[key] = value;
        }
    }

    public void Remove(string key)
    {
        HttpContext.Current.Session.Remove(key);
    }
}

public interface IStateProvider
{
  object this[string key] { get; set; }
  void Remove(string key);

}

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        DependencyInjection.Init();
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

public abstract class BaseController : Controller
{
    protected IStateProvider SessionStateProvider { get; private set; }
    public BaseController()
    {
        SessionStateProvider = DependencyResolver.Current.GetService<IStateProvider>();
    }
}


public class HomeController : BaseController
{

    public ActionResult Index()
    {
        SessionStateProvider["1"] = 2;
        return View();
    }

}

Autofac -> https://www.nuget.org/packages/Autofac.Mvc4/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    相关资源
    最近更新 更多