2013-09-10 12 views
16

私は現在のプロジェクトをよりメンテナンス可能にするために再設計しており、優れた設計方法に従うよう最善を尽くしています。現在、Silverlightコンポーネント、WCF RIAサービスと共有クラスライブラリを含むSLアプリケーション用のASP.Netホストを備えたソリューションがあり、SLとWCFサービスの両方がオブジェクトを共有できるようになっています。ビジネスロジックはあらゆる場所に分散しており、すべてのCRUD操作はWCFサービス内で手作業でコーディングされています。だから、私はあらゆるもののための新しい構造を作り出しており、この混乱を新しいフォーマットに移植します。これを行う過程で、私は私がいなければならないかわからないときにクラスを複製していることがわかります。ドメイン/エンティティ/ DTOオブジェクトの重複を減らすにはどうすればよいですか?

私の新しい構造は、次のようなレイアウトされている:

クライアント:
Reporting.Silverlight = Silverlightアプリケーション。これは私のDTOクラスを参照します。
Reporting.Web =自分のSLアプリケーションを保持しており、アクセスするための主要なエントリポイントです。

ビジネス: =私のWCFサービスはここに住んで
Reporting.Services。私のSLアプリはこれを呼び出すために何かを行い、これらのサービスはDTOクラスを返します。
Reporting.Services.Contracts =私のインターフェイスをWCFサービス用に保持し、DataContractデコレータを含むDTOクラスを保持します。
Reporting.Domain =保持し、私のドメインオブジェクトおよびビジネス・ロジック

データ:
Reporting.Data.Contract =仕事
のリポジトリ&単位Reporting.Dataのための私のインターフェイスを開催=リポジトリ/ UoWの具体的な実装。 Entity Framework 5コンテキストはここで定義されています。
Reporting.Data.Models =すべてのMy Entityオブジェクトを保持するため、EF5はSQLでそのことを実行できます。

私はほぼ同じクラスを持っている3つの場所を持っています。私にはそれがにおいします。内部Reporting.Services.Contracts私はSLクライアントに渡されるDTOを持っています。これは例として1つです:

[DataContract(Name = "ComputerDTO")] 
public class ComputerDTO 
{ 
    [DataMember(Name = "Hostname")] 
    public string Hostname { get; set; } 

    [DataMember(Name = "ServiceTag")] 
    public string ServiceTag { get; set; } 

    // ... lots more 
} 

私は上記のDTOはSLクライアントに渡されるプロパティの束であると思います。私のDTOプロパティの大部分はIDフィールドを除き、Entityオブジェクトの正当性1:1にマップされます。私はEF5とコードの最初のアプローチを使用しています

[Table("Inventory_Base")] 
public class ComputerEntity 
{ 
    // primary key 
    [Key] 
    public int AssetID { get; set; } 

    // foreign keys 
    public int? ClientID { get; set; } 

    // these props are fine without custom mapping 
    public string Hostname { get; set; } 
    public string ServiceTag { get; set; } 
    // ... plus a bunch more in addition to my navigation properties 
} 

:ここでは上記のDTOに対応する私のEntityオブジェクトです。私はまだ私の書き直しの最初の段階にあります。そして今まで私はビジネスロジックが私のEFエンティティの内部にあるべきではないという印象を持っています。 DTOにもビジネスロジックはありません。つまり、私のドメインモデルに入るのですよね?まあ、それはレポートで私の3番目のほとんど同じクラスを与えます。それは、3つのほぼ同じクラスは、おそらくこのことについてに行くための正しい方法ではないことができ持つドメイン

public class Computer 
{ 
    public string Hostname { get; set; } 
    public string ServiceTag { get; set; } 
    // ... lots more, pretty much mirrors the DTO 

    public string Method1(string param1) 
    { 
     // lots of methods and logic go in here 
    } 
} 

?私はすべてのビジネスロジックをEFエンティティの中に入れ、その結果をDTOに投影して電線に渡すべきでしょうか? EFエンティティクラス内のすべてのドメイン/ビジネスロジックを詰め込むことをお勧めします。構造的には、データベースに保存されているオブジェクトでも、アセンブリをビジネスレイヤとデータレイヤ外に移動する必要がありますか?理想的には、データプロジェクト内やビジネスプロジェクト外に含まれるEntity Frameworkへの参照を保持しようとしています。私は約200以上のクラスを持っています。私は移植していて、私のドメインを構成しています。そして、この再書き込みを済ませれば、この機能をさらに多くの機能に拡張することができます。このことをどのように構造化し、DRYを維持するかについての洞察は、非常に高く評価されます。

私が何をより良くしようとしているかを定義するのに役立つ場合は、私が従っているリポジトリ/ユニットワーク方法論を含めるべきかどうかを教えてください。

+0

可能重複(http://stackoverflow.com/questions/18109547/orm-entities-vs-domain- entity-under-entity-framework-6-0) –

+0

こんにちはGert - 私はそのリンクされた質問のあなたの答えが好きでした、そして、それは私のためにかなりクリアします。私が理解しているのは、Entityオブジェクトが同一で実用的なものであれば、ドメインオブジェクトとして使用することは大丈夫です。しかし、私の後のドメインクラスは、私のエンティティオブジェクトとは違って追加されることを期待しています。そのような状況では、DTO/Domain/Entity-for-my-ORMの間でクラスを進化させる必要がありますか? –

+0

DTO/Domain/Entityソリューションは、別個の懸念に対して特別な独自のモデルを構築することを目指しています。エンティティは、パーシスタンスインフラストラクチャがドメインの絞り込みモデルを構築するのを妨げる場合にのみ意味を持ちます。あなたのドメインがそれほど複雑でないなら、あなたはドメインモデルのためにエンティティを使うことができます。だからDTO。 – Hippoom

答えて

21

3つのほとんど同じクラスを持つことは、おそらく正しい方法ではありません これについては、行くことができますか?

IMO「3つのほとんど同一のクラス」ではなく、同じ目的を果たしません。それらは、特定の層のニーズに合わせて作られた、同じドメイン概念の多面的な側面です。

これは、モジュール性と懸念の明確な分離のために支払う価格です。より多くのポート(Hexagonal Architectureのポート&アダプターのように)が必要な場合、より多くのファセットが必要になり、より多くのマッピングが必要になります。

この上に良い記事:[Entity Frameworkの6.0の下でドメインエンティティ対ORMエンティティ]のhttp://blog.ploeh.dk/2012/02/09/IsLayeringWorththeMapping/

+0

これは良い読みです。これを階層化しておきたいのであれば、私は本当にDTOクラス、Domainクラス、Entityクラスを持つ必要があるということです。それらはすべて類似しているように見えますが、すべては異なるものに対して「責任がある」ものです。あなたが行う必要がある私の手のマッピングを減らすよいマッピングフレームワークのための推薦がありますか? –

+1

私はAutoMapper(https://github.com/AutoMapper/AutoMapper)のみを使用してくれました。 – guillaume31

関連する問題