はい、容器は注射依存性の範囲は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の主要著者
であるが、インタフェース自体に結合しますパブリッククラス(IRepository)、したがって、カップリングはまだインターフェイスの代わりにクラスに対して、私はまだインターフェイスだけにカップルできるように良い方法はありますか? –
私は、他のクラスに依存するクラスは、インターフェース(SOLIDのD)を介してのみ結合されるべきであることを意味しました。 IoCのブートストラップ自体は決してエレガントなものではありません。インターフェースの依存関係が必要な場合に使用される具体的なクラスを一般的に定義します(IoCによっては命名規則に基づいて自動的にバインドされるものもあります)。私は例を更新しました。うまくいけば、これが明確になります。 – StuartLC