2013-07-03 12 views
5

Sto avendo problemi con un progetto che funziona MVC4 frustrante bene su un computer (VS 2012), ma non dall'altra (VS 2010).senza parametri controller Constructor Autofac

(Spero che le versioni VS in conflitto non siano il problema, ma il progetto originariamente proveniva dal computer VS2010, ho lavorato un po 'sul 2012 e ora sto cercando di rimetterlo sul 2010.

ottengo "assicurarsi che il controller ha una senza parametri costruttore pubblico" errore, ma io credo che il mio controller è quello di default:

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

il codice che genera l'errore è nel mio 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; 
    } 
} 

Ho visto una domanda simile a questo, dove il realizzatore di interfaccia non aveva alcun costruttore pubblico, ma ancora una volta, penso che la mia ha quello di default:

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

Sulla base di risposte ad altre domande e la stacktrace, sono esaminando i problemi di Autofac. Ho appena fatto Install-Package Autofac e avere l'ultima (3.0.2) nel progetto, e lo stacktrace appare così:

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) 

Questo accade anche se sto davvero registrando IStateProvider come questo: builder.Register(context => new SessionStateProvider()).As<IStateProvider>(); in ContainerBuilder.BuildContainer(). In Global.asax Ho anche registrare il 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(); 
} 

Non sono sicuro di quello che i prossimi passi sono possibili per cercare di risolvere questo (io sono fuori dalla mia profondità l'analisi del stacktrace Autofac), e ho apprezzerei qualsiasi aiuto

+2

VS2010 è dotato di .NET 4.0, ma con vs2012 .net 4.5 quindi la differenza versione quadro la causa del problema non è il Visual Studio. Puoi provare a intall .net 4.5 sulla macchina vs2010 o puoi provare ad usare una versione precedente di Autofac come 2.6 per vedere se funziona in entrambi gli ambienti. – nemesv

+1

'InvalidProgramException' - sembra un bug di .NET Framework quando Autofac sta cercando di creare un resolver. –

+0

@nemesv È possibile aggiungere il pacchetto Microsoft Bcl per accedere alla maggior parte delle funzionalità 4.5 in 4.0. (Ma attenzione, possono fare un casino quando si usa il controllo del codice sorgente) –

risposta

0

Ciao, non lo collaudo in VS 2010 perché non ce l'ho. Ma nel mio VS 2013 funziona bene.

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/