web-dev-qa-db-ja.com

階段パターンの実装

「C#を介したアダプティブコード」の本で「階段」パターンの説明に遭遇しましたが、これがどのように実装されることになっているのか本当にわかりません。

Stairway patternソース

だから私はクライアントアセンブリを持っています:

_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の一部にすることはできません。ただし、ClientServiceImplementationにのみ依存する必要があるため、ClientまたはServiceInterfaceの一部にすることもできません。

私が思いついた唯一の解決策は、その上にApplicationアセンブリを配置することです。これには、3つすべて(ClientServiceInterface、およびServiceImplementation)への参照があり、 IServiceClientに。何か不足していますか?

28
d453

Mark SeemannのDependency Injectionに関する優れた本によると、アプリケーションのエントリポイントはコンポジションのルートである必要があります。ここでは、問題は依存関係の逆転に関するものであり、クライアントと実装の両方が抽象化に依存する必要があります。

その図には示されていませんが、本の他の部分で明らかになっていることは、エントリポイントが自然にそして必然的に参照することですすべて解像度のルート(コントローラー、サービス)を構築するために必要です、など)しかし、これはそのような知識を持っているのみ場所です。

クライアントが依存するインターフェースを「所有」しても問題ない場合があることに注意してください。インターフェースISecurityServiceControllersアセンブリに存在する可能性があり、IUserRepositoryは存在する可能性がありますServiceImplementationsアセンブリなどで。もちろん、1つを超えるクライアントがインターフェイスにアクセスする必要がある場合、これは実用的ではありません。

SOLIDに従うと、当然、依存性注入が必要になりますが、制御コンテナーの反転は優先度が低くなります。私は、純粋な依存性注入(解決ルートの手動構築)をますます頻繁に使用していることに気付きます。

19

その場合、ClientプロジェクトにはServiceServiceImplementationの両方への参照を含める必要があります。これらの参照は、DIで使用されるIoCコンテナを作成するためにのみ使用されます。アプリケーションの起動時に、すべてのインターフェイス実装をIoCコンテナに登録する必要があります。

ServiceImplementationインターフェースに対してServiceを実装し、Clientインターフェースに基づいてServiceをコーディングする場合、ServiceImplementationへの依存関係はありません。 。

「C#経由のアダプティブコード」のサンプルで、階段パターンがどのように実装されているかも確認できます。

https://github.com/garymcleanhall/AdaptiveCode/tree/master/Sprints/sample-sprint2-markdown

2
Krystian Kulig

ServiceFactoryに入れます。いくつかのパラメータが必要です。ファクトリコンストラクタで渡されるか、ファクトリによって作成されるIService実装を決定する構成などから取得されます。

1
Hintham