I am trying to write a sort of extendable data layer for my application One of the "repositories" is an in-memory implementation of my abstract store class
public abstract class Store<TEntity, TIdentifier> : IStore<TEntity, TIdentifier>
where TEntity : StorableEntity<TIdentifier>
{
//abstract methods here
public abstract TIdentifier GetUniqueIdentifier();
}
The "StorableEntity" abstract class is:
public abstract class StorableEntity<TIdentifier>
{
public TIdentifier ID { get; set; }
}
I have a concrete class of Store called "InMemoryStore" that looks like this:
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();
}
}
Now, the type of "U" here could be string, int, Guid etc... (most of the time it could be int)
My idea here is to create something like an IUIDGenerator like this:
public interface IUIDGenerator<T>
{
T Create(ICollection<T> collection);
}
In the above "InMemoryStore" i would then create an instance of an IUIDGenerator, pass in the store dictionarys key collection, and call the "Create" method to return a unique identifier of the required type.
For example, i could have an IntUIDGenerator class like this (that would act as a kind of incremental number generator, based on the numbers already in the dictionary keys)
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();
}
}
Actual Question: What I need to do, is within InMemoryStore, identify the type of U (the type of the identifier) and be able to dynamically select the required concrete implementation of IUIDGenerator - how can i do this?
I thought about having a type of class factory pattern - loading all the available UIDGenerators into a dictionary... but they can all have different types?
Is there a better way around this?
Also, I am aware the title of my question may be a bit off - if anyone has a better suggestion, please feel free to comment and I'll change it.