2012-01-18 12 views
2

私は解決するのが非常に難しいアーキテクチャの決定に直面しています。長い記事の前に申し訳なく思っていますが、私に手伝っていただく前に、文脈を伝えなければなりません。POCOの設計と新しいアーキテクチャのためのLazyの使用に関する助言が必要です

私の会社は、既存のASP.NETレガシーコードに新しいアーキテクチャ(ASP.NET MVCフレームワークに基づく)を統合しようとしています。ヒントは、従来のアセンブリでカプセル化されているすべてのビジネスコードを取り除くことができないということですが、一種の「アンチクラッシュ」レイヤーを作成し、それを切り離すために新しいコードにラップする必要があります。彼らはのために永続性を認識したモデルの種類を使用し、従来のASP.NET Webサイトで

  1. :私たちは、今までもいいですが、ここではデカップリングビットのトリッカーを作るつの制約(メイン)を来りますビューからの遅延読み込みを有効にします(私はそれがうんざりです)。それには理由があります。コードは非常に混乱しており、展開が難しいため、バイナリを配備せずにビューのみを変更できるようにしたいと考えていました。必要に応じて遅延ロードされるプロパティで、Godクラスがビューにプッシュされます。たとえば、デザイナーが別のプロパティを表示するためにビューを変更したい場合、彼はGodクラスから望みのものを選ぶだけで、うまく動作します。 新しいMVCアーキテクチャで同じ動作を保つ必要があります。

例を挙げておきます。我々はItemレガシー永続性を意識DTOを持っているとしましょう:

public class Item 
{ 
    public string Title {get; set; } 
    public List<UserComment> Comments {get; set; } // lazy loaded in the background in legacy code. 
} 

ので、設計者はビューで使用するItem.Titleを呼び出して展開し、彼は(foreachの中に)Item.Commentsを望んでいる場合は追加することができた後、ちょうどビューを展開することができますすべてのバイナリをデプロイする必要はありません。

次のアーキテクチャが提案されています。 mvc Webサイトの新しいPOCOは、他のアセンブリを参照していないDomain assebmlyにあります。このアセンブリでは、IItemRepositoryのようなリポジトリインタフェースの定義もあります。エンティティはASP.NET MVC ViewModelで直接使用され、基になるDIコンテナによって配線されたリポジトリの実装を通じて取得されます。

私たちはIRepositoriesの実装が生きる別のasseblyを持っています。そのアセンブリは、ドメインからエンティティを移入するために使用されるすべてのレガシーコードを参照します。

これまではすべてが素晴らしいです。しかし、ここでは難しい部分があります。ドメインアセンブリのエンティティは、ポイント1(ビューの遅延負荷)からの制約に準拠する必要があります。

私たちのPOCOはすべてのプロパティをLazy <>と宣言します。これにより、実装アセンブリ(すべてのレガシーコードを参照するアセンブリ)で、アクセス時にこれらのプロパティにデータを代入するデリゲートを定義できます。ここではMVCのためのPOCOSの新しい実装です:

public class Item 
    { 
     public string Title {get; set; } 
     public Lazy<List<UserComment>> Comments {get; set; } // lazy loaded in the background in legacy code. 
    } 

は、そしてここItemRepository実装です:

public class ItemRepository : IItemRepository 
{ 
    public Item GetItem(int id) 
    { 
     Item i = new Item() { Id = id }; 
     i.Comments = new System.Lazy<IEnumerable<UserComments>>(() => CommentsService.GetUserComments(id)); 

     return i; 
    } 
} 

我々は非常にそれを好きではない、とここに理由です:

  • POCOSエンティティに生涯管理の漏れの抽象があるように見えるので、実際にはPOCOではありません。 Lazy <>がタイプであるため、これは大きな問題ではありません。ネットフレームワーク。一方、NHibernateのようなORMを使用している場合は、NHibernateがデータ(セクショナルコンストラクタ、仮想メンバなど)をロードできるようにするためにPOCOを曲げる必要があります
  • 私たちが気に入らない理由これは、リポジトリの実装で基本的なサービス構成を隠すことです。 Item.Commentsが使用されている場合たとえば、ItemRepositoryの基礎となる実装に我々は(その場合にはCommentsService.GetUserComments(ID))、別の従来のサービスに呼び出す

質問1:あなたが使用して他の欠点を参照していますLazy <> POCO実装では?それとも設計上考慮しなければならない他の欠陥?

質問2:はどのように我々は レガシーサービスが使用されているの明確な「ビジョン」を持つために、リポジトリの実装では、従来のサービス構成を避けることができますか?さらに、実装レベルでこの「ビジョン」 が本当に必要なのですか?レガシーサービスのファサードとして の実装をリポジトリとみなすことができますか?

質問3:制約1(遅延ロード)に関して他の選択肢はありますか?

質問4:遅延メンバーの構成に関するガイドラインはありますか?

長い質問で申し訳ありませんが、本当にあなたの助けに感謝します。

トーマス

+1

私は専門的に意見を述べる資格があると感じていますが、私が個人的に感じることは実際にはそうではありません。なぜなら問題は明らかに複雑なやり方で十分に十分です。 私はアドバイスを断ることができます:非常に現実的な方法で、あなたはある種の災害の回復を工夫していますし、急性のケアのように、物事を作ろうとしない最善の方法で傷を修正する必要がありますあまりにも悪い。 – ZeroBugBounce

+0

基本的には、バイナリを配備する必要がないデザイナーのために、n層のアプリケーションの折りたたみを単一のレイヤーにハードワイヤリングしていると伝えていますか?申し訳ありませんが、これは実際にあなたの問題を解決するわけではありませんが、私はちょうど質問するのを助けることができませんでした: – guillaume31

+0

@ZeroBugBounce:それはポイントです、それはレガシーコードからかなり分離しました。 –

答えて

2

が遅延ロードの特性は、List<T>でなければなりませんか? 、今

public class Item 
{ 
    public string Title {get; set; } 
    public IList<UserComment> Comments {get; set; } 
} 

プロパティは、インタフェースのインスタンスであることから、あなたはそれのうち、仮想プロキシを作成することができます。そうでない場合、あなたはこのように、IList<T>またはICollection<T>としてそれらを定義することができます。

+0

良いアドバイス他の制約がポップアップしないかどうかチェックします。 –

+0

マーク、それは私が取ったアプローチです(これについてはhttp://blog.ploeh.dk/2011/03/04/ComposeObjectGraphsWithConfidence.aspxを参照してください)。私はそれが仮想プロキシと呼ばれていたのか分からなかった。 –

関連する問題