2016-12-27 18 views
1

一般的なリポジトリパターンとユニットワークを実装しました。私は基本的なパターンを使いました。私は、すべてのテーブルに長い、本当に長いテキストを含むいくつかのフィールドがあり、ユーザーは能力を持っていなければならず、そのいずれかを選択して開く必要があると言う要件があります。異なった名前の各フィールドが反映された汎用オブジェクトを使用して、テーブル名とフィールド名を返すメソッドを作成し、それを返すことにしました。 方法は、一般的なリポジトリクラスで、私はこのようなルックスを書いて、適切にリフレクトを使用して基本クラスからメソッドを呼び出す

public interface IRepository<T> where T : class 
    { 
     //other methods 

     string GetPropertyByName(int id, string property); 
    } 

    public class Repository<T> : IRepository<T> where T : class 
    { 
     // other methods. add, edit, delete... 

     public string GetPropertyByName(int id, string property) 
     { 
      T model = this.Get(id);   
      var obj = model.GetType().GetProperty(property).GetValue(model, null); 
      return obj != null ? obj.ToString() : null; 
     } 
    } 

私は、ヘルプEFを持つテーブルのモデルクラスをcreted働くようです。いくつかのテーブルはジェネリックリポジトリに直接バインドしますが、他のテーブルは追加のメソッドを必要とするため、別のインタフェースとその実装を持っています。例:

public interface ICompanyRepo : IRepository<COMPANY> 
{ 
    //some methods 
} 

public class CompanyRepo : Repository<COMPANY>, ICompanyRepo 
{ 
    //implementations of interface methods 
} 

そして、UOWの実装:

public interface IUnitOfWork 
{ 
    ICompanyRepo Company { get; }   
    IRepository<CURRENCY> Currency { get; }   
} 

public class UnitOfWork : IUnitOfWork 
{ 
    static DBEntities _context; 
    private UZMEDEXPORTEntities context 
    { 
     get 
     { 
      if (_context == null) 
       _context = new DBEntities(); 
      return _context; 
     } 
    } 
    public UnitOfWork() 
    { 
     _context = context; 
     Company = new SP_CompanyRepo(); 
     Currency = new Repository<CURRENCY>(); 

    } 

    public ICompanyRepo Company { get; private set; } 
    public IRepository<CURRENCY> Currency { get; private set; } 
} 

私は、ビジネス層にGetPropertyByName()メソッドを呼び出すことで問題を抱えています。 System.Reflection.TargetExceptionを返し

public string GetHistory(string tableName, string fieldName, int id) 
    { 
     var prop = unitOfWork.GetType().GetProperty(tableName); 
     MethodInfo method; 
     method = prop.PropertyType.GetMethod("GetPropertyByName"); //try to find method 
     if(method == null) //if method not found search for interface which contains that method 
      method = prop.PropertyType.GetInterface("IRepository`1").GetMethod("GetPropertyByName"); 
     var res = method.Invoke(prop, new object[] { id, fieldName }); 
     return (string)res; 
    } 

: 私はこれを試してみました。私が理解しているように、この問題は単体実装である。私の呼び出しメソッドでは、 "prop"はインターフェイスのタイプ(ICompanyRepo)ですが、呼び出し対象はインターフェイス実装クラス(この場合は "CompanyRepo")でなければなりません。 実装クラスの種類を特定する方法を見つけることができず、この問題を解決できませんでした。任意のヘルプが割り当てられました

+1

サイドノート:「ジェネリックメソッド」はC#で非常に具体的な意味を持ちます - ポストに表示されているコードは一般的な方法を示していません - メソッド( 'Foo ()'のように)または代わりに他の単語を使用してください... –

+0

メソッドはジェネリッククラス、リポジトリの中にありますので、ジェネリックメソッドも同様にコールするのが正しいと思いました。 Anywatあなたは正しいですか、その部分を編集しました@AlexeiLevenkov –

+1

私は参照してください。投稿コードの[MCVE]ガイダンスをお読みください。 'TEntity'が特定の型(奇妙な命名規則を持つ)であるのか、ポストで提供されているコードに基づいてジェネリック型のパラメータであるのかを知る方法はありません。 –

答えて

0

私はこれが最良の選択肢であるとは確信していませんが、hereのToExpando()拡張機能を使用して解決しました。この拡張で、私はunitofworkのすべてのプロパティをスローし、その名前で必要なプロパティを見つけることができます。

var propValue = unitOfWork.ToExpando().Single(x => x.Key == prop.Name).Value; 
var res = method.Invoke(propValue, new object[] { id, fieldName }); 

今方法が適切に起動されます。クリーナーソリューションがあるかもしれませんが、私はまだこれを見つけることを願っています。今のところ私はこのソリューションを使用し、反射、ダイナミクス、ジェネリックについてよく読んで練習しなければならないことに気付きました。 PS重要なメモとアドバイスについてAlexeiに特別なお礼

関連する問題