2016-05-31 12 views
8

Ich habe einen Web-API-Controller, der einige Ressourcen DI'd hat. Aus späterer Notwendigkeit habe ich einen MVC-Controller hinzugefügt, jetzt brauche ich dieselben Ressourcen auch dort. Hier ist meine ursprüngliche Konfiguration:Simple Injector initialisieren für MVC- und Web-API-Controller

[assembly: WebActivator.PostApplicationStartMethod(typeof(CineplexSearch.App_Start.SimpleInjectorWebApiInitializer), "Initialize")] 

namespace CineplexSearch.App_Start 
{ 
    using System.Web.Http; 
    using SimpleInjector; 
    using SimpleInjector.Integration.WebApi; 

    public static class SimpleInjectorWebApiInitializer 
    { 
     /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary> 
     public static void Initialize() 
     { 
      var container = new Container(); 
      container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(); 

      InitializeContainer(container); 

      container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 

      container.Verify(); 

      GlobalConfiguration.Configuration.DependencyResolver = 
       new SimpleInjectorWebApiDependencyResolver(container); 
     } 

     private static void InitializeContainer(Container container) 
     { 
      container.Register<ICachingManager, CachingManager>(Lifestyle.Transient); 
      container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient); 
     } 
    } 
} 

Kann ich DI für MVC Controller an der gleichen Stelle auch registrieren? Kann ich den Container wiederverwenden?

Update: Ich muss schließen, aber jetzt bekomme ich einen Fehler in der Web-API-Controller, die ich brauche einen parameterlosen Konstruktor; Ich habe versucht, das Hinzufügen, aber dann wird nichts injiziert natürlich

public static class SimpleInjectorWebApiInitializer 
{ 
    /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary> 
    public static void Initialize() 
    { 
     var container = new Container(); 
     container.Options.DefaultScopedLifestyle = new WebRequestLifestyle(); 

     InitializeContainer(container); 

     container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 
     container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 

     container.Verify(); 

     //GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); 
     DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 
    } 

    private static void InitializeContainer(Container container) 
    { 
     container.Register<ICachingManager, CachingManager>(Lifestyle.Transient); 
     container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient); 
    } 
} 

Antwort

10

Kann ich den Behälter wiederverwendet werden?

Ja, Sie können, und Sie sollten. Jede App-Domäne sollte normalerweise eine Container-Instanz haben.

Die MVC integration documentation der Simple Injector Dokumentation erklärt, dass Sie die MVC DependencyResolver eingestellt wie folgt:

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 

Dinge einfacher aber zu machen, sollen Sie die WebRequestLifestyle als DefaultScopedLifestyle registrieren:

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle(); 

Dies funktioniert auch für die Web-API, da Sie die Web-API ausschließlich innerhalb von IIS ausführen.

Sie müssen also beide DependencyResolver konfigurieren.

+0

Dank für die schnelle Antwort, ich fast es habe arbeiten, können Sie meine Update finden Sie? – FailedUnitTest

+0

@FailedUnitTest Sie benötigen * beide * die Abhängigkeit Resolver. Also auch der Web-API-Abhängigkeits-Resolver. – Steven

+0

Das hat es repariert, danke Steven! – FailedUnitTest

0

Ich möchte meine zwei Cent hinzufügen, denn nachdem ich Steven's Antwort und die Kommentare darunter gelesen habe, habe ich immer noch ein paar Fehler bekommen. Letztendlich hat das mit der Reihenfolge zu tun, in der die Dinge konfiguriert werden.

protected void Application_Start() 
{ 
    //set the default scoped lifestyle 
    Container container = new Container(); 
    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle(); 

    ... 
    //do class registration here. I did it with Scoped lifestyle 
    ... 
    //Let the SimpleInjector.Intergration packages register the controllers.  
    container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 

    AreaRegistration.RegisterAllAreas(); 
    //This must be here because we first need to do above before registering the web api. See WebApiConfig code. 
    GlobalConfiguration.Configure(WebApiConfig.Register); 
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
    RouteConfig.RegisterRoutes(RouteTable.Routes); 
    BundleConfig.RegisterBundles(BundleTable.Bundles); 

    //don't set the resolver here, do it in WebApiConfig.Register() 
    //DependencyResolver.SetResolver(new SimpleInjectorWebApiDependencyResolver(container)); 
    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 
    container.Verify(SimpleInjector.VerificationOption.VerifyAndDiagnose); 
} 

WebApiConfig:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     // Web API routes 
     config.MapHttpAttributeRoutes(); 
     //set the webApi resolver here! 
     config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(DependencyInjectionCoreSetup._Container); 
     //then the rest.. 
     var route = config.Routes.MapHttpRoute(
     .... 
    } 
}