c# - 为 .NET Framework 接口(interface)实现接口(interface)隔离原则

标签 c# .net

我正在将 IServiceLocator(CommonServiceLocator 包)实现到我的自定义 ServiceLocator 类中。

该接口(interface)有以下方法需要实现:

public class CustomServiceLocator : IServiceLocator
{
    private IServiceProvider _provider;

    public RatioDissectionServiceLocator(IServiceProvider provider)
    {
        _provider = provider;
    }

    public IEnumerable<object> GetAllInstances(Type serviceType)
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TService> GetAllInstances<TService>()
    {
        throw new NotImplementedException();
    }

    public object GetInstance(Type serviceType)
    {
        throw new NotImplementedException();
    }

    public object GetInstance(Type serviceType, string key)
    {
        throw new NotImplementedException();
    }

    public TService GetInstance<TService>()
    {
        return _provider.GetService<TService>();
    }
 }

我不想实现我的类中的所有方法。如何实现内置C#接口(interface)的ISP?

有什么帮助吗?

最佳答案

接口(interface)隔离原则指出:

No client should be forced to depend on methods it does not use.

这意味着,尽管对该原则有许多不清楚和误导性的解释,但大接口(interface)本身并不违反该原则。也许另一个类实际上确实依赖于该接口(interface)的所有成员。因此,我们不会查看像 IServiceLocator 这样的接口(interface)并尝试以某种方式“修复”它。

从依赖于接口(interface)的类的角度来看,ISP 是。如果一个接口(interface)有 20 个成员,而我的类依赖于所有这些成员,则这不是 ISP 违规。 (这很可能是与 ISP 无关的各种其他坏事。)如果另一个类依赖于完全相同的接口(interface)并且仅使用几个成员,那就是 ISP 违规。

在这两个示例中,它是相同的界面。原理与接口(interface)无关。这是关于依赖于接口(interface)的类是否使用其所有成员的问题。

(我经常看到的另一个奇怪的例子是一个大接口(interface)和一个实现接口(interface)的类,但为某些成员抛出NotImplementedException。这也很糟糕,而且是一个里氏替换违规,但它与 ISP 完全无关。实现接口(interface)并不依赖。)

避免 ISP 违规的一种方法是从依赖接口(interface)的类的角度来编写接口(interface)。无论您的类需要从其依赖项中获得什么,都可以编写接口(interface)来准确描述这一点。如果具体的内部实现是一个有100个成员的框架类,则将其包装在您自己的类中:

public interface ISmallSegregatedInterface
{
    void DoJustWhatMyClassNeeds();
}

public class TheImplementation : ISmallSegregatedInterface
{
    private readonly FrameworkClassWithLotsOfMembers _inner;

    public TheImplementation(FrameworkClassWithLotsOfMembers inner)
    {
        _inner = inner;
    }

    public void DoJustWhatMyClassNeeds()
    {
        _inner.CallSomeMethod();
    }
}

现在,需要依赖于一种方法的类可以依赖于仅具有该一种方法的接口(interface)。 (随着时间的推移,我发现这会导致很多单方法接口(interface)。我认为这在逻辑上会导致depending on functions and delegates,但单方法接口(interface)是可以的。

这就是接口(interface)隔离。您的类不依赖于他们不需要的大接口(interface)。他们依赖于一个或多个接口(interface)来准确描述他们的需求。这通常是通过从需要依赖它的类的角度创建接口(interface)来完成的。


您可能会发现没有类需要依赖于 IServiceLocator 的所有方法。

也许您需要的是:

TService GetInstance<TService>();

但是一个类真的需要依赖一个可以返回任何东西的方法吗?换句话说,您可能只会请求一两个依赖项。所以也许您真正需要的是:

public interface ISomethingSpecificFactory
{
    ISomethingSpecific CreateInstance();
}

或者您可能会发现您根本不需要工厂 - 也许您可以只注入(inject) ISomethingSpecific 而不是创建 ISomethingSpecific 实例的工厂。

另一种看待它的方式:如果您不需要实现 IServiceLocator 的所有方法,那么您不需要创建一个实现 IServiceLocator 的类>.


IServiceLocator 是一个框架接口(interface)。与我们创建的大多数软件不同,它的存在并不是为了满足狭隘的特定需求。它满足我们在编写软件时确定的更广泛的需求。这就是为什么它具有我们可能不需要的各种不同方法更有意义。

ISP 的一个原因是,如果许多类依赖于一个接口(interface)的不同成员,我们可能会因为一个客户端的需求而被迫更改接口(interface),而这些更改会影响依赖于其他方法的其他客户端,实际上将它们全部耦合在一起。

我们无法更改IServiceLocator以使压力不存在。因此,从技术上讲,即使我们确实通过依赖该接口(interface)违反了 ISP,也不会产生 ISP 保护我们免受的有害影响。

关于c# - 为 .NET Framework 接口(interface)实现接口(interface)隔离原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55516281/

相关文章:

c# - 如何从自动缩放图表控件中获取最大 Y 轴值

c# - 如何从 C# 线程获取成员函数作为该线程参数的对象?

c# - 集合中的排序值仅在循环中可见

c# - api Controller 中的多个 HttpPost 方法导致 500 Internal server error

c# - 如何使用自定义模型 Binder 对路由进行单元测试

c# - 如何开发负载平衡友好的 Web 应用程序

c# - Dot Net MemoryCache 逐出

c# - 为什么我不应该有一个单一的整体实用程序库?

c# - 发送大量邮件时 SmtpClient.SendMailAsync 方法挂起

c# - 如何在 C# 中获取日期范围内的所有周末