具有显式类型转换的 C# 接口继承
C# interface inheritance with explicit typecast
我有一项服务可以创建、保存和发送不同类型的订单,其中某些类型的订单可以携带附件。
该服务将使用 IExternalService 将订单发送到另一个外部服务,该服务由具有不同外部端点的其他几个服务使用。
IExternalService 包含用于向外部服务发送订单的外部 IRepository 的 getter。
我已经为那些将添加附件 IRepositoryWithAttachement 的存储库创建了一个新接口。
我在下面提供了一些示例代码,其中我遗漏了不重要的内容:
interface IRepository //Standard repo used by different external services
{
string Create(Order order);
void Update(Order order);
}
带附件的订单使用
interface IRepositoryWithAttachement : IRepository //attachable repo
{
string AddFile(Attachement file);
void UpdateFile(Attachement file);
}
必须发送附件和订单的回购
public class Repository : IRepositoryWithAttachement {...}
许多外部服务的实现使用的服务
interface IExternalService
{
string Name { get; }
....
IRepository Repository { get; }
}
用于创建、保存和发送订单的主要服务class
public class OrderService
{
public string Create(Order order)
{
...
IExternalService eService = _externalServices.GetExternalService(id);
try
{
eService.Repository.Create(order);
}
catch (Exception e)
{
....
}
...
}
现在这个特定的订单类型将添加附件,当它使用 IExternalService 获取存储库时,它将返回一个 IRepository 并尝试调用 eService.Repository.AddFile(file) 但 AddFile 方法不存在,因为 return 类型是我想要的 IRepository。但是我的 IRepositoryWithAttachement 正在扩展 IRepository 所以我很困惑我将如何到达它并且我设法做到了这一点:
public string AddFile(Attachement file) {
IExternalService eService = _externalServices.GetExternalService(id);
try
{
((IRepositoryWithAttachement ) eService .Repository).AddFile(file);
}
catch (Exception e)
{
...
}
}
}
问题
我这样做是错误的还是通过类型转换获取 addfile 方法的问题是一个丑陋的解决方案?
我看到的两个最大问题是 a) 您似乎在使用异常处理来防止存储库未实现您需要的接口,以及 b) 您正在捕获 Exception
,而不是InvalidCastException
and/or 其他 特定的 您可以正确预测和处理的异常。
恕我直言,更好的实现应该是这样的:
public string AddFile(Attachement file) {
IExternalService eService = _externalServices.GetExternalService(id);
IRepositoryWithAttachement repository = eService.Repository as IRepositoryWithAttachement;
if (repository == null)
{
// report error in some appropriate way and return, or throw an
// _informative_ exception, e.g.
// new NotSupportedException("repository does not support attachments")
}
repository.AddFile(file);
}
更好的方法是对可用的存储库 ID 进行分类并根据功能限制访问,这样 AddFile()
方法就不会首先被调用,除非您知道存储库实现了必要的接口。然后你就可以安全地转换而不必担心抛出异常。
不幸的是,如果没有 a good, minimal, complete code example 清楚地说明问题,就很难或不可能提供比上述更具体的建议,并保证相关性。完全有可能有比您现在使用的方法更好的方法可用,但如果没有更多的上下文,就不可能真正说出那会是什么。
我有一项服务可以创建、保存和发送不同类型的订单,其中某些类型的订单可以携带附件。 该服务将使用 IExternalService 将订单发送到另一个外部服务,该服务由具有不同外部端点的其他几个服务使用。
IExternalService 包含用于向外部服务发送订单的外部 IRepository 的 getter。
我已经为那些将添加附件 IRepositoryWithAttachement 的存储库创建了一个新接口。
我在下面提供了一些示例代码,其中我遗漏了不重要的内容:
interface IRepository //Standard repo used by different external services
{
string Create(Order order);
void Update(Order order);
}
带附件的订单使用
interface IRepositoryWithAttachement : IRepository //attachable repo
{
string AddFile(Attachement file);
void UpdateFile(Attachement file);
}
必须发送附件和订单的回购
public class Repository : IRepositoryWithAttachement {...}
许多外部服务的实现使用的服务
interface IExternalService
{
string Name { get; }
....
IRepository Repository { get; }
}
用于创建、保存和发送订单的主要服务class
public class OrderService
{
public string Create(Order order)
{
...
IExternalService eService = _externalServices.GetExternalService(id);
try
{
eService.Repository.Create(order);
}
catch (Exception e)
{
....
}
...
}
现在这个特定的订单类型将添加附件,当它使用 IExternalService 获取存储库时,它将返回一个 IRepository 并尝试调用 eService.Repository.AddFile(file) 但 AddFile 方法不存在,因为 return 类型是我想要的 IRepository。但是我的 IRepositoryWithAttachement 正在扩展 IRepository 所以我很困惑我将如何到达它并且我设法做到了这一点:
public string AddFile(Attachement file) {
IExternalService eService = _externalServices.GetExternalService(id);
try
{
((IRepositoryWithAttachement ) eService .Repository).AddFile(file);
}
catch (Exception e)
{
...
}
}
}
问题 我这样做是错误的还是通过类型转换获取 addfile 方法的问题是一个丑陋的解决方案?
我看到的两个最大问题是 a) 您似乎在使用异常处理来防止存储库未实现您需要的接口,以及 b) 您正在捕获 Exception
,而不是InvalidCastException
and/or 其他 特定的 您可以正确预测和处理的异常。
恕我直言,更好的实现应该是这样的:
public string AddFile(Attachement file) {
IExternalService eService = _externalServices.GetExternalService(id);
IRepositoryWithAttachement repository = eService.Repository as IRepositoryWithAttachement;
if (repository == null)
{
// report error in some appropriate way and return, or throw an
// _informative_ exception, e.g.
// new NotSupportedException("repository does not support attachments")
}
repository.AddFile(file);
}
更好的方法是对可用的存储库 ID 进行分类并根据功能限制访问,这样 AddFile()
方法就不会首先被调用,除非您知道存储库实现了必要的接口。然后你就可以安全地转换而不必担心抛出异常。
不幸的是,如果没有 a good, minimal, complete code example 清楚地说明问题,就很难或不可能提供比上述更具体的建议,并保证相关性。完全有可能有比您现在使用的方法更好的方法可用,但如果没有更多的上下文,就不可能真正说出那会是什么。