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();
builder.RegisterType<SystemDateTimeProvider>().InstancePerRequest().As<IDateTimeProvider>();
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 , -? ?