同じインターフェースから派生したサービスがあります。
public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService { }
public class ServiceC : IService { }
通常、他のIoCコンテナでは、Unity
具体的な実装を登録してKey
、それらを区別することができます。
ASP.NET Coreでは、これらのサービスを登録し、実行時にいくつかのキーに基づいてそれらを解決するにはどうすればよいですか?
or パラメータAdd
を取るServiceメソッドはありません。これは通常、具体的な実装を区別するために使用されます。key
name
public void ConfigureServices(IServiceCollection services)
{
// How do I register services of the same interface?
}
public MyController:Controller
{
public void DoSomething(string key)
{
// How do I resolve the service by key?
}
}
ここでFactoryパターンが唯一のオプションですか?
Update1 ここでは、ファクトリパターンを使用して複数の具体的な実装がある場合にサービスインスタンスを取得する方法を示す
記事を読みました。ただし、それでもまだ完全なソリューションではありません。メソッドを呼び出すと、コンストラクターにデータを注入できません。_serviceProvider.GetService()
たとえばこれを考えてみましょう:
public class ServiceA : IService
{
private string _efConnectionString;
ServiceA(string efconnectionString)
{
_efConnecttionString = efConnectionString;
}
}
public class ServiceB : IService
{
private string _mongoConnectionString;
public ServiceB(string mongoConnectionString)
{
_mongoConnectionString = mongoConnectionString;
}
}
public class ServiceC : IService
{
private string _someOtherConnectionString
public ServiceC(string someOtherConnectionString)
{
_someOtherConnectionString = someOtherConnectionString;
}
}
_serviceProvider.GetService()
適切な接続文字列を挿入するにはどうすればよいですか?Unityまたはその他のIoCライブラリでは、タイプ登録時にそれを行うことができます。IOptionを使用できますが、すべての設定を挿入する必要があります。特定の接続文字列をサービスに挿入できません。
また、他のすべてのコンテナー(コントローラーなど)も新しいコンテナーに登録する必要があるため、他のコンテナー(Unityを含む)の使用を避けようとしていることにも注意してください。
また、ファクトリパターンを使用してサービスインスタンスを作成することはDIPに反します。これにより、クライアントがここで詳細を保持する依存関係の数が増加します。
したがって、ASP.NET CoreのデフォルトのDIには次の2つが欠けていると思います。
- キーを使用してインスタンスを登録する機能
- 登録時に静的データをコンストラクターに挿入する機能
Update1
コンストラクタに物事を注入することは、どのオブジェクトを構築するかを決めることとは非常に異なるため、別の質問に移ることができます