我有一个获取IEnumerable
不同类型的存储库。
我可以通过使用:
来做到这一点switch (returnType)
{
case ReturnType.HR:
_repo.GetSystemManuals();
break;
case ReturnType.Finance:
_repo.GetPrivateRecords();
break;
case ReturnType.Dev:
_repo.GetTimeLine();
break;
case ReturnType.Admin:
_repo.GetLedger();
break;
case ReturnType.Support:
_repo.GetRoster();
break;
}
但这违反了SOLID原则的开启/关闭。
我想的方法之一是创建一个
的字典private static readonly IDictionary<S95Type, IQueryable<Customer>> ReqTypeMapper
= new Dictionary<S95Type, IQueryable<HR>>();
ReqTypeMapper.Add(ReturnType.HR, _repo.GetHR()());
但不确定如何使用不同的返回类型执行不同的方法。
答案 0 :(得分:4)
我认为您应该重新考虑您的设计并为每种类型创建一个存储库。 按定义进行的复制不应涉及许多不同的实体。 这将是一个干净,可维护的解决方案。
答案 1 :(得分:1)
你不需要一个巨大的开关。
只需调用方法动态。
_repo.getType().GetMethod("Get" + ((ReturnType)returnType).ToString()).Invoke(null,null)
答案 2 :(得分:1)
添加简单案例,您可以在enum
中的method
类型与Dictionary
之间进行翻译。
//Define type
public enum ReturnType {
HR,
Dev,
Finance
}
//Define methods
public void HRMethod() { Console.WriteLine("HR"); }
public void DevMethod() { Console.WriteLine("Dev"); }
public void FinanceMethod() { Console.WriteLine("Finance"); }
//Create a dictionary, where You add particular method for particular type
Dictionary<ReturnType, Action> myDict = new Dictionary<ReturnType, Action>();
myDict.Add(ReturnType.HR, HRMethod);
myDict.Add(ReturnType.Dev, DevMethod);
myDict.Add(ReturnType.Finance, FinanceMethod);
//Whenever the call occurs
myDict[ReturnType.HR].Invoke();
> HR
修改强>
使用IEnumerable的返回类型,它将如下所示:
//Define methods
public IEnumerable<HR> GetHR() { return new List<HR>() {new HR() {Name="HR" } }; }
public IEnumerable<Dev> GetDev() { return new List<Dev>() {new Dev() {Name="Dev" } }; }
//Create dict + fill
Dictionary<ReturnType, Func<object>> myDict2 = new Dictionary<ReturnType, Func<object>>();
myDict2.Add(ReturnType.HR, GetHR);
myDict2.Add(ReturnType.Dev, GetDev);
//Work with it as with result type
var lRes = (myDict2[ReturnType.HR].Invoke() as IEnumerable<HR>);
Console.WriteLine(lRes.First().Name);
> HR
<强>溶液2:强>
一个有点复杂的方法是:创建自定义attribute
,在每个枚举值上设置attribute
,其中包含要调用的方法的值(或方法名称,请参见下文)。完成此操作后,在开始时使用反射您将阅读这些属性,创建Dictionary
或Service
,这将提供所需的方法。
无法使用委托创建自己的属性(截至:Is it possible to have a delegate as attribute parameter?)。所以你必须使用“hacky”解决方案,包括原始类的类型,然后是方法名称。