我有一个接口/类在我的ASP。. NET MVC应用程序,其中引用了我所有的通用存储库。它看起来像这样:
public interface IDb
{
IGenericRepository<Car> CarRepository { get; }
...
IGenericRepository<User> UserRepository { get; }
}
我的目标是找到程序集中实现某个接口的所有类型,然后找到相应的通用存储库以从数据库中获取一些对象。这应该可以工作:
List<IVehicle> vehicleElements = new List<IVehicle>();
Type vehicleType = typeof(IVehicle);
Type dbType = typeof(IDb);
foreach (Type type in vehicleType.Assembly.GetTypes().Where(t => t.IsClass && t.GetInterfaces().Contains(vehicleType)))
{
PropertyInfo repositoryInfo = dbType.GetProperties().Where(p => p.PropertyType.GenericTypeArguments.Contains(type)).SingleOrDefault();
if (repositoryInfo != null)
{
var repository = repositoryInfo.GetValue(this.db);
// TODO: work with repository
}
}
return vehicleElements;
我的问题是,我不知道如何将存储库变量转换为所需的通用genericrepository…什么好主意吗?
您想要做的事情无法工作,因为为了拥有强类型存储库,您需要在编译时知道实现接口的类型。但是你只有在运行时才知道。
一个解决方案是引入非通用存储库。
另一个解决方案是使用dynamic
关键字。
dynamic repository = repositoryInfo.GetValue(this.db);
repository.SomeMethod(...);
但是,这意味着编译器不再能够检查涉及该动态变量的代码。换句话说:如果SomeMethod
在repository
的实际类型上不存在,将抛出运行时异常而不是编译器错误。
我将使用一个基本的IRepository接口,其中包含您在此代码中需要与之交互的常用方法。
如果由于某些原因这是不可能的,您可以使用松散耦合的方法,通过强制转换为动态或通过反射抓取您需要的方法。