工厂方法和泛型
本文关键字:泛型 方法 工厂 | 更新日期: 2023-09-27 17:49:15
我有以下接口和实现:
public interface IRepository<T>
{
IList<T> GetAll();
}
internal class TrendDataRepository : IRepository<TrendData>
{
public IList<TrendData> GetAll()
{
//.. returns some specific data via 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;
}
然而,我还想创建一个工厂方法,给定一个特定的字符串将返回一个具体的存储库类型,并允许我调用'GetAll'方法。在伪代码:
someObject = Factory.CreateInstance("TrendData");
someObject.GetAll();
(我知道这行不通,因为我必须在工厂方法中指定一个具体的类型)。
我需要这个功能,因为我想让用户能够将报表绑定到特定的数据源。通过这种方式,他们可以启动一个新的报表,其中报表的数据源绑定到(例如)trenddatareposiitory . getall()方法。
然而,也许是因为世界末日即将来临;-)或者是周五下午,我只是不能再清晰地思考,我不知道如何意识到这一点。
我建议返回存储库类型的集合而不是名称,并且只在UI中显示名称:
public static IEnumerable<Type> GetAvailableRepositoryClasses()
{
return Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof (IRepository<>)));
}
当用户选择源时,你可以这样做:
object repository = Activator.CreateInstance(selectedType);
此方法要求每个存储库都有一个默认构造函数。
Activator.CreateInstance
返回一个对象,你不能将它强制转换到你的IRepository<T>
接口,除非你知道你所期望的泛型T
。最好的解决方案可能是创建一个非通用的IRepository
接口,您的存储库类也实现了该接口:
public interface IRepository
{
IList<object> GetAll();
}
现在您可以将创建的存储库强制转换为IRepository
:
IRepository repository = (IRepository)Activator.CreateInstance(selectedType);
你可能需要创建一个库基类来实现:
public abstract class RepositoryBase<T> : IRepository<T>, IRepository
{
public abstract IList<T> GetAll();
IList<object> IRepository.GetAll()
{
return this.GetAll().Cast<object>().ToList();
}
}