可以在注册中指定多个 Autofac 生命周期范围吗? [英] Can multiple Autofac lifetime scopes be specified on a registration?

查看:22
本文介绍了可以在注册中指定多个 Autofac 生命周期范围吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 Autofac IoC 容器与提供 InstancePerHttpRequest 生命周期范围的 MVC4 附加组件一起使用.但是在我的项目中,我有 web、web-api 和后台工作线程.在下面的示例中,我假设 InstancePerHttpRequest 范围在不是源自 Web 请求时没有多大意义.

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();

在这种情况下,我打算发生的是,如果请求源自 Web 请求,那么它将选择 InstancePerHttpRequest 范围,如果它源自 webApi 请求,它将选择 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

推荐答案

这个问题与这些问题有很大的重叠:

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.

选项:您可以在容器之外创建两个生命周期作用域,并在调用 BeginLifetimeScope 时进行不同的注册.这将允许您共享应用程序级单例,并且对于不同上下文中的相同组件具有不同的生命周期范围.但是,管理注册有点困难,您将需要两个不同的服务定位器(例如,DependencyResolver),因为每个逻辑上下文都需要从其自己的范围进行解析.

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

如果你真的想喜欢这个选项,你可以实现一个自定义的 IContainer,它可以检测它所在的上下文并从适当的嵌套范围解析事物.这就是多租户 Autofac 支持的工作原理.然而,这是一个更复杂的解决方案,所以我不打算在这里写下所有内容.检查 Autofac 源以获取示例的多租户支持.

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.

选项:您可以使用最低公分母"类型的注册,例如 InstancePerDependencyInstancePerLifetimeScope 并跳过具有不同应用程序不同部分的生命周期.

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.

请注意,目前,从技术上讲,在内部,InstancePerHttpRequestInstancePerWebApiRequest 的作用没有区别.它们都归结为完全相同的东西,并且可以有效地互换.(我不能保证永远都是这样,但我不知道为什么需要改变.)

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

这篇关于可以在注册中指定多个 Autofac 生命周期范围吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆