Bootstrapper with Ninject using asp.net webapi - asp.net-web-api

I am trying to use Bootstrapper to do initialization for my application, ioc, automapper, configuration etc.
I need some direction on how to setup the ninject correctly in asp.net webapi using bootstrapper. With the following configuration, my apicontroller is not able to resolve the IMyService dependency. Looks like it's using different ninject kernal.
My NinjectWebCommon
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>();
GlobalConfiguration.Configuration.DependencyResolver = new MyResolver(kernel);
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)
{
}
}
bootstrapper ninject registration
public class DIRegistration : INinjectRegistration
{
public void Register(IKernel container)
{
container.Bind<IMyService>().To<MyService>().InTransientScope();
}
}
public class MyService: IMyService
{
public string GetString()
{
return "My String!!!!!";
}
}
public interface IMyService
{
string GetString();
}

What i did to solve the problem is moving bootstrapper.Initialize(CreateKernel); to the IStartupTask implementation i have created for NinjectWebBootstrap. Basically use the IKernal injected by the Bootstrapper framework and run my registration and at the end set asp.net webapi and then set DepdendencyResolver with the custom resolve that takes in the injected IKernal instance.

DIRegistration is never used. So that binding does not exist.

I was trying to update the values directly in database but values were not updated in my WCF which uses entity framework using Ninject in svc file - the same way as in https://github.com/ninject/ninject.extensions.wcf/tree/master/src/Examples/WcfTimeService and using bootstraping.
If found out that if I recycle the IIS app pool, the data gets refreshed and it works as expected. I guess it IIS and Ninject which is creating this caching issue. Do you have any idea about it?

Related

How to understand .netcore add scoped

I'm trying to understand the implementation or logic on how it works based on documentation. I am creating a .NET Core API
services.AddScoped<ICommanderRepo, SqlCommanderRepo>();
Documentation states that:
Adds a scoped service of the type specified in TService with an
implementation type specified in TImplementation to the specified
IServiceCollection.
public static IServiceCollection AddScoped<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService;
I want to know what is TService. And what is TImplementation. Because if i see it first time i dont know what it simply means.
SqlCommanderRepo implements ICommanderRepo interface.
public class SqlCommanderRepo : ICommanderRepo
{
private readonly CommanderContext _context;
public SqlCommanderRepo(CommanderContext context)
{
_context = context;
}
}
And CommanderContext extends DbContext
public class CommanderContext : DbContext
{
public CommanderContext(DbContextOptions<CommanderContext> opt) : base(opt)
{
}
}
What is TService. And what is TImplementation?
TService: The type of the service to add.
The contract for the service in your case is ICommanderRepo.
TImplementation : The type of the implementation to use.
The concrete type that implements the service in your case is SqlCommanderRepo.
From the source codes of ServiceCollectionServiceExtensions, AddScoped<TService, TImplementation> adds a scoped service of the type specified in TService with an implementation type specified in TImplementation to the specified IServiceCollection.
/// <summary>
/// Adds a scoped service of the type specified in <typeparamref name="TService"/> with an
/// implementation type specified in <typeparamref name="TImplementation"/> to the
/// specified <see cref="IServiceCollection"/>.
/// </summary>
/// <typeparam name="TService">The type of the service to add.</typeparam>
/// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
/// <seealso cref="ServiceLifetime.Scoped"/>
public static IServiceCollection AddScoped<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
return services.AddScoped(typeof(TService), typeof(TImplementation));
}
/// <summary>
/// Adds a scoped service of the type specified in <paramref name="serviceType"/> to the
/// specified <see cref="IServiceCollection"/>.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
/// <param name="serviceType">The type of the service to register and the implementation to use.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
/// <seealso cref="ServiceLifetime.Scoped"/>
public static IServiceCollection AddScoped(
this IServiceCollection services,
Type serviceType)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (serviceType == null)
{
throw new ArgumentNullException(nameof(serviceType));
}
return services.AddScoped(serviceType, serviceType);
}
Note:
Dependency injection in ASP.NET Core
Transient objects are always different; a new instance is provided to
every controller and every service.
Scoped objects are the same within a request, but different across
different requests.
Singleton objects are the same for every object and every request.

What's an xUnit runsettings equivalent?

We have several environments that had their own run settings when we used MSTest. Since Microsoft is abandoning MSTest we are switching to xUnit. Whether it's through a runsettings or a command line property, I need a way to specify TestRunParameters in my xUnit test. Does xUnit have a native way to do that like MSTest or do I need to come up with my own solution?
While you can still use RunSettings to control some aspects of vstest.console while using xUnit the current version does not have a native way to pass in parameters. I believe v3 is going to have some kind of parameter passing.
For now you could use environment variables but if you are running multiple tests sets in parallel on the same system you would have conflicts.
I use a base class which reads in a TestSettings.json file with the settings for that test set. Using the following code I am able to pass in new types and have them read in by the base class json reader.
/// <inheritdoc />
/// <summary>
/// Common TestBase which uses CommonSettingsModel. Use TestBase<T> to override with custom settings Type.
/// </summary>
public abstract class TestBase : TestBase<CommonSettingsModel>
{
}
/// <inheritdoc />
/// <summary>
/// Common TestBase for loading settings.
/// </summary>
/// <typeparam name="T">Type to read TestSettings.json file</typeparam>
public abstract class TestBase<T> where T : ICommonSettings, new()
{
/// <inheritdoc />
/// <summary>
/// Constructor loads Settings T
/// </summary>
protected TestBase()
{
Settings = SettingsUtil.GetSettings<T>();
}
/// <summary>
/// Settings T loaded from TestSettings.json
/// </summary>
protected T Settings { get; }
}
You could also do the same type of thing with a Class or AssemblyFixture for the tests.
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public SqlConnection Db { get; private set; }
}
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture fixture;
public MyDatabaseTests(DatabaseFixture fixture)
{
this.fixture = fixture;
}
// ... write tests, using fixture.Db to get access to the SQL Server ...
}
https://xunit.net/docs/shared-context

ASP.Net MVC 3 project with Ninject and HierarchicalLifetimeManager?

First of all, dependency injection is relatively new to me. I did a first project using Unity.MVC3, and now I would like to switch to Ninject on a new project, since it seems to be the most popular dependency injector for .Net projects. So now, I am trying to use Ninject v2.2.1.4 with Ninject.MVC3 v2.2.2.0 in my project.
In my previous project where I was using Unity, I had something like the following code in my Bootstrapper class:
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.RegisterType<ITestService, TestService>();
container.RegisterType<IDatabaseFactory, DatabaseFactory>(new HierarchicalLifetimeManager());
container.RegisterType<IUnitOfWork, UnitOfWork>();
container.RegisterType<ILoggingService, LoggingService>();
container.RegisterControllers();
return container;
}
Now, I my new project, I replaced this with something like the following code in the NinjectMVC3 class (App_Start):
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ITestService>().To<TestService>();
//This does not compile:
//kernel.Bind<IDatabaseFactory>().To<DatabaseFactory>(new HierarchicalLifetimeManager());
kernel.Bind<IDatabaseFactory>().To<DatabaseFactory>();
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
kernel.Bind<ILoggingService>().To<LoggingService>();
}
However, I don't know what I should do with the DatabaseFactory binding, since it normally requires the use of HierarchicalLifetimeManager. Can anyone tell me how to properly create the binding for DatabaseFactory?
First of all, add these references bu NuGet to be sure that you have a compatible set of packages.
Then, if you add the Ninject.Web.MVC it will setup the project initialization code for you through a power shell script.
And last make a BindModule class like this and add it to module in CreateKernel method that have been created in second step.
public class BindModule : NinjectModule
{
public override void Load()
{
this.Bind<IControllerActivator>().To<CustomControllerActivator>().InRequestScope();
this.Bind<MembaseClient>().ToMethod(context => new MembaseClient()).InSingletonScope();
this.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
this.Bind<ISessionFactory>().ToMethod(o => MyAutoMapper.sessionFactory).InSingletonScope();
this.Bind<ISession>().ToMethod(o => MyAutoMapper.sessionFactory.OpenSession()).InRequestScope();
}
}
Part of NinjectMVC3 class
public static class NinjectMVC3
{
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var modules = new NinjectModule[] { new BindModule() };
var kernel = new StandardKernel(modules);
RegisterServices(kernel);
return kernel;
}
}
As you can see above Ninjet has built in functions to take care of different life cycles for each object.

How to use Ninject to inject services into MVC 3 FilterAttributes?

I'm writing a custom ErrorHandler attribute for my MVC project. I would like to inject an implementation of EventViewerLogger into that attribute.
I'm using Ninject 2.2 and it works fine for other features, such as injection repositories and aggregate services through controller constructors.
I understand that I can't inject an implementation of some class into attribute through constructor, therefore I have to inject it into the attribute's property.
Interface is below:
namespace Foo.WebUI.Infrastructure
{
public interface ILogger
{
void Log(Exception e);
}
}
Event viewer logger implementation
namespace Foo.WebUI.Infrastructure
{
/// <summary>
/// Logs exceptions into the Windows Event Viewer
/// </summary>
public class EventViewerLogger: ILogger
{
private EventViewerLogger _logger = null;
EventViewerLogger()
{
_logger = new EventViewerLogger();
}
public void Log(Exception e)
{
_logger.Log(e);
}
}
}
Below is code for error handler:
namespace Foo.WebUI.Handlers
{
/// <summary>
/// Custom error handler with an interface to log exceptions
/// </summary>
public class CustomHandleErrorAttribute: HandleErrorAttribute
{
[Inject]
public ILogger Logger { get; set; }
// Default constructor
public CustomHandleErrorAttribute():base() { }
public override void OnException(ExceptionContext filterContext)
{
Logger.Log(filterContext.Exception);
base.OnException(filterContext);
}
}
}
In global.asax I register the handler and Ninject.
protected void Application_Start()
{
IKernel kernel = new StandardKernel(new NinjectInfrastructureModule());
}
Finally, I have a custom filter provider
namespace Foo.WebUI.Infrastructure
{
public class NinjectFilterProvider: FilterAttributeFilterProvider
{
private readonly IKernel kernel;
public NinjectFilterProvider(IKernel kernel)
{
this.kernel = kernel;
}
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
// Iterate through all the filters and use Ninject kernel to serve concrete implementations
foreach (var filter in filters)
{
kernel.Inject(filter.Instance);
}
return filters;
}
}
}
When I start the application I get the following exception:
Activation path:
2) Injection of dependency ILogger into property Logger of type CustomHandleErrorAttribute
1) Request for CustomHandleErrorAttribute
Suggestions:
1) Ensure that the implementation type has a public constructor.
2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.
Source Error:
Line 27: foreach (var filter in filters)
Line 28: {
Line 29: kernel.Inject(filter.Instance);
Line 30: }
Spent a day on this, learnt a lot about dependecy injection which is great, but what am I doing wrong here?
Ninject.Web.Mvc has this functionality built in called "BindFilter" which lets you map an attribute (that takes some or no constructor args) to a filter (which has its constructor args injected). Additionally, you can use it to copy values from the attribute and inject them as constructor args to the filter if you want. It also lets you change scope on your filters to be per action or per controller etc so that they actually get re-instantiated (normal action filters don't get re-instantiated per request).
Here's an example of how I've used it to do a UoW action filter.

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