Am I using correct lifetime managers for dependency injection? - asp.net-web-api

I have an asp.net web api application that uses Unity dependency injection libraries from MS Unity.AspNet.WebApi and Unity nuget packages. Also, the application uses Entity Framework version 6 database context for ORM and a generic repository.
Custom service types are consumed by Api controllers. Custom Service classes consumes EF database contexts and the generic repository.
My question is: Are HierarchicalLifetimeManager and ContainerControlledLifetimeManager correct lifetime managers for my web api application?
Codes in the UnityConfig class of my application:
using System;
using System.Configuration;
using System.Data.Entity;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using App.Api.Models;
using App.Dal;
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion
/// <summary>Registers the type mappings with the Unity container.</summary>
/// <param name="container">The unity container to configure.</param>
/// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to
/// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
public static void RegisterTypes(IUnityContainer container)
{
var connectionStringEntityFramework= ConfigurationManager.ConnectionStrings["AppEntities"].ToString();
// Entity Framework database context and generic repository
// HierarchicalLifetimeManager is used:
container.RegisterType<DbContext, FirstAngularJsEntities>(new HierarchicalLifetimeManager(), new InjectionConstructor(connectionStringFirstAngularJsEntities));
container.RegisterType<IRepository, GenRepository>(new HierarchicalLifetimeManager(), new InjectionConstructor(typeof(DbContext)));
// services
// ContainerControlledLifetimeManager is used:
container.RegisterType<IContactService, ContactService>(new ContainerControlledLifetimeManager());
container.RegisterType<IProductService, ProductService>(new ContainerControlledLifetimeManager());
}
A sample api controller has custom service injected in its constructor:
public class ContactApiController : ApiController
{
private readonly IContactService _contactService;
public ContactApiController(IContactService contactService)
{
_contactService = contactService;
}
...
}
A sample custom service has EF DbContext and repository injected in its constructor:
public class ContactService : IContactService
{
private readonly IRepository _repo;
private readonly DbContext _context;
public ContactService(DbContext context, IRepository repo)
{
_context = context;
_repo = repo;
}
...
}

Using ContainerControlledLifetimeManager you'll get singletons of your services. One instance for a long time (untill IIS recycling).
HierarchicalLifetimeManager is used with child containers - create new instance of object for every child container, so you don't create child containers it works like a singleton again :)
The best way for WebApi apllication is using PerRequestLifetimeManager.
Create new instances for every request to Api.

I tend to look at this as what is the shortest lifetime that is compatible with the semantics of what you are trying to do, with the default lifetime being Transient unless otherwise required.
DbContext holds state so we need to be consistent for the request so PerRequest or Hierachic
Repository is/should be stateless since it's state is the DbContext, so Transient
Services is/should be stateless so Transient
One reason for going with Hierarchic rather than PerRequest is that the PerRequest manager does not play well with Owin, see http://www.reply.com/solidsoft-reply/en/content/managing-object-lifetimes-with-owin-and-unity, and you will need to write some cleanup middleware to replace the HttpModule

Related

How I Inject Repository In Service to avoid Error Some services are not able to be constructed or inject service into injected service asp.net core 6

When I Inject Repository In Service Constructor (This Error Comes ) Some services are not able to be constructed
Program.Cs
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
builder.Services.AddScoped<IGenreService, GenreService>();
GenreService
public class GenreService : IGenreService
{
private readonly IRepository<GenresDto> _repositoryGenre;
public GenreService( IRepository<GenresDto> repositoryGenre)
{
_repositoryGenre = repositoryGenre;
}
I should register the DbContext in program.cs. So the answer is:
services.AddDbContext(
options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));

How are Exrin services registered to their appropriate models?

After creating a service for a model, how do I tell the model to use that service?
Within the sample Tesla app, there exists constructors which call for a service as an argument:
private readonly IClimateService _service;
public ClimateModel(IExrinContainer exrinContainer, IAuthModel authModel, IClimateService service)
: base(exrinContainer, new ClimateModelState())
{ _service = service; }
I searched but never found where the model receives the service, but I did find this:
protected override void InitServices()
{
RegisterTypeAssembly(typeof(IService), new AssemblyName(nameof(TeslaService)));
base.InitServices();
}
Exrin automatically loads Services, via reflection, if they inherit from
Exrin.Abstraction.IService

MVC5, Web API 2 and Ninject

I have created a new MVC5 project with Web API 2, I then added the Ninject.MVC3 package from NuGet.
Constructor injection is working fine for the MVC5 controllers, but i am getting an error when trying to use it with the Web API Controllers.
An error occurred when trying to create a controller of type 'UserProfileController'. Make sure that the controller has a parameterless public constructor.
Constructor for working MVC5 controller:
public class HomeController : Controller
{
private IMailService _mail;
private IRepository _repo;
public HomeController(IMailService mail, IRepository repo)
{
_mail = mail;
_repo = repo;
}
}
Constructor for non-working Web API Controller:
public class UserProfileController : ApiController
{
private IRepository _repo;
public UserProfileController(IRepository repo)
{
_repo = repo;
}
}
Below is the full NinjectWebCommon.cs file:
[assembly: WebActivator.PreApplicationStartMethod(typeof(DatingSite.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(DatingSite.App_Start.NinjectWebCommon), "Stop")]
namespace DatingSite.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using DatingSite.Services;
using DatingSite.Data;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
#if DEBUG
kernel.Bind<IMailService>().To<MockMailService>().InRequestScope();
#else
kernel.Bind<IMailService>().To<MailService>().InRequestScope();
#endif
kernel.Bind<SiteContext>().To<SiteContext>().InRequestScope();
kernel.Bind<IRepository>().To<Repository>().InRequestScope();
}
}
}
The Ninject.Web.WebApi NuGet package has just been released. From now on the preferred solution is using that package.
I couldn't find any related documentation but after installing the package everything worked for me.
Install-Package Ninject.Web.WebApi
After installation both the normal MVC and the API controller instances are provided by Ninject.
If you have Ninject.Web.Common already installed make sure to save your bindings from NinjectWebCommon.cs and let Nuget rewrite NinjectWebCommon.cs during install and put back your bindings when finished.
As pointed out in the comments depending on your execution context you will need one of the following packages as well:
Ninject.Web.WebApi.WebHost
Ninject.Web.WebApi.OwinHost
Ninject.Web.WebApi.Selfhost
The most common scenario is IIS for that pick the WebHost package.
In the case you start an IIS MVC5 web app from scratch and want to use Ninject install the following packages:
Ninject - Ninject core dll
Ninject.Web.Common - Common Web functionality for Ninject eg. InRequestScope()
Ninject.MVC5 - MVC dependency injectors eg. to provide Controllers for MVC
Ninject.Web.Common.WebHost - Registers the dependency injectors from Ninject.MVC5 when IIS starts the web app. If you are not using IIS you will need a different package, check above
Ninject.Web.WebApi WebApi dependency injectors eg. to provide Controllers for WebApi
Ninject.web.WebApi.WebHost - Registers the dependency injectors from Ninject.Web.WebApi when IIS starts the web app.
You have this problem because Controller and ApiController use different Dependency Resolvers. Solution is very simple.
At first create new classes of Dependency Resolver and Dependency Scope. You can use this:
public class NinjectResolver : NinjectScope, IDependencyResolver
{
private readonly IKernel _kernel;
public NinjectResolver(IKernel kernel)
: base(kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectScope(_kernel.BeginBlock());
}
}
public class NinjectScope : IDependencyScope
{
protected IResolutionRoot resolutionRoot;
public NinjectScope(IResolutionRoot kernel)
{
resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).SingleOrDefault();
}
public IEnumerable<object> GetServices(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).ToList();
}
public void Dispose()
{
IDisposable disposable = (IDisposable)resolutionRoot;
if (disposable != null) disposable.Dispose();
resolutionRoot = null;
}
}
After that, add next line to method CreateKernel() in NinjectWebCommon
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
I had the same problem.
After installation of the following NuGet packages:
Ninject
Ninject.web.WebApi
Ninject.web.WebApi.WebHost
Ninject.MVC3
Ninject.web.Common
Ninject.web.Common.WebHost
everything works fine
I'm found that assembly Ninject.Web.WebApi.dll define own DependencyResolver and register it with kernel in class Ninject.Web.WebApi.WebApiModule automatically.
So I simply add to NinjectWebCommon.CreateKernel one line...
GlobalConfiguration.Configuration.DependencyResolver =
kernel.Get<System.Web.Http.Dependencies.IDependencyResolver>();
Finally my project has following dependencies:
Ninject 3.2.0
Ninject.Web.Common 3.2.0
Ninject.Web.WebApi 3.2.4
Just for others, who might have a similar set up to me, and got here via google like I did.
I had multiple applications using one WebApi project. I would get the above error if I hadn't included the binding in the RegisterServices method. So before pulling your hair out, just check you have the binding set up. The error doesn't tell you you have missing bindings. Which it would if the Application is in the same project as the WebApi.
I recently had to get Web Api 2 working with so I can answer that part of the question.
These are the nuget packages needed for Web Api 2-
Ninject
Ninject.Web.Common
Ninject.Web.Common.WebHost
Ninject.Web.WebApi
WebActivatorEx
Then edit NinjectWebCommon.CreateKernel(..) including
RegisterServices(kernel);
// the next line is the important one
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
I've written a more detailed post about this - http://NoDogmaBlog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/ including a full solution to download.
You are supposed to install these packages from Nuget in webAPI project.
Ninject
Ninject.Web.Common
Ninject.Web.Common.WebHost
Ninject.Web.WebApi
Ninject.Web.WebApi.WebHost
Then you must install the Ninject package in the Repository project as well (the version must be the same as in API project). I had the same issue when there was a different version installed for Ninject.
I had this issue in a solution where the project in which I was using Ninject was not using Web API (I have 6 projects so far in my solution). I kept on getting the dreaded "parameterless constructor required" which obviously meant when I added it the Ninject injection was not getting instantiated as it was dropping into the empty constructor. I tried various solutions but in the end I checked my Ninject packages and saw that the Ninject.Web.Webapi package was installed. I uninstalled this and did a clean and rebuild. This solved the issue. My other lower level project was referencing the Ninject.Web.Api package and stupidly I had installed that into my Web front end project.
I hope this may help other people who have tried all the Stack solutions and got no where.

Ninject Binding Issue with Constructor Chaining

I have a MVC3 project that uses the Entity Framework and Ninject v2.2, and follows the Unit of Work pattern with a Service Layer wrapping my repositories.
After looking at the code below, hopefully its apparent that Ninject is using constructor chaining to inject the correct classes. It currently works prefectly in my application, however I am at the point that I need to bind an instance of IDatabase to MyDatabase with a different scope such as InSingletonScope() or InNamedScope(), not InRequestScope(). I know that I can use the [Named("MyDatabaseScope")] Attribute to customize which IDatabase object is injected, however it seems that with my code structure, if I wanted to inject my SingletonScoped instance, I would have to recreate a new Abstract and Concrete Implementation of my Unit of Work, my Service and all my Repositories, that will then chain down.
Basically my application currently goes
Controller -> Unit of Work -> Database, (Repositories -> Database)
If I have to change my Database Binding, I will now have to create another chain in addition to the current one:
Controller -> New Unit of Work -> SingletonDatabase, (New Repositories-> SingletonDatabase)
This seems to completely defeat the DRY principal. Is there a way to, from the Controller Constructor, inform Ninject that when doing constructor chaining it should use my singleton (or named binding) rather than my request scope binding, without having to recreate all my classes with a Named attribute, or a new Interface?
Sorry for the long text, I wasnt sure if I could get the point across without my code snippets and my somewhat rambling explaination.
Ninject Module Load Function:
..snip..
Bind<IUserServices>().To<UserServices>();
Bind<IBaseServices>().To<BaseServices>();
Bind<IUserRepository>().To<UserRepository>();
Bind(typeof (IRepository<>)).To(typeof (RepositoryBase<>));
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<IDatabase>().To<MyDatabase>().InRequestScope();
//This is my problem:
//Bind<IDatabase>().To<MySingletonDatabase>().InSingletonScope();
Unit of Work Implementation Constructor:
public class UnitOfWork : IUnitOfWork
{
private IDatabase _database;
public UnitOfWork(IDatabase database,
IUserRepository userRepository,
IPeopleRepository peopleRepository,
)
{
this._database = database;
this.UserRepository = userRepository;
this.PeopleRepository = peopleRepository;
}
protected IDatabase Database
{
get { return _database; }
}
...snip...
}
User Service Layer Implementation Constructor:
public class UserServices : BaseServices, IUserServices
{
private IUnitOfWork _uow;
public UserServices(IUnitOfWork uow)
: base(uow)
{
_uow = uow;
}
...snip...
}
User Repository Constructor:
public class UserRepository : RepositoryBase<User>, IUserRepository
{
public UserRepository(IDatabase database)
: base(database)
{
}
...snip...
}
Controller Constructor:
public IUserServices _userServices { get; set; }
public ActivityController(IUserServices userServices)
{
_userServices = userServices;
}
}
Using Ninject 3.0.0 you can use WhenAnyAncestrorNamed("Some name") But if you need to run asyncronous things you should thing about splitting your application into a web frontend and a server backend. This could make many things easier.

MVC, EF - DataContext singleton instance Per-Web-Request in Unity

I have a MVC 3 web application, where I am using the Entity Framework for the data access. Furthermore, I have made a simple use of the repository pattern, where e.g. all Product related stuff is handled in the "ProductRepository" and all User related stuff is handled in the "UserRepository".
Thus, I am using the UNITY container, to make a singleton instance of the DataContext, which I inject into each of the repositories. A quick search on Google, and everyone recommends you to NOT use a singleton instance of the DataContext, as it might give you some memory leaks in the future.
So, inspired by this post, making a singleton instance of the DataContext for each web request is the answer (please correct me if I am wrong!)
http://blogs.microsoft.co.il/blogs/gilf/archive/2010/05/18/how-to-manage-objectcontext-per-request-in-asp-net.aspx
However, UNITY does not support the "Per-web-request" lifetime manager. But, it is possible to implement your own custom lifetime manager, which handles this for you. Actually, this is discussed in this post :
Singleton Per Call Context (Web Request) in Unity
The question is, I have now implemented the custom lifetime manager as described in the above post, but I am unsure if this is the way to do it. I am also wondering about where the datacontext instance is disposed in the provided solution? Am I missing out something?
Is there actually a better way of solving my "issue"?
Thanks!
** Added information about my implementation **
The following is snippets from my Global.asax, Controller and Repository. This gives a clear picture of my implementation.
Global.asax
var container = new UnityContainer();
container
.RegisterType<ProductsRepository>(new ContainerControlledLifetimeManager())
.RegisterType<CategoryRepository>(new ContainerControlledLifetimeManager())
.RegisterType<MyEntities>(new PerResolveLifetimeManager(), dbConnectionString)
Controller
private ProductsRepository _productsRepository;
private CategoryRepository _categoryRepository;
public ProductsController(ProductsRepository productsRepository, CategoryRepository categoryRepository)
{
_productsRepository = productsRepository;
_categoryRepository = categoryRepository;
}
public ActionResult Index()
{
ProductCategory category = _categoryRepository.GetProductCategory(categoryId);
.
.
.
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_productsRepository.Dispose();
_categoryRepository.Dispose();
}
Product Repository
public class ProductsRepository : IDisposable
{
private MyEntities _db;
public ProductsRepository(MyEntities db)
{
_db = db;
}
public Product GetProduct(Guid productId)
{
return _db.Product.Where(x => x.ID == productId).FirstOrDefault();
}
public void Dispose()
{
this._db.Dispose();
}
Controller Factory
public class UnityControllerFactory : DefaultControllerFactory
{
IUnityContainer _container;
public UnityControllerFactory(IUnityContainer container)
{
_container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, String.Format("The controller for path '{0}' could not be found" +
"or it does not implement IController.",
requestContext.HttpContext.Request.Path));
}
return _container.Resolve(controllerType) as IController;
}
}
Addition information
Hi, I will post additional links that I come across, concerning the related issue and solution suggestions:
https://github.com/geersch/EntityFrameworkObjectContext
http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
attaching linq to sql datacontext to httpcontext in business layer
http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx
http://msdn.microsoft.com/en-us/library/bb738470.aspx
Yes do not share context and use one context per request. You can also check linked questions in that post to see all problems which a shared context caused.
Now about Unity. Idea of PerCallContextLifetimeManager works but I think provided implementation will not work for more than one object. You should use PerHttpRequestLifetimeManager directly:
public class PerHttpRequestLifetime : LifetimeManager
{
// This is very important part and the reason why I believe mentioned
// PerCallContext implementation is wrong.
private readonly Guid _key = Guid.NewGuid();
public override object GetValue()
{
return HttpContext.Current.Items[_key];
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[_key] = newValue;
}
public override void RemoveValue()
{
var obj = GetValue();
HttpContext.Current.Items.Remove(obj);
}
}
Be aware that Unity will not dispose context for you. Also be aware that default UnityContainer implementation will never call RemoveValue method.
If your implementation resolves all repositories in single Resolve call (for example if your controllers receives instances of repositories in constructor and you are resolving controllers) you don't need this lifetime manager. In such case use build-in (Unity 2.0) PerResolveLifetimeManager.
Edit:
I see pretty big problem in your provided configuration of UnityContainer. You are registering both repositories with ContainerControllerLifetimeManager. This lifetime manager means Singleton instance per container lifetime. It means that both repositories will be instantiated only once and instance will be stored and reused for subsequent calls. Because of that it doesn't matter what lifetime did you assign to MyEntities. It is injected to repositories' constructors which will be called only once. Both repositories will use still that single instance of MyEntities created during their construction = they will use single instance for whole lifetime of your AppDomain. That is the worst scenario you can achieve.
Rewrite your configuration this way:
var container = new UnityContainer();
container
.RegisterType<ProductsRepository>()
.RegisterType<CategoryRepository>()
.RegisterType<MyEntities>(new PerResolveLifetimeManager(), dbConnectionString);
Why this is enough? You are resolving controller which is dependent on repsitories but no repository instance is needed more then once so you can use default TransientLifetimeManager which will create new instance for each call. Because of that repository constructor is called and MyEntities instance must be resolved. But you know that multiple repositories can need this instance so you will set it with PerResolveLifetimeManager => each resolving of controller will produce only one instance of MyEntities.
As of Unity 3, there is already a built-in lifetime manager per http request.
PerRequestLifetimeManager
A LifetimeManager that holds onto the instance given to it during the lifetime of a single HTTP request. This lifetime manager enables you to create instances of registered types that behave like singletons within the scope of an HTTP request. See remarks for important usage information.
Remarks by MSDN
Although the PerRequestLifetimeManager lifetime manager works correctly and can help in working with stateful or thread-unsafe dependencies within the scope of an HTTP request, it is generally not a good idea to use it when it can be avoided, as it can often lead to bad practices or hard to find bugs in the end-user's application code when used incorrectly.
It is recommended that the dependencies you register are stateless and if there is a need to share common state between several objects during the lifetime of an HTTP request, then you can have a stateless service that explicitly stores and retrieves this state using the Items collection of the Current object.
The remarks say that even you are forced to use a single context per service (facade service), you should keep your service calls stateless.
Unity 3 is for .NET 4.5 by the way.
I believe the sample code shown on NerdDinner: DI in MVC using Unity for its HttpContextLifetimeManager should meet your needs.
I don't want to unnecessarily discourage you and by all means experiment but if you go ahead and use singleton instances of DataContext make sure you nail it.
It can appear to work fine on your dev environment but it could be failing to close connections properly. This will be hard to see without the load of a production environment. On a production environment with high load, undisposed connections will cause huge memory leaks and then high CPU trying to allocate new memory.
Have you considered what you are gaining from a connection per request pattern? How much performance there is to gain from opening/closing a connection once over say 3-4 times in a request? Worth the hassle? Also this makes lazy loading fails (read database queries in your view) a lot easier offences to make.
Sorry if this came across discouraging. Go for it if you really see the benefit. I'm just warning you that it could backfire quite seriously if you get it wrong so be warned. Something like entity profiler will be invaluable to getting it right - it tells you number of connections opened and closed - amongst other very useful things.
I saw question and answer few times ago. It is dated. Unity.MVC3 has life time manager as HierarchicalLifetimeManager.
container.RegisterType<OwnDbContext>(
"",
new HierarchicalLifetimeManager(),
new InjectionConstructor(connectionString)
);
and it works nice.
I would propose to solve it like this:
http://forums.asp.net/t/1644386.aspx/1
Best regards
I solved this by using Castle.DynamicProxy. I needed to have certain dependencies be injected "On Demand" meaning they needed to be resolved at time of use, not at time of "Depender" build up.
To do this I configure my container like so:
private void UnityRegister(IUnityContainer container)
{
container.RegisterType<HttpContextBase>(new OnDemandInjectionFactory<HttpContextBase>(c => new HttpContextWrapper(HttpContext.Current)));
container.RegisterType<HttpRequestBase>(new OnDemandInjectionFactory<HttpRequestBase>(c => new HttpRequestWrapper(HttpContext.Current.Request)));
container.RegisterType<HttpSessionStateBase>(new OnDemandInjectionFactory<HttpSessionStateBase>(c => new HttpSessionStateWrapper(HttpContext.Current.Session)));
container.RegisterType<HttpServerUtilityBase>(new OnDemandInjectionFactory<HttpServerUtilityBase>(c => new HttpServerUtilityWrapper(HttpContext.Current.Server)));
}
The idea being that I provide a method to retrieve the instance "on demand." The lambda gets invoked whenever any of the methods of the instance are used. The Dependent object is actually holding a reference to a proxied object, no the object itself.
OnDemandInjectionFactory:
internal class OnDemandInjectionFactory<T> : InjectionFactory
{
public OnDemandInjectionFactory(Func<IUnityContainer, T> proxiedObjectFactory) : base((container, type, name) => FactoryFunction(container, type, name, proxiedObjectFactory))
{
}
private static object FactoryFunction(IUnityContainer container, Type type, string name, Func<IUnityContainer, T> proxiedObjectFactory)
{
var interceptor = new OnDemandInterceptor<T>(container, proxiedObjectFactory);
var proxyGenerator = new ProxyGenerator();
var proxy = proxyGenerator.CreateClassProxy(type, interceptor);
return proxy;
}
}
OnDemandInterceptor:
internal class OnDemandInterceptor<T> : IInterceptor
{
private readonly Func<IUnityContainer, T> _proxiedInstanceFactory;
private readonly IUnityContainer _container;
public OnDemandInterceptor(IUnityContainer container, Func<IUnityContainer, T> proxiedInstanceFactory)
{
_proxiedInstanceFactory = proxiedInstanceFactory;
_container = container;
}
public void Intercept(IInvocation invocation)
{
var proxiedInstance = _proxiedInstanceFactory.Invoke(_container);
var types = invocation.Arguments.Select(arg => arg.GetType()).ToArray();
var method = typeof(T).GetMethod(invocation.Method.Name, types);
invocation.ReturnValue = method.Invoke(proxiedInstance, invocation.Arguments);
}
}
In Unity3, if you want to use
PerRequestLifetimeManager
You need to register UnityPerRequestHttpModule
I do this by using WebActivatorEx, the code is as below:
using System.Linq;
using System.Web.Mvc;
using Microsoft.Practices.Unity.Mvc;
using MyNamespace;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(UnityWebActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(UnityWebActivator), "Shutdown")]
namespace MyNamespace
{
/// <summary>Provides the bootstrapping for integrating Unity with ASP.NET MVC.</summary>
public static class UnityWebActivator
{
/// <summary>Integrates Unity when the application starts.</summary>
public static void Start()
{
var container = UnityConfig.GetConfiguredContainer();
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
// TODO: Uncomment if you want to use PerRequestLifetimeManager
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>Disposes the Unity container when the application is shut down.</summary>
public static void Shutdown()
{
var container = UnityConfig.GetConfiguredContainer();
container.Dispose();
}
}
}
PerRequestLifetimeManager and UnityPerRequestHttpModule classes are in Unity.Mvc package which has a dependency on ASP.NET MVC. If you don't want to have that dependency (e.g. you are using Web API) you will have to copy-paste them in to your app.
If you do that, don't forget the register the HttpModule.
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
Edit:
I'll include the classes here before CodePlex shuts down:
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Web;
using Microsoft.Practices.Unity.Mvc.Properties;
using Microsoft.Practices.Unity.Utility;
namespace Microsoft.Practices.Unity.Mvc
{
/// <summary>
/// Implementation of the <see cref="IHttpModule"/> interface that provides support for using the
/// <see cref="PerRequestLifetimeManager"/> lifetime manager, and enables it to
/// dispose the instances after the HTTP request ends.
/// </summary>
public class UnityPerRequestHttpModule : IHttpModule
{
private static readonly object ModuleKey = new object();
internal static object GetValue(object lifetimeManagerKey)
{
var dict = GetDictionary(HttpContext.Current);
if (dict != null)
{
object obj = null;
if (dict.TryGetValue(lifetimeManagerKey, out obj))
{
return obj;
}
}
return null;
}
internal static void SetValue(object lifetimeManagerKey, object value)
{
var dict = GetDictionary(HttpContext.Current);
if (dict == null)
{
dict = new Dictionary<object, object>();
HttpContext.Current.Items[ModuleKey] = dict;
}
dict[lifetimeManagerKey] = value;
}
/// <summary>
/// Disposes the resources used by this module.
/// </summary>
public void Dispose()
{
}
/// <summary>
/// Initializes a module and prepares it to handle requests.
/// </summary>
/// <param name="context">An <see cref="HttpApplication"/> that provides access to the methods, properties,
/// and events common to all application objects within an ASP.NET application.</param>
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Validated with Guard class")]
public void Init(HttpApplication context)
{
Guard.ArgumentNotNull(context, "context");
context.EndRequest += OnEndRequest;
}
private void OnEndRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var dict = GetDictionary(app.Context);
if (dict != null)
{
foreach (var disposable in dict.Values.OfType<IDisposable>())
{
disposable.Dispose();
}
}
}
private static Dictionary<object, object> GetDictionary(HttpContext context)
{
if (context == null)
{
throw new InvalidOperationException(Resources.ErrorHttpContextNotAvailable);
}
var dict = (Dictionary<object, object>)context.Items[ModuleKey];
return dict;
}
}
}
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using Microsoft.Practices.Unity.Mvc;
namespace Microsoft.Practices.Unity
{
/// <summary>
/// A <see cref="LifetimeManager"/> that holds onto the instance given to it during
/// the lifetime of a single HTTP request.
/// This lifetime manager enables you to create instances of registered types that behave like
/// singletons within the scope of an HTTP request.
/// See remarks for important usage information.
/// </summary>
/// <remarks>
/// <para>
/// Although the <see cref="PerRequestLifetimeManager"/> lifetime manager works correctly and can help
/// in working with stateful or thread-unsafe dependencies within the scope of an HTTP request, it is
/// generally not a good idea to use it when it can be avoided, as it can often lead to bad practices or
/// hard to find bugs in the end-user's application code when used incorrectly.
/// It is recommended that the dependencies you register are stateless and if there is a need to share
/// common state between several objects during the lifetime of an HTTP request, then you can
/// have a stateless service that explicitly stores and retrieves this state using the
/// <see cref="System.Web.HttpContext.Items"/> collection of the <see cref="System.Web.HttpContext.Current"/> object.
/// </para>
/// <para>
/// For the instance of the registered type to be disposed automatically when the HTTP request completes,
/// make sure to register the <see cref="UnityPerRequestHttpModule"/> with the web application.
/// To do this, invoke the following in the Unity bootstrapping class (typically UnityMvcActivator.cs):
/// <code>DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));</code>
/// </para>
/// </remarks>
public class PerRequestLifetimeManager : LifetimeManager
{
private readonly object lifetimeKey = new object();
/// <summary>
/// Retrieves a value from the backing store associated with this lifetime policy.
/// </summary>
/// <returns>The desired object, or null if no such object is currently stored.</returns>
public override object GetValue()
{
return UnityPerRequestHttpModule.GetValue(this.lifetimeKey);
}
/// <summary>
/// Stores the given value into the backing store for retrieval later.
/// </summary>
/// <param name="newValue">The object being stored.</param>
public override void SetValue(object newValue)
{
UnityPerRequestHttpModule.SetValue(this.lifetimeKey, newValue);
}
/// <summary>
/// Removes the given object from the backing store.
/// </summary>
public override void RemoveValue()
{
var disposable = this.GetValue() as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
UnityPerRequestHttpModule.SetValue(this.lifetimeKey, null);
}
}
}

Resources