2012-04-20 13 views
2

私は呼び出し元クラスのジェネリック型に基づいて2つのデータメソッドの1つを呼び出す必要があるアプリケーションに取り組んでいます。例えば、Tがタイプfooのであれば、私はdata.GetFoo()を呼び出します:タイプに基づいてDALメソッドを呼び出す

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime) 
{ 
    using (MesReportingDal data = new MesReportingDal()) 
    { 
     return data.GetFoo(mostRecentProcessedReadTime); // Notice GetFoo() 
    } 
} 

を、Tはタイプのバーであれば、私はdata.GetBar()を呼び出します:

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime) 
{ 
    using (MesReportingDal data = new MesReportingDal()) 
    { 
     return data.GetBar(mostRecentProcessedReadTime); // Notice GetBar() 
    } 
} 

これまでは、すべてのタイプが同じ方法で取得されたため、私は1つのDALメソッドしか必要としませんでした。

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime) 
{ 
    using (MesReportingDal data = new MesReportingDal()) 
    { 
     if (T is Foo) { return data.GetFoo(mostRecentProcessedReadTime); } 
     if (T is Bar) { return data.GetBar(mostRecentProcessedReadTime); } 
    } 
} 

これは、OCPに違反:私は今、私はこのような何かを避けるためにしようとしているT.

の種類に応じて、2つの方法のいずれかを呼び出す必要があります。これを処理するためのエレガントな方法があるので、私はif文を取り除くことができますか?

編集 - これはタイプが

public partial class Foo1 : IDataEntity { } 
public partial class Foo2 : IDataEntity { } 
public partial class Bar1 : IDataEntity { } 
public partial class Bar2 : IDataEntity { } 

のように見えるものですこれらのFOOSやバーがLINQのツーSQLで使用DBMLアイテムです。

+0

あなたは 'T'クラスのコントロールを持っていますか?それらは変更できますか?ベースインターフェイス/クラスなどありますか? – NSGaga

+0

私の編集を参照してください。それは役に立ちますか? –

+0

Foo *、Bar *を変更したくない場合、GetFoo、GetBarでなければなりません - ataddeiniが提案したようにGet()はできません。どのようにGetObjectList()を呼び出すつもりですか?あなたは例えばFoo、コール前のバー(たとえば、型付き変数) - またはこれをいくつかの非常に一般的な方法で呼び出す(別の汎用メソッドからTを使用する)あなたができるなら、ataddeiniが言ったことが最も簡単です。 – NSGaga

答えて

3

私はGetFooGetBarをちょうどGetに変更し、MesReportingDalも一般的にします。

だから私はあなたがこのようなものに終わるだろうと思う:

private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime) 
{ 
    using (var data = new MesReportingDal<T>()) 
    { 
     return data.Get(mostRecentProcessedReadTime);   
    } 
} 

ところで、using声明を持つことも、そうでない場合は次のようなコンパイルエラーが発生します、MesReportingDalIDisposableを実装している必要があります。

'MesReportingDal':usingステートメントで使用される型は、 'System.IDisposable'に暗黙的に変換可能である必要があります。

UPDATE

これをもう少し考えて、あなたのフィードバックを読んだ後で、リポジトリインタフェースを抽出して、ファクトリメソッドに戻すことができます。これにより、1つのdata.Get(...)コールを維持することができますが、T

public interface IRepository<T> : IDisposable 
{ 
    IList<T> Get(DateTime mostRecentRead); 
} 

public class FooRepo : IRepository<Foo> 
{ 
    public IList<Foo> Get(DateTime mostRecentRead) 
    { 
     // Foo Implementation 
    } 
} 

public class BarRepo : IRepository<Bar> 
{ 
    public IList<Bar> Get(DateTime mostRecentRead) 
    { 
     // Bar Implemenation 
    } 
} 

に基づいて、異なる実装であなたの工場は、この

public class RepositoryFactory 
{ 
    public static IRepository<T> CreateRepository<T>() 
    { 
     IRepository<T> repo = null; 
     Type forType = typeof(T); 

     if (forType == typeof(Foo)) 
     { 
      repo = new FooRepo() as IRepository<T>; 
     } 
     else if (forType == typeof(Bar)) 
     { 
      repo = new BarRepo() as IRepository<T>; 
     } 

     return repo; 
    } 
} 

のようになります。これは、あなたの最初のコードを維持できるようになりますブロッククリーン

private static IList<T> GetObjectList(DateTime mostRecentProcessedReadTime) 
{ 
    using (var data = RepositoryFactory.CreateRepository<T>()) 
    { 
     return data.Get(mostRecentProcessedReadTime); 
    } 
} 

希望に役立ちます。

+0

これはうまくいくかどうかわかりませんが、それは私があまり明確でなかったためかもしれません。 data.Get()メソッドは、型に基づいて実装が異なります。 Get()内のアルゴリズムは異なります。 –

+0

@BobHornはい、ありがとうございます。これについてもっと考えてみると、私はリポジトリインターフェースと工場に戻ってきています。私はまもなく例を使って更新しようとします。 – ataddeini

+0

ありがとうございます。これはifロジックをどこか他のものにプッシュしますが、消費コードをきれいに保ちます。私はロジックを完全には避けることを望んでいましたが、この解決法は少なくとも工場内に保持しています。私は私の唯一の他の選択肢は反射だと思うが、これは今のところ働くことができる。 –