2

我正在尝试为我的应用程序编写一种可扩展的数据层“存储库”之一是我的抽象存储类的内存实现

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”类型可以是字符串、整数、Guid 等……(大多数时候它可能是整数)

我的想法是创建类似这样的 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 加载到字典中......但它们都可以有不同的类型?

有没有更好的方法来解决这个问题?

另外,我知道我的问题的标题可能有点偏离 - 如果有人有更好的建议,请随时发表评论,我会改变它。

4

4 回答 4

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();
}
于 2010-07-15T22:23:51.300 回答
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在地图中等等......)

于 2010-07-15T22:22:00.183 回答
0

简短的回答:使用依赖注入,并让您的 DI 容器为您处理它。

于 2010-07-15T22:22:29.337 回答
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();
    }
}
于 2010-07-15T22:43:45.153 回答