1
votes

I have Castle Windsor Ioc in my MVC application. I have noticed that Objects tracked by release policy count is growing up all the time and as it seems this objects are never released(memory is growing up).

The code is:

public class ControllersInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromThisAssembly()
            .BasedOn<IController>()
            .LifestyleTransient());
    }
}

In global.asax i have:

 controllerFactory = new WindsorControllerFactory();
 ControllerBuilder.Current.SetControllerFactory(controllerFactory);
 controllerFactory.ValidateControllersResolution();

And class is:

public class WindsorControllerFactory: DefaultControllerFactory{
    private readonly IWindsorContainer container;

    public WindsorControllerFactory()
    {
        container = new WindsorContainer()
            .Install(FromAssembly.This())
            .AddFacility<WcfFacility>();
         default policy is: LifecycledComponentsReleasePolicy
        //container.Kernel.ReleasePolicy;
    }

    public override void ReleaseController(IController controller)
    {
        //this is called after each view return
        container.Kernel.ReleaseComponent(controller);
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            throw new HttpException(404,
                $"The controller for path '{requestContext.HttpContext.Request.Path}' could not be found.");
        }

        var controller=  ((IController)container.Kernel.Resolve(controllerType)).AddControllerLoggingFunctionality();
        return controller;
    }

    public void DisposeContainer()
    {//this is never executed
        container.Dispose();
    }

In WEB API version: Web API with Castle Windsor there is register for dispose before returning controller:

request.RegisterForDispose(
        new Release(
            () => this.container.Release(controller)));

But in my case there is RequestContext instead of HttpRequestMessage, which doesn't have RegisterForDispose method. Is there some other way to register for dispose or some other way to dispose controller after view is returned?

Or I'm not on the right track?

1
I'm confused. The question title refers to MVC but in MVC, releasing is entirely handled by the ControllerFactory in MVC. Are you saying the ReleaseController method in your ControllerFactory is not being called?Phil Degenhardt

1 Answers

0
votes

The RegisterForDispose() method only exists on HttpRequestMessage because it is capable of associating arbitrary objects with the request for the duration of the request through its Properties collection. Even the framework itself uses it (in GetOwinContext(), for example).

On the other hand, the traditional HttpRequest (that is available for MVC controllers) does not expose this capability* hence no RegisterForDispose() is provided.

* (Although you can associate arbitrary items to the HttpContext.Items, that is generally used to pass data between modules. If you were to use it to associate items to the current request, you'll have to dispose them manually as well