0

C#/ ASP.NETを使用してモデルタイプをリポジトリタイプにマップすることが可能かどうか疑問に思っていました。ご覧のとおり、私はリポジトリ/作業単位のパターンを実装しようとしています。ASP.NETマップのモデルタイプがリポジトリタイプに対応していますか?

public class UnitOfWork : IDisposable 
{ 
    private SchoolContext context = new SchoolContext(); 
    private DepartmentRepository departmentRepository; 
    private CourseRepository courseRepository; 

    public DepartmentRepository DepartmentRepository 
    { 
     get 
     { 

      if (this.departmentRepository == null) 
      { 
       this.departmentRepository = new DepartmentRepository(context); 
      } 
      return departmentRepository; 
     } 
    } 

    public CourseRepository CourseRepository 
    { 
     get 
     { 

      if (this.courseRepository == null) 
      { 
       this.courseRepository = new CourseRepository(context); 
      } 
      return courseRepository; 
     } 
    } 

しかし、UnitOfWorkは各リポジトリタイプのプロパティの長いリストを保持する必要がありますが、問題があります。この例では、対応する2つのリポジトリ(分割リポジトリとコースリポジトリ)を持つエンティティタイプが2つ(部門、コース)しかないため、それほど悪くはありません。しかし、アプリケーションのサイズが大きくなると、UnitOfWorkクラスはすばやく大きくなり、数十、または数百のプロパティが混乱します。これは神クラス以外のものではありません。

私が望むのは、モデルタイプをリポジトリオブジェクトにマップするジェネリックメソッドGetRepository()など、より一般的なものです。以下の疑似コードは、私が望むものを示しています。

// definition 
public TRepository GetRepository<TModel>(){ // pending implementation } 

// use-case 
var departmentRepository = UnitOfWork.GetRepository<TModel>(); 

したがって、モデルタイプをリポジトリオブジェクトにマップするコードを書くことはできますか? AutoMapperは、ジェネリック型ではなく、具体的な実装間でのマッピングにすぎないので、うまくいきません。どう思いますか?作業単位のプロパティとして、リポジトリの実装ごとにハードコードするのではない場合に、この問題にどのようにアプローチしますか?

+1

UnitOfWorkからリポジトリを削除します。リポジトリにUoWを挿入し、コンテキストからエンティティセットを取得します。 – Jasen

+1

依存性注入と制御の逆転のための仕事のように見えます。あなたはIOCブートストラップのモデルとそれに対応するリポジトリの関連付けを登録します... – Theo

+0

これを解決するためにあなた自身のマッパーを書くことができます –

答えて

0

あなたは、このように拡張メソッドを定義することができます。

public static class Mapper 
{ 
    public static T Map<T>(Object source) where T : class 
    { 
     var instance = Activator.CreateInstance<T>(); 

     foreach (var property in typeof(T).GetProperties()) 
     { 
      if (property.CanRead) 
      { 
       var sourceProperty = source.GetType().GetProperty(property.Name); 

       if (sourceProperty == null) 
       { 
        continue; 
       } 

       var value = sourceProperty.GetValue(source); 

       property.SetValue(instance, value); 
      } 
     } 

     return instance; 
    } 
} 

あなたは別の1つのクラスをマッピングする場合:

var foo = Mapper.Map<CustomerViewModel>(new Customer { CustomerID = "ACME", CompanyName = "Acme Corp.", ContactName = "Jhon Doe" }); 

出力:

{CustomerViewModel} 会社名: " Acme Corp. " 得意先:辞書<(

また
public class Customer 
{ 
    public String CustomerID { get; set; } 

    public String CompanyName { get; set; } 

    public String ContactName { get; set; } 
} 

public class CustomerViewModel 
{ 
    public String CustomerID { get; set; } 

    public String CompanyName { get; set; } 
} 

が、これはあなたが動的オブジェクト(ExpandoObject)、辞書からのマッピングのために、この拡張メソッドを向上させることができます基本的な考え方です:「ACME」

あなたは以下のクラスを持っていると仮定すると、 String、Object >)、コレクションのマッピング(アイテムの大きなコレクション)のパフォーマンスを向上させるためのマッピングテーブルを作成します。

このメソッドは、匿名オブジェクトもサポートしています。

この回答が有用である場合は、ご要望に応じてアルゴリズムを改善してください。

+0

ドメインモデルをビューモデルにマップする方法を知っています。ただautomapperを使うだけです。私が持っている質問は、無関係なプロパティ/コンポジションを持つ2つのオブジェクトをどのようにマッピングするかですが、同様の命名規則を使用してマッピングする方法です。私は 'UserModel'と呼ばれるドメインモデルがあり、そのリポジトリは 'UserRepository'と呼ばれ、UserModelをUserRepositoryにマッピングしたいとします。どうすればこれを達成できますか? –

+0

この場合、クラス名はプロパティ名とは関係ありません。ラムダ式をサポートするためにこのコードを修正しようとしましたか?多分あなたの質問で何かが恋しくなり、別の名前でプロパティをマップしたいのです –

関連する問題