鉴于您的用例描述,我想说您有几个选择。
首先,您可以让每个应用程序注册自己的一组依赖项,包括生命周期范围。考虑到应用程序之间的差异以及注册看起来相当小的事实,在这方面拥有一两段“重复”代码并不是什么大问题。
其次,您可以将公共部分(减去生命周期范围)包装到可在每个应用程序中使用的 ContainerBuilder 扩展方法中。这仍然意味着每个应用程序都有一些“重复代码”,但通用逻辑将被包装在一个简单的扩展中。
public static IRegistrationBuilder<TLimit, ScanningActivatorData, DynamicRegistrationStyle>
RegisterConnection<TLimit, ScanningActivatorData, DynamicRegistrationStyle>(this ContainerBuilder builder)
{
// Put the common logic here:
builder.Register(...).AsImplementedInterfaces();
}
在每个应用程序中使用这样的扩展程序如下所示:
builder.RegisterConnection().InstancePerHttpRequest();
// or
builder.RegisterConnection().InstancePerLifetimeScope();
最后,如果您知道它是 Web 还是非 Web,您可以制作一个处理开关的自定义模块:
public class ConnectionModule : Autofac.Module
{
bool _isWeb;
public ConnectionModule(bool isWeb)
{
this._isWeb = isWeb;
}
protected override void Load(ContainerBuilder builder)
{
var reg = builder.Register(...).AsImplementedInterfaces();
if(this._isWeb)
{
reg.InstancePerHttpRequest();
}
else
{
reg.InstancePerLifetimeScope();
}
}
}
在每个应用程序中,您可以注册模块:
// Web application:
builder.RegisterModule(new ConnectionModule(true));
// Non-web application:
builder.RegisterModule(new ConnectionModule(false));
或者,您提到您在其他应用中的生命周期范围有一个名称。 你可以让你的模块取名:
public class ConnectionModule : Autofac.Module
{
object _scopeTag;
public ConnectionModule(object scopeTag)
{
this._scopeTag = scopeTag;
}
protected override void Load(ContainerBuilder builder)
{
var reg = builder.Register(...)
.AsImplementedInterfaces()
.InstancePerMatchingLifetimeScope(this._scopeTag);
}
}
消费类似:
// Web application (using the standard tag normally provided):
builder.RegisterModule(new ConnectionModule("httpRequest"));
// Non-web application (using your custom scope name):
builder.RegisterModule(new ConnectionModule("yourOtherScopeName"));
我建议不要在 Web 应用程序中简单地使用 InstancePerLifetimeScope,除非这确实是您想要的。 正如其他答案/cmets 中所述,InstancePerHttpRequest 使用特定的命名生命周期范围,因此它是安全地创建子生命周期范围;使用InstancePerLifetimeScope 没有这样的限制,所以实际上每个子作用域只有一个连接,而不是请求的一个连接。我个人并不认为其他开发人员不会使用子生命周期范围 (which is a recommended practice),所以在我的应用程序中我非常具体。如果您可以完全控制您的应用程序,并且可以确保您没有创建额外的子作用域,或者您确实希望每个作用域有一个连接,那么InstancePerLifetimeScope 可能会解决您的问题。