Simple Injector でこれを解決する方法はいくつかあります。
まず第一に、複数のコンストラクターを持つことはアンチパターンであるため、コンポーネントには常に単一のコンストラクターを持たせてください。
ただし、提供されたタイプは外部ライブラリからのものであるため、変更することはできません。
代わりにできることは、この特定の型から派生させ、コンストラクターを 1 つだけ持つサブクラスを作成することです。この型は、関心のある基本クラスの特定のコンストラクターを呼び出すことができます。
class MyBaseClassManager<T> : BaseCacheManager<T>
{
public MyBaseClassManager([args]) : base([args]) { }
}
container.RegisterSingleton(typeof(ICacheManager<>), typeof(MyBaseCacheManager<>)):
ただし、一般的には、アプリケーションによって定義されていない抽象化にアプリケーション コードが依存しないようにする必要があります。これは依存関係逆転の原則(DIP) 違反であるためです。DIP は、アプリケーションに合わせた抽象化の定義へと私たちを導きます。このような抽象化に基づいて、呼び出しを外部コンポーネントに転送するアダプターを定義できます。例:
// In the application's core layer
public interface ICache<T>
{
}
// Adapter in the Composition Root
public sealed class CacheManagerCacheAdapter<T> : ICache<T>
{
private static BaseCacheManager<T> manager = new BaseCacheManager<T>();
// Implement ICache<T> methods
public object GetByKey(object key)
{
// translate and forward to the external component
return this.manager[key];
}
}
// Registration
container.RegisterSingleton(typeof(ICache<>), typeof(CacheManagerCacheAdapter<>)):
必要な閉じた型の数が限られている場合は、すべての閉じたバージョンを明示的に登録することもできます。
container.RegisterSingleton<ICacheManager<Foo>>(new BaseCacheManager<Foo>());
container.RegisterSingleton<ICacheManager<Bar>>(new BaseCacheManager<Bar>());
container.RegisterSingleton<ICacheManager<FooBar>>(new BaseCacheManager<FooBar>());
さらに別のオプションは、こちらで説明されているように、コンストラクターの解決動作をオーバーライドすることです。あなたはこれを行うことができます
public class CacheManagerConstructorResolutionBehavior
: IConstructorResolutionBehavior {
private readonly IConstructorResolutionBehavior org;
public CacheManagerConstructorResolutionBehavior(IConstructorResolutionBehavior org) {
this.org = org;
}
public ConstructorInfo GetConstructor(Type serviceType, Type implementationType) {
if (implementationType.IsGenericType &&
implementationType.GetGenericTypeDefinition() == typeof(BaseCacheManager<>)) {
return implementationType.GetConstructors()
.OrderByDescending(c => c.GetParameters().Length)
.First();
}
return this.org.GetConstructor(serviceType, implementationType);
}
}
var container = new Container();
container.Options.ConstructorResolutionBehavior =
new CacheManagerConstructorResolutionBehavior(
container.Options.ConstructorResolutionBehavior);
もう 1 つのオプションは、ResolveUnregisteredType` イベントにフックすることですが、これは最後の手段としてのみお勧めします。