我有这个单例工厂类示例,我在其中使用字典并在运行时确定相关的报表类。因为根据每个报表服务还必须执行的操作,最多有 40 种组合。
public sealed class ReportServiceFactory : IGetReportServices
{
private static readonly ReportServiceFactory instance = new ReportServiceFactory();
private static readonly Dictionary<Tuple<ReportTypes, ReportPeriodTypes>, IServiceReports> reportEntityServices =
new Dictionary<Tuple<ReportTypes, ReportPeriodTypes>, IServiceReports> {
{ Tuple.Create(ReportTypes.Foo, ReportPeriodTypes.Week), new FooService<FooWeekEntity>() },
{ Tuple.Create(ReportTypes.Foo, ReportPeriodTypes.Month), new FooService<FooMonthEntity>() },
{ Tuple.Create(ReportTypes.Bar, ReportPeriodTypes.Week), new BarService<BarWeekEntity>() },
{ Tuple.Create(ReportTypes.Bar, ReportPeriodTypes.Month), new BarService<BarMonthEntity>() }
};
// Explicit static constructor to tell C# compiler not to mark type as beforefieldinit
static ReportServiceFactory()
{
}
private ReportServiceFactory()
{
}
public static ReportServiceFactory Instance
{
get { return instance; }
}
public IServiceReports Get(ReportTypes reportType, ReportPeriodTypes periodType)
{
if (!Enum.IsDefined(typeof(ReportTypes), reportType))
throw new ArgumentOutOfRangeException("reportType");
if (!Enum.IsDefined(typeof(ReportPeriodTypes), periodType))
throw new ArgumentOutOfRangeException("periodType");
var reportTuple = Tuple.Create(reportType, periodType);
if (!reportEntityServices.ContainsKey(reportTuple))
return null;
return reportEntityServices[reportTuple];
}
}
我希望能够为Get()
工厂上的函数返回一个更具体的接口,例如在执行时将其更改IServiceFooReports
为......这样我就可以访问下面的FooViewModel
Get()
函数,而无需将结果转换为其他调用代码。
public interface IServiceFooReports : IServiceReports
{
IEnumerable<FooViewModel> Get();
}
public class FooService<T> : IServiceFooReports
{
... use EF model context and call .CreateObjectContext<T>()
do filtering on the IQueryable result and return the result materialised as the relevant view models
}
这可能吗?这是IGetReportServices
界面,以防也需要更改。IServiceReports
是空的,目前仅用作将这些报告服务存储在同一个字典中的一种方式……标记接口?
public interface IGetReportServices
{
IServiceReports Get(ReportTypes reportType, ReportPeriodTypes reportPeriodType);
}