6

次のインターフェースと実装があります。

public interface IRepository<T>
{
    IList<T> GetAll();
}

internal class TrendDataRepository : IRepository<TrendData>
{
    public IList<TrendData> GetAll()
    {
        //.. returns some specific data via Entity framework
    }
}

Entity Framework によってすべて異なるデータを返す複数の実装を用意する予定です。ある時点で、IRepository インターフェイスを実装するクラスのリストをユーザーに表示したいと考えています。私は次のコードでこれを行います。これは私にとってとてもうまくいきます。

    public static IEnumerable<string> GetAvailableRepositoryClasses()
    {
        var repositories = from t in Assembly.GetExecutingAssembly().GetTypes()
                           where t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof (IRepository<>))
                           select t.Name;

        return repositories;
    }

ただし、指定された特定の文字列が具体的なリポジトリ タイプを返し、その上で「GetAll」メソッドを呼び出せるようにするファクトリ メソッドも作成したいと考えています。擬似コード:

someObject = Factory.CreateInstance("TrendData");
someObject.GetAll();

(ファクトリ メソッドで具象型を指定する必要があるため、これが機能しないことはわかっています)。

ユーザーがレポートを特定のデータソースにバインドできるようにしたいので、この機能が必要です。このようにして、レポートのデータソースが (たとえば) TrendDataRepository.GetAll() メソッドにバインドされている新しいレポートを開始できます。

しかし、おそらく世界の終わりが近づいているためです ;-) または、金曜日の午後で、もうはっきりと考えることができないため、これを実現する方法がわかりません.

いくつかの指針は本当に歓迎されます。

4

1 に答える 1

2

名前の代わりにリポジトリ タイプのコレクションを返し、名前を UI に表示することをお勧めします。

public static IEnumerable<Type> GetAvailableRepositoryClasses()
{
    return Assembly.GetExecutingAssembly().GetTypes()
        .Where(t => t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof (IRepository<>)));
}

次に、ユーザーがソースを選択すると、次のことができます。

object repository = Activator.CreateInstance(selectedType);

この方法では、各リポジトリにデフォルトのコンストラクタが必要です。

Activator.CreateInstanceオブジェクトを返しますが、期待してIRepository<T>いるジェネリック型がわからない限り、それをインターフェイスにキャストすることはできません。おそらく最善の解決策は、リポジトリ クラスも実装Tする非ジェネリック インターフェイスを作成することです。IRepository

public interface IRepository
{
    IList<object> GetAll();
}

これで、作成したリポジトリを次の場所にキャストできますIRepository:

IRepository repository = (IRepository)Activator.CreateInstance(selectedType);

両方を実装するリポジトリ基本クラスを作成する場合があります。

public abstract class RepositoryBase<T> : IRepository<T>, IRepository
{
    public abstract IList<T> GetAll();
    IList<object> IRepository.GetAll()
    {
        return this.GetAll().Cast<object>().ToList();
    }
}
于 2012-12-21T13:59:13.033 に答える