2013-07-03 54 views
5

我遇到了一個MVC4項目的問題,該項目在一臺計算機(VS 2012)上工作正常,但在另一臺(VS 2010)上沒有問題。 (我希望衝突的VS版本不是問題,但該項目最初來自VS2010電腦,我在2012年做了一些工作,現在我試圖把它放回到2010年)。無參數控制器構造函數Autofac

我得到一個「確保控制器具有一個無參數的公共構造函數」錯誤,但我認爲我的控制器有一個默認:

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問題。在ContainerBuilder.BuildContainer()builder.Register(context => new SessionStateProvider()).As<IStateProvider>();:我只是做了Install-Package Autofac並在該項目中的最新版本(3.0.2),和堆棧跟蹤看起來是這樣的:

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這樣。在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堆棧跟蹤的),和我感謝任何幫助。

+2

VS2010帶有.NET 4.0,但與.NET 4.5這樣的框架的版本差異vs2012造成問題的原因不是視覺工作室。您可以嘗試在vs2010機器上安裝.net 4.5,或者您可以嘗試使用舊版本的Autofac(如2.6)來查看它是否可以在兩種環境中使用。 – nemesv

+1

'InvalidProgramException' - 當Autofac試圖構建解析器時,看起來像是一個.NET Framework錯誤。 –

+0

@nemesv您可以添加Microsoft Bcl程序包以訪問4.0中的大多數4.5功能。 (但要小心,使用源代碼控制時可能會造成混亂) –

回答

0

嗨,我不測試在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/