2011-09-28 12 views
1

私は開発中のアプリケーションをモジュラーアプリケーションの設計に従っています。認証/承認、ロギング、データアクセスなどの共通の中央サービスを提供する「コア」垂直スタックがあります。コンテキスト固有の領域は、同じ論理層のコアアセンブリを参照するモジュールで実装されます。モジュラーアプリケーションアーキテクチャでのタイプの共有

アプリケーションは、ファサードレイヤ、ドメインレイヤ、およびデータアクセスコードを含むインフラストラクチャコードを持つサービスアプリです。各モジュールはドメイン層アセンブリを実装します。モジュールにパブリックAPIがある場合は、ファサードアセンブリも実装されます。例えば

、解決策は含まれています

  • Core.Api - ファサードのアセンブリコアAPIのための
  • コア - コアサービスのドメインアセンブリ、エンティティなど
  • Core.Dataを - コアデータアクセスアセンブリ
     
  • ModuleA.Api - ファサードアセンブリモジュールAの(参照Core.Api)
  • ModuleA - モジュールA(参照コア)のドメインアセンブリ
     
  • ModuleB.Api - モジュールB(参照コア)のドメインアセンブリ
  • enter image description here

    (など - モジュールB(参照Core.Api)

  • ModuleBためのファサードのアセンブリ。私たちは約24個のモジュールを持っています)。

    これは、IoCコンテナとしてのUnityを持つDIを使用して結合されています。 WebHostプロジェクトでは、さまざまな実装が完全に埋め込まれたインターフェイスにマッピングされる構成が定義されています。

    このアプローチは単なる論理的な目的ではなく、実装の柔軟性を可能にする(つまり、他のコードを壊すことなく、または他のコードに触れることなくモジュールの実装を変更することができます)。また、チーム間で作業を分割し、他のコードの回帰エラーのリスクがほとんどない新しいモジュールでアプリケーションを拡張することも非常に簡単です。

    ModuleBにModuleAで定義されている1つ以上のタイプが必要な場合、私の質問は何ですか? ModuleBがModuleAを参照することは許容されますか、またはModuleAをCoreに移動する必要がありますか?私はこの明確に私をリードガッチャに走って以下に説明変更の一部を実装を見て

    UPDATE

    ...

    私のモジュールは相互依存している2つの場所があります。 。以下で説明するアプローチに従って、私が共有したいインターフェイスとタイプをModule1からCoreに移動できます。これにより、ModuleBはModuleAとModuleBを緊密に結合することなく使用できます。ただし、ModuleB.Apiのサービス操作でModuleA.Apiで定義されたデータコントラクトの一部を使用する必要もあります。これは私にデザインに疑問を投げかけます。

    IPのため、正確な使用例は記述できませんが、ModuleAにはEntityAドメインオブジェクトがあるといっても過言ではありません。 ModuleA.ApiはパブリックAPIによって公開されるEntityContractAデータコントラクト(DTO)を定義します。 ModuleB。Apiには、パラメータとしてEntityContractAを必要とするメソッドがあり、次に、パラメータとしてEntityAを受け付けるModuleBのメソッドに委譲します。

    この場合も、EntityAをコアに移動すると、ドメインレイヤの問題は解決されますが、ファサードレイヤでは役に立ちません。 EntityContractAをCore.Apiに移動すると、全体的なにおいがしやすくなります。

    ここで私は達成するために必要なものの例です:

    をModuleB.Api.ServiceFacadeBで:

    のDomainServiceがModuleA.ServiceBある
    public EntityContractB FilterBy(EntityContractA contractA) 
    { 
        var entityA = Mapper.Map<EntityContractA, EntityA>(contractA); 
    
        var entityB = domainService.FilterBy(entityA); 
    
        var contractB = Mapper.Map<EntityB, EntityContractB>(entityB); 
    
        return contractB; 
    } 
    

    public EntityB FilterBy(EntityA entityA) 
    { 
        // Do work 
    } 
    
  • 答えて

    0

    良いニュース:実際には、懸念とモジュール性のパターンが明確に分離された良好なアーキテクチャです。これにより、チームは互いに独立したモジュールを開発でき、それぞれのインターフェイス(ファサード/ API)にのみ依存します。これはベストプラクティスです!

    (潜在的な)悪いニュース:Module2からModule1を直接参照することから始めれば、この美しいアーキテクチャを単独で破ることになります。モジュール1を作成したチームは、インターフェイスを安定に保つことだけを気にする必要がありましたが、直接参照のために、実装の変更に注意する必要があります。

    私の提案:Module1で定義されているタイプのModule2が必要な場合は、それをCore APIまたはModule1 APIクラスに移動してください。これは、あなたのアセンブリがそれらのタイプに依存しており、安定している必要があることを明確にしているという事実を正式化します。

    +0

    どうやってそれらをコアに移動することになりますか?あなたが使用するインタフェースとタイプだけを定義し、実装をモジュールのままにしますか? – SonOfPirate

    +0

    私は(現実的ではないが)現在のアーキテクチャでは、実装が概念的にはインタフェースと同じ名前空間に実装されている必要があると思います。つまり、Module1からCoreに完全に移動する必要があります。 – kroonwijk

    +0

    IoCコンテナを使用する場合、このような制約はないと思います。私はすでにインターフェイスを実装している私のすべての「サービス」を持っています。もっと考えると、「契約」(インターフェイス)とサポートタイプをコアに置き、実装を別のモジュールに残すほうが意味があります。これにより、両方のモジュールがCoreを参照するだけで済みますが、実装でモジュール性の利点を得ることができます。 – SonOfPirate

    0

    モジュール2は、基準を持っている必要がありますModule1のモジュール間の相互依存性は、共通のコアコードに部品を移動させるケースを作りません。

    +0

    私が読んだガイドラインは、そうでなければ私がそうすることをためらいました。 Kroonwijkは、Module1が直接参照する他のモジュールに及ぼす影響についての良い点を示しています。インターフェイスとサポートするタイプをコアに移動することで、他のモジュールがコードを使用できるようにしますが、実装を切り離したままにしておくことで、変更には再コンパイルやデプロイメントなどを必要としません。 – SonOfPirate

    +0

    あなたのアプリに関する情報やここで検討しているモジュールを説明することができます。私はあなたのアプリケーションを理解したいと思います。なぜなら、これらのデザインの決定は、ほとんどの場合、アプリケーションの使用事例に従うからです。 – sudmong

    +0

    私はIPのために私が持っているよりもはるかに詳細に入ることができるかわかりません。あなたが知りたいと思うことは何ですか? – SonOfPirate

    0

    ModuleBがModuleAを参照できるかどうか、または ModuleAをコアに移動する必要がありますか?

    いいえ、私は特定のモジュールと結びついていないどこかで共有タイプを再定義します。これらの共有型を定義する場所に依存関係がないことを確認してください。

    [警告、自己プロモーション:]世界の視界は5-Layer Architectureで、「共通」のレイヤーになります。

    +0

    私はリンクを感謝し、私はより多くの時間がある場合、それをより完全に読む必要があります。興味深いアサーションがありますが、OOは行動に基づいたモデリングを提案している(つまりPOCOはありません)一方で、データ中心のアプローチを多く取っているようです。しかし、ここで違いがあるかどうかはわかりません。私は抽象クラス(インターフェイス)とサポートタイプを自分のコアライブラリ(あなたの用語に従った共通レイヤ)に移動することに傾いています。私の唯一の恐怖は、私がこれがモジュラーアーキテクチャの目的を打ち負かすような横行にならないようにすることではないということです。 – SonOfPirate