Can multiple Autofac lifetime scopes be specified on a registration?

我只是一个虾纸丫 提交于 2019-11-29 09:01:00

问题


I'm using the Autofac IoC container with the MVC4 add-on which provides the InstancePerHttpRequest lifetime scope. However within my project I have the web, web-api and background worker threads. In the following example I assume the InstancePerHttpRequest scope doesn't mean much when not originating from a web request.

builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>()
    .InstancePerHttpRequest()

I'm wondering if it is possible to do something like the following example and have the container choose the most appropriate lifetime scope?

builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>()
    .InstancePerHttpRequest()
    .InstancePerApiRequest()
    .InstancePerDependency();

In this case what I intend to happen is if the request originates from a web request then it will choose the InstancePerHttpRequest scope, if it originates from an webApi request it will choose the InstancePerApiRequest scope and if it is used by the application worker threads it will use the InstancePerDependency scope?

Any ideas if this or something similar is possible?
Thanks


回答1:


This question has some fairly heavy overlap with these:

  • Managing AutoFac lifetime scopes per session and request in asp.net mvc 3
  • Instance per matching lifetime scope, with default?
  • Autofac - Lifetime and modules
  • Autofac Lifetimes and the Default Provider within a Matching Lifetime Scope

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.)



来源:https://stackoverflow.com/questions/16817655/can-multiple-autofac-lifetime-scopes-be-specified-on-a-registration

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