MVC5 Web API and Dependency Injection - c#

Trying to do some DI on Web API 2 without third-party tools.
So, from some examples I've got custom dependency resolver (why there's no integrated one? Strange, even Microsoft.Extensions.DependencyInjection provides nothing):
public class DependencyResolver : IDependencyResolver
{
protected IServiceProvider _serviceProvider;
public DependencyResolver(IServiceProvider serviceProvider)
{
this._serviceProvider = serviceProvider;
}
public IDependencyScope BeginScope()
{
return this;
}
public void Dispose()
{
}
public object GetService(Type serviceType)
{
return this._serviceProvider.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this._serviceProvider.GetServices(serviceType);
}
public void AddService()
{
}
}
then created this class:
public class ServiceConfig
{
public static void Register(HttpConfiguration config)
{
var services = new ServiceCollection();
services.AddScoped<IMyService, MyServiceClient>();
var resolver = new DependencyResolver(services.BuildServiceProvider());
config.DependencyResolver = resolver;
}
}
and registered it:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configure(ServiceConfig.Register);
}
But when I'm trying to use it:
public class TestController : ApiController
{
private IMyService _myService = null;
public TestController(IMyService myService)
{
_myService = myService;
}
public void Get()
{
_myService.DoWork();
}
}
I'm getting error:
An error occurred when trying to create a controller of type 'TestController'. Make sure that the controller has a parameterless public constructor.
How to cook this one in right way?

What you see happening is related to this problem. In short, Web API will call its default IHttpControllerActivator implementation to request a new controller instance. That instance will call into your DependencyResolver.GetService method. That method will forward the call to MS.DI's GetService method. However, since you didn't register your controllers into the MS.DI container, it will return null. This will cause the default IHttpControllerActivator to try to create the controller using reflection, but this requires a default constructor. Since the controller doesn't have one, this results in the rather cryptic exception message.
The quick solution, therefore, is to register your controllers, e.g.:
services.AddTransient<TestController>();
This, however, will only partly solve your problem because your IDependencyResolver implementation is broken. It is broken in an ugly way, because it might seem to work at first, but will result in memory leaks, because you always resolve from the root container, instead of resolving from a scope. This will cause your resolved controller instances (and other disposable transient components) to stay referenced for the lifetime of your application.
To fix this, you should change your IDependencyResolver implementation to the following:
public class DependencyResolver : IDependencyResolver
{
private readonly IServiceProvider provider;
private readonly IServiceScope scope;
public DependencyResolver(ServiceProvider provider) => this.provider = provider;
internal DependencyResolver(IServiceScope scope)
{
this.provider = scope.ServiceProvider;
this.scope = scope;
}
public IDependencyScope BeginScope() =>
new DependencyResolver(provider.CreateScope());
public object GetService(Type serviceType) => provider.GetService(serviceType);
public IEnumerable<object> GetServices(Type type) => provider.GetServices(type);
public void Dispose() => scope?.Dispose();
}
This implementation will ensure a new IServiceScope is created on each web request and services are always resolved from a request; not from the root IServiceProvider.
Although this will fix your problems, another implementation might still be benificial.
The IDependencyResolver contract is problematic, because it is forced to return null when a call to GetService doesn't result in the correct resolution of a registration. This means that you will end up with these annoying "Make sure that the controller has a parameterless public constructor" errors when you forget to register your controllers.
It is, therefore, much easier to create a custom IHttpControllerActivator instead. In that case you can call GetRequiredService which will never return null:
public class MsDiHttpControllerActivator : IHttpControllerActivator
{
private readonly ServiceProvider provider;
public MsDiHttpControllerActivator(ServiceProvider provider) =>
this.provider = provider;
public IHttpController Create(
HttpRequestMessage request, HttpControllerDescriptor d, Type controllerType)
{
IServiceScope scope = this.provider.CreateScope();
request.RegisterForDispose(scope); // disposes scope when request ends
return (IHttpController)scope.ServiceProvider.GetRequiredService(controllerType);
}
}
This MsDiHttpControllerActivator implementation can be added to the Web API pipeline as follows:
GlobalConfiguration.Configuration.Services
.Replace(typeof(IHttpControllerActivator),
new MsDiHttpControllerActivator(services.BuildServiceProvider(true)));
This removes the need to have an IDependencyResolver implementation. You still need to register your controllers, though:
services.AddTransient<TestController>();
Also note that I changed this:
services.BuildServiceProvider()
To this:
services.BuildServiceProvider(true)
This is a really important change; it protects you (for some part) against Captive Dependencies, which are one of the major problems when using DI Containers. For some obscure reason, the BuildServiceProvider() overload defaults to false, which means it will not validate your scopes.

Related

How to write constructor when in an mvc api project

I am trying to write an API project in code first approach. I written some code but it shows error
An error occurred when trying to create a controller of type 'CatalogController'. Make sure that the controller has a parameterless public constructor.
and
Type Nop.Api.Controllers.CatalogController does not have a default constructor
Controller
public class CatalogController : ApiController
{
private readonly ICatalogModelFactory _catalogModelFactory;
public CatalogController(ICatalogModelFactory catalogModelFactory)
{
_catalogModelFactory = catalogModelFactory;
}
public HttpResponseMessage HomepageCategories()
{
HttpResponseMessage response = new HttpResponseMessage();
var model = _catalogModelFactory.PrepareHomepageCategoryModels();
var result = JsonConvert.SerializeObject(model);
response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result) };
return response;
}
}
Can anyone please help me how solve this error? I am not getting what is wrong in the constructor part. When debugging this it is not hitting the breakpoint.
Why am I getting this error?
When you request a resource from a controller, the framework needs to process the request. So the routing identifies the controller, action etc. and then it needs to instantiate an instance of the controller in order to invoke the wanted method.
In order to do that, he will either need a public empty constructor or some way to resolve your constructor's dependencies.
In your case, you have one ctor that has a dependency of ICatalogModelFactory. The framework will need you to implement a Dependency Resolver and register you new resolver when the application starts (Global.asax) like this:
DependencyResolver.SetResolver(new MyDependencyResolver());
Here's and example of a UnityContainer custom dependency resolver as found in this link:
public class UnityDependencyResolver : IDependencyResolver
{
IUnityContainer container;
public UnityDependencyResolver(IUnityContainer container)
{
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch
{
return new List<object>();
}
}
}
And the registration occurred in the Global.asax Application_Start method:
IUnityContainer container = GetUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
By the way, another way to do so, is to create a ControllerFactory and simply resolve the controller with a DI container. I prefer using the dependency resolver for resolving controllers.

How can I instantiate Services in MVC

I have an ASP.Net MVC 5 project using an Onion Architecture where I have repositories and services and I use Services from my controller. In my controller, I need to use the IGenericService variables I created, but how can I instantiate these variables? The problem being that my Service needs a IRepository for its constructor, and in turn IRepositoryneeds to be initialized too.
What I tried was AddSingleton(IGenericService<MyClass>, GenericService<MyClass>) in the method ConfigureServices(IServiceCollection services) in the Startup.cs file but it doesn't seem to help.
Edit As suggested my #Nkosi I am trying to resolve dependencies and followed this tutorial to do so : http://scottdorman.github.io/2016/03/17/integrating-asp.net-core-dependency-injection-in-mvc-4/ . My problem now is that I get an invalid operation exception :
Unable to resolve service for type 'Repository.PrincipalServerContext' while attempting to activate 'WebExploitv2.Controllers.NavigationController'
My startup.cs looks like this now:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var services = new ServiceCollection();
ConfigureAuth(app);
ConfigureServices(services);
var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());
DependencyResolver.SetResolver(resolver);
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllerAsServices(typeof(Startup).Assembly.GetExportedTypes()
.Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
.Where(t => typeof(IController).IsAssignableFrom(t)
|| t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
services.AddSingleton<IGenericRepository<Web_Documents>, GenericRepository<Web_Documents>>();
services.AddSingleton<IGenericService<Web_Documents>, GenericService<Web_Documents>>();
services.AddSingleton<IGenericRepository<Web_Categories>, GenericRepository<Web_Categories>>();
services.AddSingleton<IGenericService<Web_Categories>, GenericService<Web_Categories>>();
services.AddSingleton<IGenericService<Web_User_joint_Profils>, GenericService<Web_User_joint_Profils>>();
services.AddSingleton<IGenericRepository<Web_User_joint_Profils>, GenericRepository<Web_User_joint_Profils>>();
services.AddSingleton<IGenericRepository<Web_Group_joint_Profils>, GenericRepository<Web_Group_joint_Profils>>();
services.AddSingleton<IGenericService<Web_Group_joint_Profils>, GenericService<Web_Group_joint_Profils>>();
services.AddSingleton<IMenuService, MenuService>();
services.AddSingleton<IMenuRepository, MenuRepository>();
}
}
I also added a DefaultDependencyResolver class :
public class DefaultDependencyResolver : IDependencyResolver
{
protected IServiceProvider serviceProvider;
public DefaultDependencyResolver(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public object GetService(Type serviceType)
{
return this.serviceProvider.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.serviceProvider.GetServices(serviceType);
}
}
Next I have the ServiceProviderExtension class:
public static class ServiceProviderExtensions
{
public static IServiceCollection AddControllerAsServices(this IServiceCollection services, IEnumerable<Type> controllerTypes)
{
foreach(var type in controllerTypes)
{
services.AddTransient(type);
}
return services;
}
}
Finally in my controller, I have Interfaces of GenericService which allows me to access Repository and in turn access my DB. I use the followed interfaces for instantiation
private IGenericService<Web_User_joint_Profils> _userProfileService;
private IGenericService<Web_Group_joint_Profils> _groupProfileService;
private IGenericService<Web_Categories> _categoryService;
PrincipalServerContext context;
private NavigationController(PrincipalServerContext context, IGenericService<Web_User_joint_Profils> userProfileService, IGenericService<Web_Group_joint_Profils> groupProfileService, IGenericService<Web_Categories> categoryService)
{
_context = context;
_userProfileService = userProfileService;
_groupProfileService = groupProfileService;
_categoryService = categoryService;
}
Note that My GenericService takes POCOs as generics in order to know where to look in Database. So for each of these in Startup.ConfigureServices(IServiceCollection services) I added an AddSingleton method to register these services and repositories with the DI container.
Any ideas why I get this exception?
I wouldn't call services inside a startup.
Instance your IGenericService as a private readonly, then create the constructor to call in startup.cs or where ever you decide to use it.
private readonly IGenericService _genericService = new GenericService();
public IGenericService GenericService
{
get{ return _genericService; }
set{ _genericService = value; }
}
Now you call your classes like:
GenericService.Method();
It is rather simple, using IServiceCollection instance that is being passed to ConfigureServices method by the run time you do:
services.AddSingleton<IAbstraction, ConcreteImplementation>();
or, for a transient lifetime scope:
services.AddTransient<IAbstraction, ConcreteImplementation>();
or, in your case:
services.AddSingleton<IGenericService<MyClass>, GenericService<MyClass>>();

CastleWindsor LifeStyle.PerWebRequest behaves like singleton

I am trying to create a UserService that I can inject in my classes, that will hold the user currently logged in to my system.
I am using CastleWindsor as my container.
Now my problem is that I am trying to make my UserService disposable, so that the databaseconnection fetching the user on creating will also be disposed when the object is destroyed.
I added the following setup in my Global.asax.cs:
private static void BootstrapContainer()
{
_container = new WindsorContainer().Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(_container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(_container.Kernel);
_container.Register(Component.For<IUserService>()
.LifestylePerWebRequest()
.ImplementedBy<UserService>());
_container.Register(Component.For<IPrincipal>()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => HttpContext.Current.User));
}
Which is called in my Application_Start.
My UserService code is as follows:
public interface IUserService
{
OrganisationBruger User { get; }
int UserId { get; }
}
public class UserService : IUserService, IDisposable
{
private readonly IPrincipal _principal;
private OrganisationBruger _user;
private readonly DatabaseDataContext _db;
public UserService(IPrincipal principal, IDatabaseDataContextFactory dataContextFactory)
{
_principal = principal;
_db = dataContextFactory.GetDataContext();
}
public OrganisationBruger User => _user ?? (_user = GetUser());
public int UserId => Convert.ToInt32(_principal.Identity.Name);
private OrganisationBruger GetUser()
{
return _db.OrganisationBrugers.Single(u => u.ID == UserId);
}
public void Dispose()
{
_db.Dispose();
}
}
When I Debug my code I can see on the very first request I fire it correctly creates the class UserService.cs and then disposes it after the webrequest. Now my problem is the second web request does not seem to call the constructor anymore thus just reusing the formerly created object. This leads to the DatabaseContext already being disposed of.
I thought that LifestylePerWebRequest meant that the UserService would get recreated on every request. Can anyone help me understand this?
So first of all I had overlook the "registration of the module"-part in the documentation. You need to add the following to your web.config:
<httpModules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/>
</httpModules>
Second of all I was not a hundred percent sure how the dependency resolver worked. The problem was that one of the modules using my UserService as a dependency had its lifecycle set to Singleton which is default behavior when you specify nothing about the lifecycle when registering your module with the container.
I fixed the problem by making sure that every module that is using my UserService as dependency is also registered with a lifecycle of LifestylePerWebRequest() or LifestyleTransient().
You should double check if you have any other interface which use IUserService overwrites the lifestyle.
In that case, Castle windsor will not resolve IUserService for each request because ITest is set to singleton.
For example
_container.Register(Component.For<ITest>()
.LifestyleSingleton()
.ImplementedBy<Test>());
public interface ITest
{
}
public class Test: ITest
{
private readonly IUserService _ser;
public Test(IUserService ser)
{
_ser= ser;
}
}
I have a WindsorHttpControllerActivator that implements IHttpControllerActivator. It registers the controller for disposal which ensures a new controller gets created on each request by destroying the old one. This occurs when .LifestylePerWebRequest() completes each request.
public IHttpController Create(
HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
var controller =
(IHttpController)_container.Resolve(controllerType);
// Controller disposal ensures new controller for each request, hence DbContexts are fresh and pull fresh data from the DB.
request.RegisterForDispose(
new Release(
() => _container.Release(controller)));
return controller;
}
private class Release : IDisposable
{
private readonly Action _release;
public Release(Action release)
{
_release = release;
}
public void Dispose()
{
_release();
}
}

Simple Injector per-web-api-request dependency in SignalR hub

According to this post, it should be possible to inject per-web-request dependencies into SignalR hubs (although with some limitations like problem with OnDisconnected() method). In my case it is ASP Web API (not MVC) and it does not work for some reason.
Here are relevant parts:
container.RegisterWebApiControllers(httpConfiguration);
container.RegisterWebApiRequest<DbContext, MyDbContext>();
container.RegisterWebApiRequest<ISampleRepository, SampleRepository>(); //DbContext injected to SampleRepository
//Enable injections to SignalR Hubs
var activator = new SimpleInjectorHubActivator(container);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => activator);
This class makes possible to inject into hubs:
public class SimpleInjectorHubActivator : IHubActivator
{
private readonly Container _container;
public SimpleInjectorHubActivator(Container container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return (IHub)_container.GetInstance(descriptor.HubType);
}
}
And Hub itself:
[HubName("sample")]
public class SampleHub : Hub
{
public ActiveBetsHub(ISampleRepository repository)
{
}
//Irrelevant methods here. OnDisconnected() NOT implemented!
}
With this setup I get exception:
No registration for type SampleHub could be found and
an implicit registration could not be made.
The ISampleRepository is registered as 'Web API Request'
lifestyle, but the instance is requested outside the context of a Web API Request.
Which is expected as I understand. However I get exactly same exception when I change Lifestyle of repository to Transient:
var transientHybrid = Lifestyle.CreateHybrid(() => HttpContext.Current != null, new WebApiRequestLifestyle(), Lifestyle.Transient);
container.Register<ISampleRepository, SampleRepository>(transientHybrid);
I suspect the problem could lie in HttpContext.Current != null check that is not working for Web API the same way as for MVC.
SignalR 2.2
Simple Injector 2.8.3
What do I miss?
UPDATE:
This is stack trace on how SignalR creates Hubs:
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.Container.GetInstance(Type serviceType)
at MyWebAbi.WebApiApplication.SimpleInjectorHubActivator.Create(HubDescriptor descriptor) in Global.asax.cs:line 108
at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.ResolveHub(String hubName)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.CreateHub(IRequest request, HubDescriptor descriptor, String connectionId, StateChangeTracker tracker, Boolean throwIfFailedToCreate)
So the proper solution would be to use ExecutionContextScope for a Hubs but this scope needs to be explicitly closed which makes things more complicated...
Your definition of your hybrid lifestyle is incorrect. The WebApiRequestLifestyle does not depend in any way on the HttpContext so checking whether HttpContext.Current != null will not work. You will have to check if there is an active Web API request lifestyle scope (or execution context scope, which is basically the same) by calling container.GetCurrentExecutionContextScope():
var transientHybrid = Lifestyle.CreateHybrid(
() => container.GetCurrentExecutionContextScope() != null,
new WebApiRequestLifestyle(),
Lifestyle.Transient);
Do note however that you should be very careful composing a hybrid lifestyle of a scoped lifestyle and transient, because this will easily yield in wrong results. This is actually the default behavior of some DI libraries, but this is a design flaw IMO. I assume you very consciously registered your MyDbContext with the scoped lifestyle, because you need to make sure that the same instance is used throughout the request. Using the Transient lifestyle means that you might get multiple MyDbContext during the request. This might not be a problem, because in your hubs you might currently only have one reference to your MyDbContext, but your code might break once your object graph changes and a second reference to MyDbContext is added.
So instead, I would advice not using this combination of lifestyles. Instead, just use either the WebApiRequestLifestyle or the ExecutionContextScopeLifestyle (they are the same) and make sure that such a execution context scope is started before your hub is resolved.
And by the way, don't forget to register your hubs explicitly in Simple Injector. This allows Simple Injector to analyze the complete object graph for you including your hub classes.
Recently I faced the same problem and found the following working quite well, hope this will help someone:
public class SignalRDependencyResolver : DefaultDependencyResolver
{
public SignalRDependencyResolver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public override object GetService(Type serviceType)
{
return _serviceProvider.GetService(serviceType) ?? base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
var #this = (IEnumerable<object>) _serviceProvider.GetService(typeof (IEnumerable<>).MakeGenericType(serviceType));
var #base = base.GetServices(serviceType);
return #this == null ? #base : #base == null ? #this : #this.Concat(#base);
}
private readonly IServiceProvider _serviceProvider;
}
public class SignalRHubDispatcher : HubDispatcher
{
public SignalRHubDispatcher(Container container, HubConfiguration configuration) : base(configuration)
{
_container = container;
}
protected override Task OnConnected(IRequest request, string connectionId)
{
return Invoke(() => base.OnConnected(request, connectionId));
}
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
return Invoke(() => base.OnReceived(request, connectionId, data));
}
protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled)
{
return Invoke(() => base.OnDisconnected(request, connectionId, stopCalled));
}
protected override Task OnReconnected(IRequest request, string connectionId)
{
return Invoke(() => base.OnReconnected(request, connectionId));
}
private async Task Invoke(Func<Task> method)
{
using (_container.BeginExecutionContextScope())
await method();
}
private readonly Container _container;
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new ExecutionContextScopeLifestyle();
container.Register<DbContext, MyDbContext>(Lifestyle.Scoped);
container.Register<ISampleRepository, SampleRepository>(Lifestyle.Scoped);
// if you want to use the same container in WebApi don't forget to add
app.Use(async (context, next) => {
using (container.BeginExecutionContextScope())
await next();
});
// ... configure web api
var config = new HubConfiguration
{
Resolver = new SignalRDependencyResolver(container)
}
// ... configure the rest of SignalR
// pass SignalRHubDispatcher
app.MapSignalR<SignalRHubDispatcher>("/signalr", config);
}
}

using a Handler in Web API and having Unity resolve per request

I am using Unity as my IoC framework and I am creating a type based on the value in the header of each request in a handler:
var container = new UnityContainer();
container.RegisterType<IFoo,Foo>(new InjectionConstructor(valuefromHeader));
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
The problem is that the handler's SendAsync means that the global container is getting overwritten by different requests and the controllers that use IFoo in their constructor are getting the wrong values.
1) Can I make the SendAsync sync?
2) If not, how do I create different instances for each request and have the IoC container resolve safely?
I have looked at the following articles without success:
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/
http://benfoster.io/blog/per-request-dependencies-in-aspnet-web-api-using-structuremap
Thanks in advance.
I agree with #Steven's approach, but that doesn't answer your more general question of how to resolve per request.
I would recommend you change to using the UnityHierarchicalDependencyResolver and then anything you register with HierarchicalLifetimeManager will be resolved per request.
Change this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
to this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityHierarchicalDependencyResolver(container);
The problem you are having is caused by you mixing runtime values with design time dependencies. In general, the services you resolve from the container should not depend on runtime values in their constructor. You shouldn't do this, because components tend to live much longer than runtime values and injecting runtime values into components, makes it much harder to diagnose and verify the container's configuration.
Instead, hide that value behind a service that can provide consumers with that instance when required. For instance:
public interface IHeaderValueProvider
{
HeaderValue GetCurrentValue();
}
You can create an implementation that can be easily registered and injected into any component that needs that value. Anytime after the construction phase, those components can call the GetCurrentValue() method on the injected IHeaderValueProvider dependency.
I managed to resolve per request by declaring my custom UnityResolver's class within the WebApiConfig class. The UnityResolver class uses the HttpConfiguration class assuming you're using an OWIN context.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var _container = new UnityContainer();
DependencyConfiguration.ConfigureContainer(_container);
config.DependencyResolver = new UnityResolver(_container);
}
The ConfigureContainer class is simply a class where I declare my IOC dependencies as shown below:
private static void RegisterReleaseEnv(IUnityContainer container)
{
//Repository Registration
container
.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager());
}
It is very important that you use the HierarchicalLifetimeManager lifetime manager so that you get a new instance per request.
The UnityResolver class then looks like this:
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
I hope this helps.
For more information: http://www.asp.net/web-api/overview/advanced/dependency-injection

Categories

Resources