2010-07-15 61 views
2

我想爲我的應用程序編寫一種可擴展的數據層其中一個「倉庫」是我的抽象商店類的內存中實現C#泛型和抽象工廠模式 - 或者某種類似的方式

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」 的,看起來像這樣:

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(); 
    } 
} 
0123現在

的類型,「U」這裏可能是字符串,整數,的Guid等... (大部分時間它可能是int)

我在這裏的想法是像這樣的一個IUIDGenerator創造的東西:

public interface IUIDGenerator<T> 
{ 
    T Create(ICollection<T> collection); 
} 

在上述「InMemoryStore」我會然後創建一個IUIDGenerator的一個實例,通過在商店dictionarys密鑰集合,並調用「創建」方法返回所需類型的唯一標識符。

例如,我可以有一個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所需的具體實現 - 我該如何做到這一點?

我想過有一種類工廠模式 - 將所有可用的UIDGenerator加載到字典中......但它們都可以有不同的類型?

有沒有更好的解決方法呢?

此外,我知道我的問題的標題可能有點偏離 - 如果任何人有更好的建議,請隨時發表評論,我會改變它。

回答

2

您可以使用IoC框架,如Unity,Castle,Ninject等。然後,你會用類似下面的配置容器:

_container = new UnityContainer(); 
_container.RegisterType<IUIDGenerator<int>, IntUIDGenerator); 
_container.RegisterType<IUIDGenerator<Guid>, GuidUIDGenerator); 

然後在你的類,你已經有類似以下內容:

public override U GetUniqueIdentifier() 
{ 
    var generator = _container.Resolve<IUIDGenerator<U>>(); 
    return generator.Create(); 
} 
0

我認爲你必須至少使用一次演員。如果您儲存所有的發電機在地圖上像

Map<Type, object> generators; 

可以使用

class InMemoryStore<T,U> { 
    public override U GetUniqueIdentifier() { 
    var generator = generators[typeof(U)] as IUIDGenerator<U>; 
    return generator.Create(collection); 
    } 
} 

當然,我省略了所有種類的驗證代碼:)(如檢查,如果U類型發電機在地圖等...)

0

你可以對添加額外的泛型類型參數發電機,例如

public class InMemoryStore<T, U, V> : Store<T, U> 
    where T : StorableEntity<U> 
    where V : IUIDGenerator<U>, new() { 

    public override U GetUniqueIdentifier() 
    { 
     return (V)(Activator.CreateInstance<V>()).Create(); 
    } 
}