0

Unityからシンプルインジェクタに移行しようとしています。シンプルインジェクタでインジェクションを動作させるのに問題があります。複数のコンストラクタでジェネリックタイプを登録する

ワーキングユニティコード

var container = new UnityContainer(); 
DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 

container.RegisterType(
    typeof(ICacheManager<>), 
    new ContainerControlledLifetimeManager(), 
    new InjectionFactory((c, targetType, name) => 
     CacheFactory.FromConfiguration(targetType.GenericTypeArguments[0], "myCache"))); 

私の試みを下回っている:

var registration = Lifestyle.Singleton.CreateRegistration(
    typeof(ICacheManager<>), 
    typeof(BaseCacheManager<>), 
    container); 

container.AddRegistration(
    serviceType: typeof(BaseCacheManager<>), 
    registration: registration); 

コンテナは、それが持つべきBaseCacheManager<Object>を作成できるようにするために、私は次のようなエラーに

を取得しています1つの公共コンストラクタ

+0

型にコンストラクタが1つしかないことを確認する必要があります。他のコンストラクタを削除します。 – Steven

+0

返事をお寄せいただきありがとうございます。私はCacheManager.netの外部ライブラリを使用してキャッシュを支援しています。 2番目のコンストラクタを削除する以外の方法はありますか? –

+0

これを処理できるDIフレームワークを使用できませんか?新しい軽量のMS(ドットネットコア)でもそれに対処できます。クラスの公開者を1人だけ許可するのはかなり大きな制限です~~ – MichaC

答えて

1

Simple Injectorでこれを解決する方法はいくつかあります。

まず、コンポーネントには常にmultiple constructors is an anti-patternを持つ単一のコンストラクタを使用させます。

ただし、提供されるタイプは外部ライブラリからのものなので、変更することはできません。

代わりにできることは、この特定の型から派生し、1つのコンストラクタしか持たないサブクラスを作成することです。このタイプは、あなたが興味を持っている基本クラスの特定のコンストラクタに呼び出すことができます。しかし、あなたはあなたのアプリケーション・コードを持つ防ぐ必要があり、一般的に

class MyBaseClassManager<T> : BaseCacheManager<T> 
{ 
    public MyBaseClassManager([args]) : base([args]) { } 
} 

container.RegisterSingleton(typeof(ICacheManager<>), typeof(MyBaseCacheManager<>)): 

これであるため、アプリケーションによって定義されていない抽象化に依存Dependency Inversion Principle(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<>)): 

登録することができます。hereが説明したように

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); 

さらに別のオプションは、私は最後の手段としてのみこれを助言するだろうがResolveUnregisteredType` event上にフックするためですを行うことができます。

+0

ありがとう、スティーブン、本当にありがとう、この質問に答える時間。 CacheManagerライブラリがDIPに違反しているので、私は他の実装を調べ始め、このhttps://github.com/exceptionless/Foundatio#cachingを見つけました。 –

+0

こんにちは@WebbyWebDeveloper。その図書館はDIPに違反していません。あなたのアプリケーションはです。アプリケーションでは任意のライブラリを使用できますが、DIPはアプリケーションのメインコードからライブラリを隠すように指示します。 – Steven

+0

ちょっとした注意:BaseCacheManagerはライブラリの次のバージョンに1つのctorしか持たないでしょう。私は数日前にそれを変更しました、実際に面白い、今すぐ現れます;) それ以外は、一般的には、複数のctorが問題になることに全く反対します。あなたは常に第三者図書館を扱わなければならず、DIフレームワークは決してあなたにこのような制約を課すべきではありません。幸いなことに、これらのフレームワークの多くがあります。もう1つを選択することができます^^ – MichaC

関連する問題