c# - 如果我们想利用依赖注入(inject),我们还应该创建实例吗?

标签 c# dependency-injection instantiation constructor-injection

我对依赖注入(inject)的概念越来越深入,我读的越多,我就越喜欢它背后的想法。我已经用了一段时间了,但还是时不时有很多事情让我感到困惑,我觉得我没有充分发挥它的潜力。

想象一下下面的代码。在这个类中,(可能有一些事情可以改进,但是..)我们有一个返回字符串值的方法。不需要构造函数注入(inject)(或者至少我是这么认为的,如果我错了,请纠正我),但是在 try block 的最后一行,我们创建了 StreamReader 类的新实例能够将响应流传递给它并使用 ReadToEnd 方法获取结果。

依赖注入(inject)背后的想法是避免在类内部创建实例,但是如何处理这种情况呢?

public class WebClientService : IWebClientService
{    
        public async Task<String> GetApiResponseAsync(string Url)
        {
            String responseText = await Task.Run(() =>
            {
                try
                {
                    HttpWebRequest request = WebRequest.Create(Url) as HttpWebRequest;
                    WebResponse response = request.GetResponse();
                    Stream responseStream = response.GetResponseStream();
                    return new StreamReader(responseStream).ReadToEnd();
                }
                catch (Exception e)
                {
                    LogMessageDispatcher.Instance.Log(e);
                }
                return null;
            });

            return responseText;
        }
}

我正在阅读“Mark Seemann 的书 - 依赖注入(inject)”,但我还有很多内容要讲。

最佳答案

这是一个非常简单的示例,并且相对容易定义,因为您的耦合是一个没有任何服务相关功能的基本类。我们先从维基百科对DI的定义说起:

In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object. A "dependency" is an object that can be used, for example as a service. Instead of a client specifying which service it will use, something tells the client what service to use. The "injection" refers to the passing of a dependency (a service) into the object (a client) that would use it. The service is made part of the client's state.[1] Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.

那是什么意思。当我们使用 DI 时,我们不应该创建 StringBuilder 对象吗?答案是否定的(或者更好但并非总是如此)。我可以在没有 DI 的情况下创建一个新的 float 吗?创建构建器服务并从那里创建 StreamReader 是否有意义?

您将看到 StreamReader 是一个非常基本的实现 public class StreamReader : System.IO.TextReader 并且这些类甚至没有实现除 IDisposable 之外的任何其他接口(interface)。您不能认真考虑在任何类中为 IDisposable 注入(inject) StreamReader。

如果您想与 StreamReader 分离,那么这意味着您将来可能想要使用其他东西。您可以创建一个 StreamService 并随心所欲地创建您的流,但最终 StreamService 将具有 Coupling,因为 StreamReader 可以'不要被注入(inject)。

这就是维基百科推断服务被注入(inject)的原因。对象可能是解耦的,但您可能希望使用其他模式,例如 Factory

顺便说一句,使用 StreamReader 时始终使用 Using 关键字,以便正确处理对象。

关于c# - 如果我们想利用依赖注入(inject),我们还应该创建实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59335128/

相关文章:

c# SerialPort WriteTimeout 使用?

asp.net-mvc-3 - 是否可以将太多存储库注入(inject) Controller ?

c# - 使用 Unity 改变构造函数注入(inject)的字符串参数

c++ - 如何强制 C++ 模板的特定实例实例化?

objective-c - 当全局对象传递给函数时,在 Objective C 中实例化它们。关于对象范围的困惑

c# - 无法从 IIS 打开数据库错误

c# - c#中Thread中suspend和sleep的区别

java - EJB 无法解析引用,因为应用程序中存在多个具有相同接口(interface)的 ejb

c++ - 显式模板实例化 : MSVC vs. GCC

c# - 我是否在依赖者或委托(delegate)人上定义两个实体之间的关系?