「C#を介したアダプティブコード」の本で「階段」パターンの説明に遭遇しましたが、これがどのように実装されることになっているのか本当にわかりません。
( ソース )
だから私はクライアントアセンブリを持っています:
_using ServiceInterface;
namespace Client
{
class Program
{
static void Main(string[] args)
{
// Have to create service implementation somehow
// Where does ServiceFactory belong?
ServiceFactory serviceFactory = new ServiceFactory();
IService service = serviceFactory.CreateService();
service.Do();
}
}
}
_
サービスインターフェイスアセンブリ:
_namespace Service
{
public interface IService
{
void Do();
}
}
_
そしてサービス実装アセンブリ:
_using ServiceInterface;
namespace ServiceImplementation
{
public class PrintService : IService
{
public void Do()
{
Console.WriteLine("Some work done");
}
}
}
_
そして問題は、IService
名前空間でClient
オブジェクトを取得する方法です。実際のnew PrintService()
オブジェクト作成はどこに配置すればよいですか?インターフェイスアセンブリはServiceInterface
に依存しないため、これをServiceImplementation
の一部にすることはできません。ただし、Client
はServiceImplementation
にのみ依存する必要があるため、Client
またはServiceInterface
の一部にすることもできません。
私が思いついた唯一の解決策は、その上にApplication
アセンブリを配置することです。これには、3つすべて(Client
、ServiceInterface
、およびServiceImplementation
)への参照があり、 IService
をClient
に。何か不足していますか?
Mark SeemannのDependency Injectionに関する優れた本によると、アプリケーションのエントリポイントはコンポジションのルートである必要があります。ここでは、問題は依存関係の逆転に関するものであり、クライアントと実装の両方が抽象化に依存する必要があります。
その図には示されていませんが、本の他の部分で明らかになっていることは、エントリポイントが自然にそして必然的に参照することですすべて解像度のルート(コントローラー、サービス)を構築するために必要です、など)しかし、これはそのような知識を持っているのみ場所です。
クライアントが依存するインターフェースを「所有」しても問題ない場合があることに注意してください。インターフェースISecurityService
はControllers
アセンブリに存在する可能性があり、IUserRepository
は存在する可能性がありますServiceImplementations
アセンブリなどで。もちろん、1つを超えるクライアントがインターフェイスにアクセスする必要がある場合、これは実用的ではありません。
SOLIDに従うと、当然、依存性注入が必要になりますが、制御コンテナーの反転は優先度が低くなります。私は、純粋な依存性注入(解決ルートの手動構築)をますます頻繁に使用していることに気付きます。
その場合、Client
プロジェクトにはService
とServiceImplementation
の両方への参照を含める必要があります。これらの参照は、DIで使用されるIoCコンテナを作成するためにのみ使用されます。アプリケーションの起動時に、すべてのインターフェイス実装をIoCコンテナに登録する必要があります。
ServiceImplementation
インターフェースに対してService
を実装し、Client
インターフェースに基づいてService
をコーディングする場合、ServiceImplementation
への依存関係はありません。 。
「C#経由のアダプティブコード」のサンプルで、階段パターンがどのように実装されているかも確認できます。
https://github.com/garymcleanhall/AdaptiveCode/tree/master/Sprints/sample-sprint2-markdown
ServiceFactory
に入れます。いくつかのパラメータが必要です。ファクトリコンストラクタで渡されるか、ファクトリによって作成されるIService
実装を決定する構成などから取得されます。