2013-07-03 40 views
5

Tôi đang gặp vấn đề với một dự án MVC4 hoạt động tốt trên một máy tính (VS 2012), nhưng không hoạt động trên một máy tính khác (VS 2010).Bộ điều khiển Parameterless Constructor Autofac

(Tôi hy vọng các phiên bản VS xung đột không phải là vấn đề, nhưng dự án ban đầu đến từ máy tính VS2010, tôi đã thực hiện một số công việc vào năm 2012 và bây giờ tôi đang cố gắng đưa nó trở lại vào năm 2010.)

tôi nhận được một "Hãy chắc chắn rằng bộ điều khiển có một constructor nào parameterless" lỗi nhưng tôi nghĩ điều khiển của tôi có mặc định một:

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

các mã mà ném lỗi là ở ControllerFactory tôi:

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

tôi thấy một câu hỏi tương tự như này, nơi người thực hiện giao diện không có nhà xây dựng công cộng, nhưng một lần nữa, tôi nghĩ rằng tôi không có mặc định một:

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

Dựa trên câu trả lời cho các câu hỏi khác và stacktrace, tôi nhìn vào các vấn đề của Autofac. Tôi chỉ làm Install-Package Autofac và có mới nhất (3.0.2) trong dự án, và stacktrace trông như thế này:

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) 

Điều này xảy ra ngay cả khi tôi đang thực sự đăng ký IStateProvider như thế này: builder.Register(context => new SessionStateProvider()).As<IStateProvider>(); trong ContainerBuilder.BuildContainer(). Trong Global.asax Tôi cũng đăng ký 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(); 
} 

Tôi không chắc chắn những gì các bước có thể tiếp theo là dành cho cố gắng giải quyết này (tôi lối thoát về chiều sâu của tôi phân tích các stacktrace Autofac), và tôi 'd đánh giá cao sự giúp đỡ nào.

+2

VS2010 đi kèm với .net 4.0 nhưng vs2012 với .net 4.5 nên sự khác biệt phiên bản khuôn khổ gây ra vấn đề không phải là visual studio. Bạn có thể thử intall .net 4.5 trên máy vs2010 hoặc bạn có thể thử sử dụng phiên bản cũ hơn của Autofac như 2.6 để xem liệu nó có hoạt động trong cả hai môi trường hay không. – nemesv

+1

'InvalidProgramException' - có vẻ như lỗi .NET Framework khi Autofac đang cố gắng xây dựng trình phân giải. –

+0

@nemesv Bạn có thể thêm gói Microsoft Bcl để truy cập hầu hết các tính năng 4.5 trong 4.0. (Nhưng xem ra, họ có thể làm cho một mớ hỗn độn khi sử dụng kiểm soát nguồn) –

Trả lời

0

Xin chào, tôi không kiểm tra điều đó trong VS 2010 vì tôi không có. Nhưng trong VS 2013 của tôi hoạt động tốt.

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/