Can multiple Autofac lifetime scopes be specified on a registration?

自古美人都是妖i 提交于 2019-11-30 07:27:10
Travis Illig

This question has some fairly heavy overlap with these:

You'll want to check those out for some ideas.

The short answer is: This sort of thing isn't supported out of the box. You'll need to do one of a couple of things.

Option: You could have a different container for the background threads. This wouldn't allow you to share application-level singletons, but that might be OK for your application.

Option: You could create two lifetime scopes off the container and do the different registrations as part of the call to BeginLifetimeScope. This would allow you to share application-level singletons and have different lifetime scopes for the same components in different contexts. It's a little harder to manage the registrations, though, and you'll need two different service locators (e.g., DependencyResolver) because each logical context would need to resolve from its own scope.

var builder = new ContainerBuilder();
builder.RegisterType<AppLevelSingleton>().SingleInstance();
var container = builder.Build();

// Create a nested lifetime scope for your background threads
// that registers things as InstancePerDependency, etc. Pass
// that scope to whatever handles dependency resolution on the thread.
var backgroundScope = container.BeginLifetimeScope(
  b => b.RegisterType<DatabaseFactory>()
        .As<IDatabaseFactory>()
        .InstancePerDependency());

// Create a nested lifetime scope for the web app that registers
// things as InstancePerHttpRequest, etc. Pass that scope
// as the basis for the MVC dependency resolver.
var webScope = container.BeginLifetimeScope(
  b => b.RegisterType<DatabaseFactory>()
        .As<IDatabaseFactory>()
        .InstancePerHttpRequest());
var resolver = new AutofacDependencyResolver(webScope);
DependencyResolver.SetResolver(resolver);

If you really wanted to get fancy with this option, you could implement a custom IContainer that can detect which context it's in and resolves things from the appropriate nested scope. This is how the multitenant Autofac support works. However, that's a much more involved solution so I'm not going to write that all out here. Check the Autofac source for the multitenant support for examples.

Option: You could use a "lowest common denominator" sort of registration like InstancePerDependency or InstancePerLifetimeScope and skip the notion of having a different lifetime for different parts of the application.

Note that, right now, technically, internally, there is no difference between what InstancePerHttpRequest and InstancePerWebApiRequest do. They both boil down to exactly the same thing and are effectively interchangeable. (I can't promise it'll always be that way forever, but I don't know why it would need to change.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!