鉴于您的用例描述,我会说你有几个选项。
首先,您可以让每个应用程序注册自己的一组依赖关系,包括生命周期范围。在这方面有一两个“重复”的代码片段并不是什么大问题,因为考虑到应用程序与注册似乎很小的事实之间的差异。
二,您可以将公共部分(减去生命周期范围)包装到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
除非这其实你想要什么。正如在其他回答/评论中指出的那样,InstancePerHttpRequest
使用特定的命名生命周期范围,以便创建子周期范围是安全的;使用InstancePerLifetimeScope
没有这样的限制,所以实际上你会得到每个子范围的一个连接,而不是请求的一个连接。我个人不认为其他开发人员不会使用子女生命期范围(which is a recommended practice),所以在我的应用程序中我非常具体。如果您完全控制您的应用程序,并且可以确保您没有创建额外的子范围,或者您确实希望每个范围都有一个连接,那么也许InstancePerLifetimeScope
将解决您的问题。
你有关于连接的具体生命时间吗?如果是这样,每个应用程序的生命周期是不同的,还是不管应用程序的类型如何都是相同的?怎么样汇集?你是否在某些应用中游泳,但不是其他人? –
就像你说的那样:“MVC扩展使用一个命名范围来实现一次一次请求机制。”当您在控制台应用程序中使用模块时,名为范围的Http不存在。目前我正在研究工作单元的内容,并将其封装在一个范围内。 –