アプリケーション用に一種の拡張可能なデータ レイヤーを作成しようとしています。「リポジトリ」の 1 つは、抽象ストア クラスのインメモリ実装です。
public abstract class Store<TEntity, TIdentifier> : IStore<TEntity, TIdentifier>
where TEntity : StorableEntity<TIdentifier>
{
//abstract methods here
public abstract TIdentifier GetUniqueIdentifier();
}
「StorableEntity」抽象クラスは次のとおりです。
public abstract class StorableEntity<TIdentifier>
{
public TIdentifier ID { get; set; }
}
次のような「InMemoryStore」と呼ばれる Store の具体的なクラスがあります。
public class InMemoryStore<T, U> : Store<T, U>
where T : StorableEntity<U>
{
protected static Dictionary<U, T> store = new Dictionary<U, T>();
public override U GetUniqueIdentifier()
{
// call relevant "generator" here - SOMETHING LIKE THIS??
// var generator = GetGeneratorSomehow(U);
// return generator.Create();
}
}
さて、ここでの「U」の型は、string、int、Guid などの可能性があります... (ほとんどの場合、int である可能性があります)
ここでの私の考えは、次のような IUIDGenerator のようなものを作成することです:
public interface IUIDGenerator<T>
{
T Create(ICollection<T> collection);
}
上記の「InMemoryStore」では、IUIDGenerator のインスタンスを作成し、ストア ディクショナリのキー コレクションを渡し、「Create」メソッドを呼び出して、必要な型の一意の識別子を返します。
たとえば、このような IntUIDGenerator クラスを持つことができます (これは、辞書キーに既に含まれている数値に基づいて、一種の増分数値ジェネレーターとして機能します)
public class IntUIDGenerator : IUIDGenerator<int>
{
public int Create(ICollection<int> collection)
{
var result = collection.Max() + 1;
if (collection.Contains(result))
return result;
throw new NotUniqueException();
}
}
実際の質問: 私がしなければならないことは、InMemoryStore 内で、U の型 (識別子の型) を識別し、必要な IUIDGenerator の具体的な実装を動的に選択できるようにすることです - どうすればこれを行うことができますか?
クラス ファクトリ パターンのタイプを持つことを考えました - 利用可能なすべての UIDGenerators を辞書にロードします...しかし、それらはすべて異なるタイプを持つことができますか?
これを回避するより良い方法はありますか?
また、質問のタイトルが少しずれている可能性があることも認識しています。より良い提案があれば、お気軽にコメントしてください。変更します。