Sar*_*kar 6 c# generics factory-method
我有以下界面和实现:
public interface IRepository<T>
{
IList<T> GetAll();
}
internal class TrendDataRepository : IRepository<TrendData>
{
public IList<TrendData> GetAll()
{
//.. returns some specific data via Entity framework
}
}
Run Code Online (Sandbox Code Playgroud)
我将要有多个实现,它们都通过Entity Framework返回不同的数据.在某些时候,我想向用户表示实现IRepository接口的类列表.我使用以下代码执行此操作.这对我很有用.
public static IEnumerable<string> GetAvailableRepositoryClasses()
{
var repositories = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof (IRepository<>))
select t.Name;
return repositories;
}
Run Code Online (Sandbox Code Playgroud)
但是,我还想创建一个工厂方法,给定一个特定的字符串将返回一个具体的存储库类型,并允许我在其上调用'GetAll'方法.在伪代码中:
someObject = Factory.CreateInstance("TrendData");
someObject.GetAll();
Run Code Online (Sandbox Code Playgroud)
(我知道这不起作用,因为我必须在工厂方法中指定具体类型).
我希望这个功能,因为我想让用户能够将报告绑定到特定的数据源.通过这种方式,他们可以启动一个新报告,其中报告的数据源绑定到(例如)TrendDataRepository.GetAll()方法.
然而,也许是因为世界末日即将来临;-)或者是星期五下午我不能再思考了,我不知道如何实现这一点.
一些指针真的很受欢迎.
我建议返回存储库类型的集合而不是名称,并仅在 UI 中显示名称:
public static IEnumerable<Type> GetAvailableRepositoryClasses()
{
return Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof (IRepository<>)));
}
Run Code Online (Sandbox Code Playgroud)
然后,当用户选择源时,您可以执行以下操作:
object repository = Activator.CreateInstance(selectedType);
Run Code Online (Sandbox Code Playgroud)
此方法要求每个存储库都有一个默认构造函数。
Activator.CreateInstance返回一个对象,除非您知道所需IRepository<T>的泛型类型,否则您无法将其强制转换为接口。T最好的解决方案可能是创建一个非通用IRepository接口,您的存储库类也实现该接口:
public interface IRepository
{
IList<object> GetAll();
}
Run Code Online (Sandbox Code Playgroud)
现在您可以将创建的存储库转换为IRepository:
IRepository repository = (IRepository)Activator.CreateInstance(selectedType);
Run Code Online (Sandbox Code Playgroud)
您可以创建一个实现两者的存储库基类:
public abstract class RepositoryBase<T> : IRepository<T>, IRepository
{
public abstract IList<T> GetAll();
IList<object> IRepository.GetAll()
{
return this.GetAll().Cast<object>().ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1153 次 |
| 最近记录: |