Windsor container. Lifetime of objects in ASP.NET MVC application

535 Views Asked by At

I have a new project where Windsor container is used for IoC.

Here is simplified code executed in Install

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(Classes.FromThisAssembly().BasedOn<BaseController>().LifestyleTransient(), 
                       Component.For<ISecurityManager>().ImplementedBy<SecurityManager>(), 
                       Component.For<IAccountManager>().ImplementedBy<AccountManager>()
                       ........)
}

Information that I found in official documenation is not enough for understand in detail these lines.

Classes.FromThisAssembly().BasedOn<BaseController>().LifestyleTransient(), 

This line in Register method enables dependency injection to all classes in my application that are inherited from BaseController.

BaseController is included.

Injection will not be made to other classes than described above.

We show to container that lifetime of all controllers classes will be an instance.

Component.For<ISecurityManager>().ImplementedBy<SecurityManager>()

To all controllers registered above, if they have in constructor interface ISecurityManager will be injected instance of class SecurityManager.

Lifetime of this SecurityManager is singleton as default value. So after application start we will have only one instance of SecurityManager for all controllers till the end of application execution.

Are my ideas correct? It seems that not, at least because LifestyleTransient() for controllers seems to me strange and that injected objects will be singletons too.

1

There are 1 best solutions below

0
On BEST ANSWER

From bottom to the top :

Lifetime of this SecurityManager is singleton as default value. So after application start we will have only one instance of SecurityManager for all controllers till the end of application execution.

Exactly this is going to happen.

It seems that not, at least because LifestyleTransient() for controllers seems to me strange and that injected objects will be singletons too.

Controllers are transient because they hold the HttpContext - they have the information about the current user request and the following response. This is why they are transients and not singletons - the HttpContext is per request and it is created every time a browser/client requests something.

So it is understandable why controllers have shorter lifespan than your other services. It greatly depends on the inner architecture of the application. If someone else has a better idea why - I am more than willing to learn.

The Register/Resolve/Release cycle of your controllers can be done by creating a custom controller factory and substituting the default :

public class WindsorControllerFactory : DefaultControllerFactory
{
    private readonly IKernel _kernel;

    public WindsorControllerFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    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.", requestContext.HttpContext.Request.Path));
        }

        if (_kernel.GetHandler(controllerType) != null)
        {
            return (IController)_kernel.Resolve(controllerType);
        }
        return base.GetControllerInstance(requestContext, controllerType);
    }

    public override void ReleaseController(IController controller)
    {
        _kernel.ReleaseComponent(controller);
    }
}

and somewhere put :

 container.Register(Component.For<IControllerFactory>().ImplementedBy<WindsorControllerFactory>());

My controllers too have singleton dependenices. In this way you can achieve a pipeline programming model - you funnel the request from the controller through a series of objects and than return the results.

If SecurityManager has something to do with Authentication or Authorization it maybe better to use the MVC default Filtering mechanisms like IAuthorizationFilter or AuthorizeAttribute. Of course this maybe data access filter and it may be reasonable to put it in a different object.

Did I answer your questions?