摆脱泛型声明
本文关键字:声明 泛型 | 更新日期: 2023-09-27 17:51:10
我正在尝试定义适当的接口和类,以创建一个存储库接口和一个基本存储库类,以完成每个存储库都需要的常见功能。然后,我还想为特定的实体类型定义一个存储库,该实体类型也在它自己的接口中定义。
到目前为止,我已经想到了以下内容:
// The repository interface:
/// <summary>
/// Defines the methods of the base repository
/// </summary>
/// <typeparam name="TEntity">An entity class</typeparam>
public interface IRepository<TEntity> where TEntity : class
{
/// <summary>
/// Retrieves all the entities
/// </summary>
/// <returns>A query able set of entities</returns>
IQueryable<TEntity> Get();
}
// An abstract implementation of it, which all repositories will inherit from:
/// <summary>
/// Represents the base repository from which all database bound repositories inherit
/// </summary>
/// <typeparam name="TEntity">The entity type this repository handles</typeparam>
public abstract class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
/// <summary>
/// Retrieves all the entities
/// </summary>
/// <returns>A query able set of entities</returns>
public virtual IQueryable<TEntity> Get()
{
return this.Context.Set<TEntity>();
}
}
用户实体的特定接口:
/// <summary>
/// Represents a user
/// </summary>
public class User
{
public string Login { get; set; }
public string Password { get; set; }
}
/// <summary>
/// Defines the interface for user repository implementations
/// </summary>
/// <typeparam name="TEntity">A user entity</typeparam>
public interface IUserRepository<TEntity> : IRepository<TEntity> where TEntity : User
{
void Authenticate(TEntity user);
}
// and it's implementation:
/// <summary>
/// Represents a database bound repository that handles user entities
/// </summary>
/// <typeparam name="TEntity">A user entity</typeparam>
public class UserRepository<TEntity> : BaseRepository<TEntity>, IUserRepository<TEntity> where TEntity : User
{
public void Authenticate(TEntity user)
{
// do some stuff here
}
}
上面的工作很好,但为了实例化一个UserRepository,我必须写var users = new UserRepository<User>()
很明显,UserRepository中的泛型只能是User类型,所以我想找到一种不必显式编写的方法。我希望可以写成var users = new UserRepository()
。
另外,在编写测试时,我必须像这样创建IUserRepository的模拟:
var usersMock = new Mock<IUserRepository<User>>();
在这里,我也希望能够这样写:
var usersMock = new Mock<IUserRepository>();
这可能是一个XY问题,所以我对不同的整体实现建议持开放态度。
您可以实现特定的接口:
public interface IUserRepository : IRepository<User>
{
void Authenticate(Useruser);
}
// and it's implementation:
public class UserRepository : BaseRepository<User>, IUserRepository
{
public void Authenticate(User user)
{
// do some stuff here
}
}
你的接口可以有泛型类型参数,但是当你实现一个接口时,你可以指定这些参数。您的实现也不需要是通用的
如果你总是使用一个特定的类或接口来继承/实现一个特定的类,那么你不需要给它附加泛型。
下面是一个例子,希望是你想要的:
public interface IUserRepository : IRepository<IUser>
{
void Authenticate(IUser user);
}
public class UserRepository : BaseRepository<User>, IUserRepository
{
public void Authenticate(IUser user)
{
// do some stuff here
}
}
您现在可以实例化和模拟,而不必指定可能总是相同的泛型。
var repository = new UserRepository();