我使用两种类型的通用接口IRepository<Entity, DTO>
。如何使用依赖注入在RepositoryFactory中初始化。
接口。
public interface IRepository<Entity, DTO> where Entity : BaseEntity where DTO : BaseDTO
{
bool Save(Entity Entity);
bool Save(Entity Entity, out int OutID);
bool Update(Entity Entity);
bool Update(Entity Entity, out int OutID);
DTO GetRecord(Entity ID);
DTO GetRecord(Expression<Func<Entity, bool>> predicate);
List<DTO> GetList();
List<DTO> GetByQuery(Expression<Func<Entity, bool>> predicate);
}
BaseEntity,BaseDTO
public abstract class BaseEntity
{
public int ID { get; protected set; }
}
public class BaseDTO
{
public int ID { get; protected set; }
}
管理员存储库
public class AdministratorRepository : Repository<AdministratorEntity, AdministratorDTO>
{
public AdministratorRepository(string ConnectionString) : base(ConnectionString)
{
}
// Implemented functions for Repository base class
}
存储库基础存储库类
public abstract class Repository<Entity, DTO> : IRepository<Entity, DTO>
where Entity : BaseEntity
where DTO : BaseDTO
{
// Implemented functions for IRepository Interface
}
RepositoryFactory
public class RepositoryFactory<Entity, DTO> where Entity : BaseEntity where DTO : BaseDTO
{
private static string CONNECTION_STRING = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
public static IRepository<Entity, DTO> Create(Repositories repository)
{
IRepository<Entity, DTO> iRepo = null;
switch (repository)
{
// If I do this, program wants me to cast
case Repositories.Administrator:
// Casting error occured in this line.
// AdministratorRepository derives from Repository.
/*
Cannot implicitly convert type
'BusinessRules.Repositories.AdministratorRepository' to
'BusinessRules.Repositories.IRepositories.IRepository<Entity,DTO>'.
An explicit conversion exists (are you missing a cast?)
*/
iRepo = new AdministratorRepository(CONNECTION_STRING);
break;
// If I do this, program throws an exception
// Exception: TypeInitializationException
// Exception Description: The type initializer for 'BusinessRules.Repositories.RepositoryFactory`2' threw an exception.
case Repo.Administrator:
iRepo = (IRepository<Entity, DTO>)(new AdministratorRepository(CONNECTION_STRING));
break;
}
return iRepo;
}
}
答案 0 :(得分:0)
您提到的场景是“您尝试分配更多派生类型对象而不是接口的泛型类型参数”。要允许分配,您应该使用out参数类型定义通用接口。 阅读本文以了解C#中的variance。
您可以使用out关键字声明泛型类型参数协变。
因此将IRepository
接口定义为
public interface IRepository<out Entity, out DTO> where Entity : BaseEntity where DTO : BaseDTO
{
//......
}
完整代码(示例应用 - 检查this实况小提琴)
using System;
public abstract class BaseEntity
{
public int ID { get; protected set; }
}
public class BaseDTO
{
public int ID { get; protected set; }
}
public interface IRepository<out Entity, out DTO> where Entity : BaseEntity where DTO : BaseDTO
{
string GetTestString();
}
public abstract class Repository<Entity, DTO> : IRepository<Entity, DTO>
where Entity : BaseEntity
where DTO : BaseDTO
{
// Implemented functions for IRepository Interface
public Repository(string connectionString)
{
}
public abstract string GetTestString();
}
public class AdministratorEntity : BaseEntity
{
}
public class AdministratorDTO : BaseDTO
{
}
public class AdministratorRepository : Repository<AdministratorEntity, AdministratorDTO>
{
public AdministratorRepository(string ConnectionString) : base(ConnectionString)
{
}
public override string GetTestString()
{
return "TestString";
}
// Implemented functions for Repository base class
}
public class Program
{
public static void Main()
{
IRepository<BaseEntity, BaseDTO> repo = new AdministratorRepository("connectionString");
Console.WriteLine(repo.GetTestString());
Console.WriteLine("Hello World");
}
}