依存性解決の一部としてランタイムパラメータを渡すにはどうすればよいですか?
2023-11-20 21:30:41
質問
私のサービスの実装の一部に接続文字列を渡すことができるようにする必要があります。私はこれをコンストラクタで行っています。接続文字列はユーザが設定可能で、ClaimとしてClaimsPrincipalに追加されます。
今のところ問題ありません。
残念ながら、ASP.NET Coreの依存性注入機能をフルに使って、DIでサービス実装を解決できるようにしたいとも思っています。
POCインプリメンテーションがあるのですが。
public interface IRootService
{
INestedService NestedService { get; set; }
void DoSomething();
}
public class RootService : IRootService
{
public INestedService NestedService { get; set; }
public RootService(INestedService nestedService)
{
NestedService = nestedService;
}
public void DoSomething()
{
// implement
}
}
public interface INestedService
{
string ConnectionString { get; set; }
void DoSomethingElse();
}
public class NestedService : INestedService
{
public string ConnectionString { get; set; }
public NestedService(string connectionString)
{
ConnectionString = connectionString;
}
public void DoSomethingElse()
{
// implement
}
}
これらのサービスは、起動時に登録され
INestedService
はコントローラのコンストラクタに追加されます。
public HomeController(INestedService nestedService)
{
NestedService = nestedService;
}
予想通り、エラーが発生しました。
Unable to resolve service for type 'System.String' while attempting to activate 'Test.Dependency.Services.NestedService'.
ここで私のオプションは何ですか?
どのように解決するのですか?
アプリケーションの開始時に知られていない実行時パラメータを渡すには、ファクトリーパターンを使用する必要があります。ここでは2つのオプションがあります。
-
ファクトリクラス (どのように
IHttpClientFactory
が実装されています)public class RootService : IRootService { public RootService(INestedService nested, IOtherService other) { // ... } } public class RootServiceFactory : IRootServiceFactory { // in case you need other dependencies, that can be resolved by DI private readonly IServiceProvider services; public RootServiceFactory(IServiceProvider services) { this.services = services; } public IRootService CreateInstance(string connectionString) { // instantiate service that needs runtime parameter var nestedService = new NestedService(connectionString); // note that in this example, RootService also has a dependency on // IOtherService - ActivatorUtilities.CreateInstance will automagically // resolve that dependency, and any others not explicitly provided, from // the specified IServiceProvider return ActivatorUtilities.CreateInstance<RootService>(services, new object[] { nestedService, }); } }
を注入し
IRootServiceFactory
の代わりにIRootService
IRootService rootService = rootServiceFactory.CreateInstance(connectionString);
-
ファクトリーメソッド
services.AddTransient<Func<string,INestedService>>((provider) => { return new Func<string,INestedService>( (connectionString) => new NestedService(connectionString) ); });
の代わりに、ファクトリーメソッドをサービスに注入してください。
INestedService
public class RootService : IRootService { public INestedService NestedService { get; set; } public RootService(Func<string,INestedService> nestedServiceFactory) { NestedService = nestedServiceFactory("ConnectionStringHere"); } public void DoSomething() { // implement } }
または呼び出しごとに解決する
public class RootService : IRootService { public Func<string,INestedService> NestedServiceFactory { get; set; } public RootService(Func<string,INestedService> nestedServiceFactory) { NestedServiceFactory = nestedServiceFactory; } public void DoSomething(string connectionString) { var nestedService = nestedServiceFactory(connectionString); // implement } }
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み] [Solved] アセンブリ System.Web.Extensions dll はどこにありますか?
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み] Could not find a part of the path ... binroslyncsc.exe
-
[解決済み] 他のスレッドからGUIを更新するにはどうすればよいですか?
-
[解決済み] エンティティフレームワークのタイムアウト
-
[解決済み] intをenumにキャストするにはどうすればよいですか?
-
[解決済み] ランダムな英数字の文字列を生成するにはどうすればよいですか?
-
[解決済み] .NETコンソールアプリケーションでアプリケーションのパスを取得するにはどうすればよいですか?
-
[解決済み] C#でメソッドをパラメータとして渡す
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】C#で四捨五入する方法
-
[解決済み】Unity3DでOnTriggerEnterが動作しない件
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み] 2つのリストを結合する
-
[解決済み】画像のペイントにTextureBrushを使用する方法
-
[解決済み] .NET Core DI、コンストラクタにパラメータを渡す方法