c# - 正确实现同一接口的正确方法
问题描述
请记住,如果我不需要,我不想添加额外的依赖项。此外,我在寻找解决方案时发现的大部分想法都来自这里(stackoverflow.com)。
假设我有一个 IPrinterRepository 接口,我有多个不同的实现。
例如 EpsonRepository 和 CanonRepository、HPRepository 等一样实现 IPrinterRepository
所以现在我像这样在ConfigurationServices中注册了我的服务
services.AddTransient<EpsonRepository>();
services.AddTransient<HPRepository>();
services.AddSingleton<IPrinterRepositoryResolver, PrinterRepositoryResolver>();
- V1 -
现在,我一直在我的数据库中为每个特定用户激活的每台活动打印机保存一个 PRINTER_CODE。PrinterCode 是一类 const 字符串。
PrinterRepositoryResolver 处理正确实现的选择。所以有一种方法可以使用 switch 语句来做到这一点。
public IPrinterRepository GetRepository(string key)
{
switch (key)
{
case PrinterCode.Epson:
return (IPrinterRepository)_serviceProvider.GetService(typeof(EpsonRepository));
case PrinterCode.HP:
return (IPrinterRepository)_serviceProvider.GetService(typeof(HPRepository));
default:
throw new KeyNotFoundException("Sevice not implemented or not supported any more!");
}
}
- V2 -
或者也许我可以按类型选择正确的实现,这样我就不必使用 PRINTER_CODE 或维护 switch 语句。例子
而不是 PRINTER_CODE 将 DB 中实现的完整名称保存为字符串,并在以后需要时使用它来选择正确的实现。
public IPrinterRepository GetRepository(string ImplementationName)
{
var repoType= Type.GetType(ImplementationName);
return (IPrinterRepository)_serviceProvider.GetService(repoType);
}
这一切都适用于我的开发环境,但我不知道它是否可以。
就个人而言,我不喜欢这个开关,因为每次添加新的打印机实现时,都必须有人维护 PrinterCodes 和开关。
但同时保存一个带有命名空间的长字符串作为选择的键有点难看,我觉得可能还有更多我不知道的缺点。是否有一些调整或更好的想法,所以我可以以正确的方式做到这一点。
解决方案
我会采用稍微修改的 V1 方式:
避免了获取样板的对象,并且对象类型与 V2 案例中的名称没有紧密耦合。
public IPrinterRepository GetRepository(string name)
{
if (!_PrinterTypes.TryGetValue(name, out var type))
throw new KeyNotFoundException("Sevice not implemented or not supported any more!");
return _serviceProvider.GetService(type);
}
static readonly Dictionary<string, Type> _PrinterTypes = new Dictionary<string, Type>
{
[PrinterCode.Epson] = typeof(EpsonRepository),
[PrinterCode.HP] = typeof(HPRepository)
};
推荐阅读
- sql-server-2012 - 如何选择不同的列一次并空白到其相似的 id 列
- html - 为什么图表没有出现在我的网站 html 上
- android - 是否有强制使用“FrameLayout”来加载片段?
- multithreading - 如何将结构传递给QT线程
- jmeter - Jmeter - 如何仅在关闭所有从属中的主线程后执行拆除线程组?
- javascript - 为什么html画布线动画可以工作,但在已经画线之后却不行
- git - 有没有办法不跟踪对 Github 上特定存储库的贡献?
- kubernetes - 如果健康检查不满足successThreshold和failureThreshold,pod的状态应该是什么,也不
- c# - 实体框架 Linq IntelliSense 问题
- java - 生成的多项式回归值离坐标太远