简体   繁体   English

WCF - 依赖注入和 SOLID 原理的接口或 Class

[英]WCF - Interface or Class for Dependency Injection and SOLID principles

I am migrating an old.Net Framework 4.7.2 MVC application to.Net 6 and I am using some web services.我正在将旧的.Net Framework 4.7.2 MVC 应用程序迁移到.Net 6,并且正在使用一些 web 服务。 As Asp.Net 6 MVC is setup for Dependency Injection, I am trying to follow the principles of SOLID in my updated design.由于 Asp.Net 6 MVC 是为依赖注入设置的,我试图在我更新的设计中遵循SOLID的原则。

I know in the service container I can add the service as:我知道在服务容器中我可以将服务添加为:

builder.Services.AddTransient<IWebService, WebServiceClient>();

Then in the dependent class:然后在依赖的class中:

private readonly IWebService _ws;

public SomeClass(IWebService ws)
{
   _ws = ws;
}

This all works fine, but when using the interface of a web service, there are no methods exposed for OpenAsync or CloseAsync , but if I change it to this:这一切都很好,但是当使用 web 服务的接口时,没有为OpenAsyncCloseAsync公开方法,但是如果我将其更改为:

private readonly WebServiceClient _ws;

public SomeClass(IWebService ws)
{
    _ws = (WebServiceClient)ws;
}

I now have access to the concrete class and it exposes OpenAsync and CloseAsync我现在可以访问具体的 class 并且它公开OpenAsyncCloseAsync

Question(s) :问题

  1. Is it safe to use the Interface and not be able to call OpenAsync or CloseAsync ?使用接口并且不能调用OpenAsyncCloseAsync是否安全? Will this potentially cause unreleased resources and risk the object not being disposed?这是否会潜在地导致未释放的资源并有可能导致 object 未被处置?

  2. If I go with the second example and use the concrete class web service client instead of the Interface, is this breaking the D in SOLID -如果我在第二个示例中使用 go 并使用具体的 class web 服务客户端而不是接口,这是否会破坏SOLID中的D -

Entities must depend on abstractions, not on concretions.实体必须依赖于抽象,而不是具体。 It states that the high-level module must not depend on the low-level module, but they should depend on abstractions.它指出高级模块不能依赖于低级模块,但它们应该依赖于抽象。

Even with letting SOLID aside, using interfaces instead of concrete classes allows you to perform unit testing with mocked dependencies.即使将 SOLID 放在一边,使用接口而不是具体类也允许您使用模拟依赖项执行单元测试。 You can't mock concrete classes but only interfaces.你不能模拟具体的类,只能模拟接口。 When you will try to mock the interface in your unit tests, your concrete class under your interface will be replaced by a mocked version of it with your custom behavior.当您尝试在单元测试中模拟接口时,您的接口下的具体 class 将被替换为具有您自定义行为的模拟版本。 With your code in the second example, your application will crash because the mock can't be casted into WebServiceClient.使用第二个示例中的代码,您的应用程序将崩溃,因为无法将模拟转换为 WebServiceClient。

Talking about SOLID, your not breaking the D really, but the L. Liskov Substitution means that you should be able to replace an interface implementation at any time without breaking your code.谈到 SOLID,您并没有真正破坏 D,但是 L. Liskov Substitution 意味着您应该能够随时替换接口实现而不会破坏您的代码。 Therefore, if you put any implementation other than WebServiceClient under your interface, your cast will make the application crash.因此,如果您将 WebServiceClient 以外的任何实现放在您的接口下,您的强制转换将使应用程序崩溃。

So anyway, the second example is a really bad idea, both for solid and unit testing.所以无论如何,第二个例子对于实体测试和单元测试都是一个非常糟糕的主意。

Now, about not calling OpenAsync and CallAsync.现在,关于不调用 OpenAsync 和 CallAsync。 I assume WebServiceClient and IWebService are both classes you have access to (I mean, they are not from an external library).我假设 WebServiceClient 和 IWebService 都是您可以访问的类(我的意思是,它们不是来自外部库)。 Why don't you just declare OpenAsync and CloseAsync in your interface so you can call them from it?为什么不在界面中声明 OpenAsync 和 CloseAsync 以便可以从中调用它们呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM