2017-11-29 18 views
1

永続クラスの代わりにデータクロスレイヤー/アセンブリを渡すためにDTOを使用する場合、永続モデルのクラスへのアクセスを同じアセンブリ内のオブジェクトに限定できます。依存関係注入は、クラスのスコープを「内部」に拡大しますか?

しかし、(依存性の注入のためのORM、AutoFacためNHibernateはを使用している)オーチャードCMSのようなシステムでは、持続性は、永続性のためIRepository<T>を提供する別のアセンブリを経由してあり、システムは、クラスのコンストラクタの1で私のアセンブリにIRepository<T>を注入し、したがって、永続クラスTをパブリックにする必要があります。依存関係注入がなければ、私はTを内部として定義し、IRepository<T>を私のアセンブリコード内で利用することができます。依存関係注入はクラスを常に公開する必要がありますか?

答えて

1

はい、容器は注射依存性の範囲はpublicに拡張することit generally requires 、インスタンス化供給依存することができるようにするためです。

実際には、依存性反転主体の別の一般的な(そして誤った) "悩み"は、現在注入されているクラスの内部依存関係のすべてが、典型的には公共のコンストラクタに公開されているということです。 3 Amigos "OOのプリンシパルであり、OOの校長は、クラスの内部的な依存関係をしっかりと隠していた。

当然のことながら、これは、デカップリングを防止し、悪化することを防ぐ直接的なクラスをその依存関係と直接結びつけることであった。これは、SOLID後の時代のコードがファーストクラスの設計上の懸念として認識される。

覚えておいていただきたいのは、クラス間の結合は常にインターフェイスを介して行われることです。このように、これらのパブリッククラスとコンストラクタを実際に "使用する"唯一のアクターは、コンテナ自体とユニットテストだけです。例によって

リポジトリ総会

public interface IFooRepo 
{ 
    Task<IEnumerable<Foo>> FindFoos(Predicate predicate); 
    // ... 
} 

// For IoC and testing purposes, MyFooRepo must be public 
public class MyFooRepo : IFooRepo 
{ 
    // .. Implement 
} 

サービスアセンブリ

// Note : No indication of the IFooRepository dependency here 
public interface IMyService 
{ 
    Task DoAmazingThingsWithFoo(); 
} 

// MyService class must also be public for IoC and tests 
public class MyService : IMyService 
{ 
    private readonly IMyRepo _repo; 
    // Dependencies are publically visible on the constructor 
    public MyService(IMyRepo repo) 
    { 
     _repo = repo; 
    } 
    // ... Implement 
} 

IoCのブートストラップ

Bind<IFooRepo>().To<MyFooRepo>(); // Can also specify lifetimes etc 
Bind<IMyService>().To<MyService>(); 

さらに読む - Mark Seemannはpublic scopeを徹底的に守っています。


[1]スティーブンあなたは、インターフェイスに対しても私の例が「カップリングは、典型的には、インターフェースに対してであるべきである」と指摘SimpleInjectの主要著者

+0

であるが、インタフェース自体に結合しますパブリッククラス(IRepository )、したがって、カップリングはまだインターフェイスの代わりにクラスに対して、私はまだインターフェイスだけにカップルできるように良い方法はありますか? –

+0

私は、他のクラスに依存するクラスは、インターフェース(SOLIDのD)を介してのみ結合されるべきであることを意味しました。 IoCのブートストラップ自体は決してエレガントなものではありません。インターフェースの依存関係が必要な場合に使用される具体的なクラスを一般的に定義します(IoCによっては命名規則に基づいて自動的にバインドされるものもあります)。私は例を更新しました。うまくいけば、これが明確になります。 – StuartLC

関連する問題