J'ai un contrôleur API Web qui a des ressources DID. Par la suite, j’ai ajouté un contrôleur MVC et j’ai maintenant besoin des mêmes ressources. Voici ma configuration d'origine:
[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);
}
}
}
Puis-je enregistrer DI pour MVC Controller au même endroit? Puis-je réutiliser le conteneur?
Mise à jour: Je dois être proche, mais je reçois maintenant une erreur dans le contrôleur de l'API Web pour laquelle j'ai besoin d'un constructeur sans paramètre. J'ai essayé de l'ajouter, mais rien ne s'injecte bien sûr
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);
}
}
Puis-je réutiliser le conteneur?
Oui, vous pouvez et vous devriez. Chaque domaine d'application doit généralement avoir une instance de conteneur.
La Documentation d'intégration MVC de la documentation Simple Injector explique que vous devez définir MVC DependencyResolver
comme suit:
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
Cependant, pour faciliter les choses, vous devez inscrire la WebRequestLifestyle
comme DefaultScopedLifestyle
:
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
Cela fonctionnera également pour l'API Web, car vous n'exécutez l'API Web qu'à partir d'IIS.
Vous devez donc configurer les deux DependencyResolvers.
Sachez également que la WebRequestLifestyle()
est obsolète à l’époque. Vous pouvez utiliser à la place:
//...
container.Options.DefaultScopedLifestyle = new SimpleInjector.Lifestyles.AsyncScopedLifestyle();
//...
Je voudrais ajouter mes deux cents parce qu'après avoir lu la réponse de Steven et les commentaires ci-dessous, il me restait quelques erreurs. Finalement, cela a à voir avec l'ordre dans lequel les choses sont en train d'être configurées.
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(
....
}
}