use injected implementation in constructor [duplic

2019-08-03 00:04发布

This question already has an answer here:

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

2条回答
Bombasti
2楼-- · 2019-08-03 00:18

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.

查看更多
forever°为你锁心
3楼-- · 2019-08-03 00:24

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);
    }

}
查看更多
登录 后发表回答