use injected implementation in constructor [duplicate]

对着背影说爱祢 提交于 2019-12-13 19:06:20

问题


Sorry about the ambiguous title, but I wasn't sure how to phrase it.

I am looking for any thoughts on whether the following would be a poor usage of an injected object. I have an IOC container set up in my application (I am using Unity, but I don't think that really matters for this). I was wondering if it is bad practice or if there is any catch to setting a variable in the constructor from the injected interface implementation without ever setting the injected implementation to a private variable.

In the example below, injectedClass is injected into the constructor by my IOC container. Typically, I would set injectedClass equal to a private instance of IInjectedClass, but since I am only going to use it to set that single variable, I am just setting the variable it in the constructor and then forgetting about the injected item.

public class SomeClass
{
    private string _someVariable;

    public SomeClass(IInjectedClass injectedClass)
    {
         _someVariable = injectedClass.GetSomeString();
    }

    public void SomeMethod()
    {
         Console.WriteLine(_someVariable);
    }

}

Is there any reason that the above code would be a bad practice? Or is the only argument against it that if I wanted to use the injectedClass again, it would not be available?

Thanks for any thoughts


回答1:


There are several problems with doing this. One is that it violates Nikola Malovic's 4th law of IoC.

In another answer here on Stack Overflow, I've outlined the various motivations for this rule.

In this particular case, there's the additional problem that it makes your class harder to reason about. When you look at the class as a black box (which is what all encapsulation is about), this is what you see:

public class SomeClass
{
    public SomeClass(IInjectedClass injectedClass)

    public void SomeMethod()    
}

It looks as though SomeClass requires IInjectedClass, but it turns out that it really only needs a string. This makes it more difficult to use, because you have to supply a complete IInjectedClass instance, when all you could have gotten away with was a string. You could say that this violates Postel's Law.

A better alternative is to be honest about the dependencies and request the string as a Primitive Dependency:

public class SomeClass
{
    private string _someVariable;

    public SomeClass(string someVariable)
    {
         _someVariable = someVariable;
    }

    public void SomeMethod()
    {
         Console.WriteLine(_someVariable);
    }

}



回答2:


I don't see a problem with that. However, you could also inject the string immediately. You could explicitly tell your container that a parameter with name x should be filled with a certain string.

If you do it that way, you're not creating a dependency on IInjectedClass.



来源:https://stackoverflow.com/questions/22563160/use-injected-implementation-in-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!