我正在将 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/