How to use Autofac to resolve instance dependencies for each request for Nancy-created types in lifespan

We have several applications hosted on Windows services that host the Nancy endpoint on their own in order to expose application tools.

We use Autofac as our IOC. Multiple repositories are registered in the root container in the main DLL shared by all applications; this container is then passed to Nancy as its container, using the bootloader obtained from Nancy.Autofac.Bootstrapper.

We found that when a web request was received by Nancy, it resolves the repository request from the root container, and this leads to the memory being consumed by uncollected garbage IDisposable, since the root container does not exit (it has a Windows lifetime). This caused a memory leak in the services.

Then we switched to the model, where we added registration for repositories, using Nancy InstancePerRequestin the overridden method ConfigureRequestContainer()in our boot device:

protected override void ConfigureRequestContainer(ILifetimeScope container, NancyContext context)
{
    base.ConfigureRequestContainer(container, context);
    PerRequestContainerBuilder().Update(container.ComponentRegistry);
}

private static ContainerBuilder PerRequestContainerBuilder()
{
    var builder = new ContainerBuilder();

    // Dependency for repository
    builder.RegisterType<SystemDateTimeProvider>().InstancePerRequest().As<IDateTimeProvider>();

    // Repository
    builder.RegisterType<BookmarkRepository>().InstancePerRequest().As<IBookmarkRepository>();

    return builder;
}

We also override the method CreateRequestContainer()for creating the request container with the tag MatchingScopeLifetimeTags.RequestLifetimeScopeTag.

protected override ILifetimeScope CreateRequestContainer(NancyContext context)
{
     return ApplicationContainer.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
}

It seems that the problem has IDisposablenot been resolved - the child request container is located at the end of the web request pipeline, and the objects allowed by it are also deleted and eventually garbage collected.

, , -, , ConfigureRequestContainer(), , , , " ", , - .

Autofac , -? ?

+4
1

Autofac "" . InstancePerRequest, Autofac MatchingScopeLifetimeTags.RequestLifetimeScopeTag, .

, Nancy bootstrapper ConfigureRequestContainer . ! , InstancePerRequest ( Nancy 1.1), .

:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var builder = new ContainerBuilder();

        // Do request-scoped registrations using InstancePerRequest...

        var container = builder.Build();

        // Pass the pre-built container to the bootstrapper
        var bootstrapper = new MyAwesomeNancyBootstrapper(container);

        app.UseNancy(options => options.Bootstrapper = bootstrapper);
    }
}
public class MyAwesomeNancyBootstrapper : AutofacNancyBootstrapper
{
    private readonly ILifetimeScope _lifetimeScope;

    public MyAwesomeNancyBootstrapper(ILifetimeScope lifetimeScope)
    {
        _lifetimeScope = lifetimeScope;
    }

    protected override ILifetimeScope GetApplicationContainer()
    {
        return _lifetimeScope; // Tell Nancy you've got a container ready to go ;)
    }
}

( Nancy 1.1. CreateRequestContainer ).

. https://github.com/khellang/Nancy.AutofacExample

+6

All Articles