我们在 C# 中有一个抽象泛型类,非常像这样:
public abstract class Repository<T>
where T: Entity
{
public abstract void Create(T t);
public abstract T Retrieve(Id id);
//etc.
}
我们有一些派生类,例如:
public class EventRepository
: Repository<Event>
{
//etc.
}
我们正在实现一个工作单元模式,该模式保留一个字典来将实体类型映射到存储库类型,以便当需要创建或更改实体时,它知道要实例化哪个存储库:
private Dictionary<Type, Type> m_dicMapper;
该字典已初始化并加载所有映射,如下所示:
m_dicMapper.Add(typeof(Event), typeof(EventRepository));
//and so on for a few other repository classes.
然后,当一个实体 e
需要创建,例如:
//retrieve the repository type for the correct entity type.
Type tyRepo = m_dicMapper[e.GetType()];
//instantiate a repository of that type.
repo = Activator.CreateInstance(tyRepo);
//and now create the entity in persistence.
repo.Create(e);
问题是,repo
是什么类型在上面的代码中?我想将其声明为通用 Repository<T>
type,但显然 C# 不允许我这样做。以下行均无法编译:
Repository repo;
Repository<T> repo;
Repository<e.GetType()> repo;
我可以将其声明为 var
,但是我无法访问 Create
和其他方法 Repository<T>
实现。我希望能够使用通用类来通用地使用存储库!但我想我做错了什么。
所以我的问题是,我可以使用哪些编码和/或设计的解决方法来解决这个问题?谢谢。
最佳答案
我个人建议使用单独的单例类封装对字典的访问,然后包装字典的 getter 和 setter,例如 RepositoryStore
类。
我建议更改Dictionary<Type, Type>
至Dictionary<Type, object>
,然后在 RepositoryStore
内处理转换;像这样吗?
更新(使用 Type
和 Lazy<T>
)
如果您使用 .NET 4,您可以充分利用 Lazy
class,并将字典类型更改为 IDictionary<Type, Lazy<object>>
。我修改了原来的答案以反射(reflect)它的工作原理:
class RepositoryStore
{
private IDictionary<Type, Lazy<object>> Repositories { get; set; }
public RepositoryStore()
{
this.Repositories = new Dictionary<Type, Lazy<object>>();
}
public RepositoryStore Add<T, TRepo>() where TRepo : Repository<T>
{
this.Repositories[typeof(T)] = new Lazy<object>(() => Activator.CreateInstance(typeof(TRepo)));
return this;
}
public Repository<T> GetRepository<T>()
{
if (this.Repositories.ContainsKey(typeof(T)))
{
return this.Repositories[typeof(T)].Value as Repository<T>;
}
throw new KeyNotFoundException("Unable to find repository for type: " + typeof(T).Name);
}
}
使用方法非常简单...
var repositoryStore = new RepositoryStore()
// ... set up the repository store, in the singleton?
Repository<MyObject> myObjectRepository = repositoryStore.GetRepository<MyObject>();
myObjectRepository.Create(new MyObject());
关于c# - 在 C# 中转换为泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16962687/