依赖注入ctor两次 [英] Dependency injection ctor twice

查看:73
本文介绍了依赖注入ctor两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用依赖注入的类。

I have a class which use dependency injection.

public class BoerpiDebitAccountBalanceRetriever : IDebitAccountBalanceRetriever
    {
        private readonly IAccountInfo _MyDebitAccountInfo;

        public Exception ServiceException { get; set; }

        public BoerpiDebitAccountBalanceRetriever(IAccountInfo MyDebitAccountInfo)
        {
            _MyDebitAccountInfo = MyDebitAccountInfo;
        }

        public virtual DebitAccountBalanceResult GetDebitAccountBalance()
        {
            var client = GetBoerpiClient();
            var request = GetCustomerBalanceRequest();
            DebitAccountBalanceResult debitAccountBalanceResult = new DebitAccountBalanceResult();
            var response = GetCustomerBalanceResponse(client, request);
            debitAccountBalanceResult.DebitBalance = (decimal)response.AvailableFunds;
            debitAccountBalanceResult.MethodSuccess = response.MethodSuccess;
            return debitAccountBalanceResult;
        }

        public virtual GetCustomerBalanceResponse GetCustomerBalanceResponse(iBOERPIClient client,
            GetCustomerBalanceRequest request)
        {
            var response = client.GetDebitCustomerBalance(request);
            return response;
        }

        public virtual iBOERPIClient GetBoerpiClient()
        {
            var client = new iBOERPIClient();
            return client;
        }

        public virtual GetCustomerBalanceRequest GetCustomerBalanceRequest()
        {
            var request = new GetCustomerBalanceRequest();
            request.FacilityID = Int32.Parse(_MyDebitAccountInfo.FacilityId);
            request.InmateID = _MyDebitAccountInfo.InmateId;
            request.Token = _MyDebitAccountInfo.Token;
            return request;
        }
    }





在另一个班级



And in another class

public class TestCallFlowApplication : ICallFlowApplication
   {
       public IDebitAccountBalanceRetriever DebitAccountBalanceRetriever;
       public IAccountInfo MyDebitAccountInfo;
       public IPromptPlayer PromptPlayer;
       public ILine LineApi { get; set; }
       public ICallInfo CallInfo { get; set; }

       public TestCallFlowApplication(IDebitAccountBalanceRetriever debitAccountBalanceRetriever,
           IAccountInfo MyDebitAccountInfo)
       {
           MyDebitAccountInfo = MyDebitAccountInfo;
           DebitAccountBalanceRetriever = debitAccountBalanceRetriever;
       }

       public virtual void InstantiatePromptPlayer()
       {
           PromptPlayer = new PromptPlayer(LineApi, CallInfo);
       }

       public void GetMyDebitAccountInfo()
       {
           MyDebitAccountInfo.InmateId = PromptPlayer.InmateId;
           MyDebitAccountInfo.FacilityId = PromptPlayer.FacilityId;
           MyDebitAccountInfo.Token = Token;
       }





所以你在第二个类的构造函数中看到,我们注入了两个依赖项。

IDebitAccountBalanceRetriever IAccountInfo



但是在第一个类中,似乎 BoerpiDebitAccountBalanceRetriever 被注入 IAccountInfo

所以在第二个上课,紧紧地做两个依赖夫妻?我该怎么办?



我的尝试:



我从构造函数中删除第二个依赖项,只使用new up实例?但不确定它是否正确?



So you see in the second class's constructor, we inject two dependency.
IDebitAccountBalanceRetriever and IAccountInfo

However in the first class, it seems BoerpiDebitAccountBalanceRetriever is injected IAccountInfo.
So in the second class, do the two dependency couple tightly? What should I do?

What I have tried:

I remove the second dependency from the constructor and just use new up instance? But not sure it is correct?

推荐答案

首先,您没有两个注入依赖项,而是三个。答案是:不仅两个依赖关系没有紧密耦合,而且根本没有耦合问题。您可能认为两个实例通过常见的 IAccountInfo 耦合,但是......没有类似的东西。通常,此接口的实例过于不同,这两个实例甚至可能具有不同的类型。我们来看看。



你的问题就是看不到你在做什么。也许这是在许多不相关的代码背后看不到令人惊讶的简单事情的问题。也许你需要的只是缩短代码以查看问题的根源。抓取所有不相关的代码,你会看到:

First of all, you have not two injecting dependencies, but three. The answer is: not only two dependencies are not tightly coupled, but there is no coupling issue at all. You probably think that two instances are coupled via common IAccountInfo, but… there is nothing like that. You have, generally, too different instances of this interface, and these two instances could be even of different types. Let's see.

Your problem is just not seeing what you are doing. Perhaps this is the problem of not seeing amazingly simple thing behind a lot of unrelated code. Perhaps all you need is to shorten up the code to see at the root of the problem. Scratch all unrelated code, and you will see:
interface IA { }
interface IB { }

class AGood : IA { }
class ABetter : IA { }

class B : IB {
    public B(IA a) { this.a = a; }
    IA a;
}

class C {
    public C(IB b, IA a) { this.b = b;  this.a = a; }
    IA a;
    IB b;
}



请注意,您的顶级注射容器(客户端) TestCallFlowApplication 实现一些应用程序,它与问题完全无关。在我的示例中,这是 C ,界面被划掉了。我有意提供了两个不同的 IA 的实现(类似于你的样本的 IAccountInfo ),只是为了证明我的观点。在这里你如何使用所有这些实现:


Note that the fact that your top level injection container (client) TestCallFlowApplication implement some application, it totally irrelevant to the problem. In my sample, this is C, the interface is scratched out. I intentionally provided two different implementations of IA (analog of IAccountInfo of your sample), just to justify my point. Here how you can use all those implementations:

IA a1 = new AGood();
IA a2 = new ABetter();
IB b = new B(a1);
C c = new C(b, a2); // a1 is injected through b, a2 as a separate parameter



请注意,您有两个注入 IA 实例。它们不仅是两个独立的对象,而且它们也可以是两个不同的甚至不相关的(不受具有此接口的那个继承关系的约束)类型。你在哪里看到紧张? :-)



我的第二点......更难解释。你必须看到抽象设计背后的应用程序。通常,它需要更多的抽象思维,而不仅仅是从结构上看代码构造。如果你想到一个单一的界面,理解它的目的和质量需要你同时想象它的所有可能的实现,从这个角度看它们理论上是无限的。但是,对于许多人来说,想象一些与特定应用程序目标相关的实现会更容易。看起来,您的行为就像您认为自己有责任正确实施设计模式。但这不是你真正的责任。它是设计模式的作者,负责提出对某些应用程序可能有用的东西。这不是你取悦一些模式或原则的作者的目标。如果您从应用程序目标出发,它可能有助于您获得清晰的愿景。关于这个话题,对于一些食物,请看我过去的答案: 请向我推荐一些带有设计模式的基本C ++项目



至于你的什么我试过了部分,请看我对这个问题的评论。这是一个好主意,解释你真正尝试的东西;在这种情况下,它将是您的代码的一些修改变体。



-SA


Note that you have two injected IA instances. Not only they are two independent objects, but they also could be of two different and even unrelated (not bound by inheritance relationship except to the one with this interface) types. Where do you see tightness? :-)

My second point… is harder to explain. You have to see the application behind the abstract design. Often, it requires more abstract thinking than just looking at the code construct structurally. If you think of a single interface, understanding of its purpose and qualities requires you to imagine simultaneously all possible implementations of it, from this standpoint a theoretically infinite number of them. But, to many, it would be easier to imagine some implementations related to a particular set of application goal. Seemingly, you behave like you feel your responsibility for "implementing the design pattern right". But this is not your real responsibility. It's the author of design pattern is responsible for proposing something potentially useful for some application. It's not your goal to "please" the author of some pattern or a principle. If you go from the application goals, it may help you to gain clear vision. On this topic, for some food for though, please see my past answer: Please suggest me some basic C++ project with design patters.

As to your "What I have tried" section, please see my comment to the question. It's a good idea to explain what you really tried; in this case, it would be some modified variant of your code.

—SA


这篇关于依赖注入ctor两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆