ユースケースの説明を考えると、いくつかのオプションがあると思います。
まず、ライフタイムスコープを含む独自の依存関係のセットを各アプリケーションに登録させることができます。この点で1つまたは2つの「重複した」コードがあることは、アプリケーションと登録がかなり小さいように見えるという事実との違いを考えると、それほど大きな問題ではありません。
次に、共通部分(ライフタイムスコープを除く)を、各アプリケーションで使用できる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"));
InstancePerLifetimeScope
実際に意図したものでない限り、単にWebアプリケーションで使用することはお勧めしません。他の回答/コメントに記載されてInstancePerHttpRequest
いるように、子のライフタイムスコープを安全に作成できるように、特定の名前付きライフタイムスコープを使用します。usingInstancePerLifetimeScope
にはそのような制限がないため、リクエストに対して1つの接続ではなく、子スコープごとに1つの接続を実際に取得します。私は個人的に、他の開発者が子のライフタイムスコープを使用しないとは思いません(これは推奨される方法です)。そのため、私のアプリケーションでは非常に具体的です。アプリケーションを完全に制御していて、追加の子スコープを作成していないこと、またはスコープごとに1つの接続が実際に必要であることを確認できる場合は、InstancePerLifetimeScope
あなたの問題を解決します。