C# 是否可以为存储库模式创建强类型类?
我正在尝试实现一个存储库模式,但是我不明白当实体具有不同类型的id时,它是如何可能的。目前,我不得不回退到使用object,而我确实希望使用存储库所持有的实体的特定类型的idC# 是否可以为存储库模式创建强类型类?,c#,C#,我正在尝试实现一个存储库模式,但是我不明白当实体具有不同类型的id时,它是如何可能的。目前,我不得不回退到使用object,而我确实希望使用存储库所持有的实体的特定类型的id interface IEntity { object GetId(); } class Foo : IEntity { private string id; public Foo(string id) { this.id = id; } public o
interface IEntity
{
object GetId();
}
class Foo : IEntity
{
private string id;
public Foo(string id)
{
this.id = id;
}
public object GetId()
{
return id;
}
}
class Bar : IEntity
{
private int id;
public Bar(int id)
{
this.id = id;
}
public object GetId()
{
return id;
}
}
class Repository<T> where T : IEntity
{
private Dictionary<object, T> entities = new Dictionary<object, T>();
public IEnumerable<T> List => entities.Values.AsEnumerable();
public void Add(T entity)
{
entities.Add(entity.GetId(), entity);
}
public T Get(object id)
{
return entities[id];
}
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo("0");
var bar = new Bar(0);
var fooRepo = new Repository<Foo>();
fooRepo.Add(foo);
fooRepo.Get(foo.GetId());
var barRepo = new Repository<Bar>();
barRepo.Add(bar);
barRepo.Get(bar.GetId());
}
}
我也试过这样的方法:
class Repository<Id, Value> where Value : IEntity
{
private Dictionary<Id, Value> entities = new Dictionary<Id, Value>();
public IEnumerable<Value> List => entities.Values.AsEnumerable();
public void Add(Value entity) // But got stuck here, I don't want to pass in Id as separate parameter, I want it auto magically from the interface.
{
entities.Add(entity.GetId(), entity);
}
public Value Get(Id id)
{
return entities[id];
}
}
您可以将键的泛型类型添加到IEntity。例如: 界面粗糙度 { TId GetId; } Foo类:智能 { 私有字符串id; 公共食物字符串id { this.id=id; } 公共字符串GetId { 返回id; } } 类存储库,其中tenty:ienty { 私有字典实体=新字典; 公共无效附加实体 { entities.Addentity.GetId,entity; } 公共TEntity GetTId id { 返回实体[id]; } }
乔尔的解决方案可以扩展到允许差异。泛型集合实现IEnumerable和IEnumerable的方式相同 实体
interface IEntity
{
object GetId();
}
interface IEntity<TId> : IEntity
{
new TId GetId();
}
abstract class EntityBase<TId> : IEntity<TId>
{
protected TId id;
protected EntityBase(TId id)
{
this.id = id;
}
public TId GetId() => id;
object IEntity.GetId() => GetId();
}
首先,它不是一个存储库模式,它是一个通用的存储库,一些开发人员认为它不仅仅是有用的东西,主要是因为我们对抽象有抽象作用。您可以将IEntity接口设置为通用接口,然后执行以下操作:class Repository,其中Value:IEntity
abstract class Repository
{
protected Dictionary<object, IEntity> entities;
protected Repository()
{
entities = new Dictionary<object, IEntity>();
}
public virtual void Add(IEntity entity)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
entities.Add(entity.GetId(), entity);
}
public virtual IEntity Get(object id)
{
if (id == null) throw new ArgumentNullException(nameof(id));
return entities[id];
}
}
abstract class Repository<TId, TEntity> : Repository
where TEntity : class, IEntity<TId>
{
protected Repository() : base() { }
public override void Add(IEntity entity)
{
Add((TEntity)entity);
}
public override IEntity Get(object id)
{
return Get((TId)id);
}
public void Add(TEntity entity)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
entities.Add(entity.GetId(), entity);
}
public TEntity Get(TId id)
{
if (id == null) throw new ArgumentNullException(nameof(id));
return (TEntity)entities[id];
}
}
class Foo : EntityBase<string>
{
public Foo(string id) : base(id) { }
}
class Bar : EntityBase<int>
{
public Bar(int id) : base(id) { }
}
class FooRepository : Repository<string, Foo>
{
public FooRepository() { }
}
class BarRepository : Repository<int, Bar>
{
public BarRepository() { }
}
[TestMethod]
public void IEntitySupport()
{
// use IEntity and object
IEntity bar = new Bar(1);
Repository barRepository = new BarRepository();
barRepository.Add(bar);
var bar2 = barRepository.Get((object)1);
Assert.AreSame(bar, bar2);
}
[TestMethod]
public void TEntitySupport()
{
// use TEntity and TId
var foo = new Foo("a");
var fooRepository = new FooRepository();
fooRepository.Add(foo);
var foo2 = fooRepository.Get("a");
Assert.AreSame(foo, foo2);
}