I have a Web API controller that has some resources DI'd. Out of later necessity I have added an MVC controller, now I need same resources DI'd there as well. Here is my original configuration:
[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);
}
}
}
Can I register DI for MVC Controller in the same place as well? Can I reuse the container?
Update: I must be close, but now I get an error in the Web API controller that I need a parameterless constructor; I tried adding it, but then nothing gets injected of course
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);
}
}
In order to add a Web API Controller you will need to Right Click the Controllers folder in the Solution Explorer and click on Add and then Controller. Now from the Add Scaffold window, choose the Web API 2 Controller – Empty option as shown below. Then give it a suitable name and click OK.
ASP.NET Core injects objects of dependency classes through constructor or method by using built-in IoC container. The built-in container is represented by IServiceProvider implementation that supports constructor injection by default.
If you have MVC project and you need to add Web API controller to this project, it can be done very easy. 1. Add Nuget package Microsoft. AspNet.
Can I reuse the container?
Yes you can, and you should. Every app domain should typically have one container instance.
The MVC integration documentation of the Simple Injector documentation explains that you should set the MVC DependencyResolver
as follows:
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
To make things easier however, your should register the WebRequestLifestyle
as DefaultScopedLifestyle
:
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
This will work for Web API as well, since you are solely running Web API from within IIS.
So you need to configure both the DependencyResolvers.
I would like to add my two cents because after reading Steven's answer and the comments below it I still got some errors. Eventually this had to do with the order in which things are getting configured.
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(
....
}
}
Also be aware that the WebRequestLifestyle()
is obsolete at the time .
You can use instead:
//...
container.Options.DefaultScopedLifestyle = new SimpleInjector.Lifestyles.AsyncScopedLifestyle();
//...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With