このシングルトン ファクトリ クラスの例では、ディクショナリを使用して、実行時に関連するレポート クラスを決定します。各レポート サービスが行う必要があることに基づいて、最大 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);
}