2

Using Constructor Injection, a dependency gets injected to a consumer like this (at least I hope I understood it correctly):

public class SomeConsumer
{
    private IDependency someDependency;
    public SomeConsumer(IDependency someDependency)
    {
        if (someDependency != null)
        {
            this.someDependency = someDependency;
        }
        else
        {
            throw new ArgumentNullException("someDependency");
        }
    }

    public void Baz()
    {
        someDependency.DoSomething();
    }
    (...)
}

If I were to use the Null Object Pattern for IDependency, do I need the guard clause? Or is it wrong to inject a Null Object?

UPDATE: To clarify, let's assume I have classes and interfaces like this:

public interface IDependency
{
    void DoSomething();
}

public class NullDependency : IDependency
{
    public void DoSomething()
    {
        //Do nothing...
    }
}

public class RealDependency : IDependency
{
    public void DoSomething()
    {
        Console.WriteLine("Did something");
    }
}

public class Foo
{
    public void Bar()
    {
        IDependency dependency = new NullDependency();
        SomeConsumer sc = new SomeConsumer(dependency);
        sc.Baz();
    }
}

Can I then safely remove the guard clause from SomeConsumer, making it look like:

public class SomeConsumer
{
    private IDependency someDependency;
    public SomeConsumer(IDependency someDependency)
    {
        this.someDependency = someDependency;
    }

    public void Baz()
    {
        //if someDependency is a NullDependency, this does nothing
        someDependency.DoSomething(); 
    }
    (...)
}

Or should I use the guard clause because I can't be sure that null will never be injected?

Thaoden
  • 3,460
  • 3
  • 33
  • 45

3 Answers3

3

IMHO I'd abandon the guard clause under the following circumstances:

  • SomeConsumer is only being used from within your product
  • Null object pattern is thoroughly lived by your team and/or dependency injection container configuration

I would probably not abandon the guard clause, if:

  • the need for a null object isn't documented sufficiently for the target audience
  • SomeConsumer is part of an open API to be used by developers that are not aware of the null object pattern
  • I'd like to receive feedback from my dependency injection container by the time it instanciates SomeConsumer, that I made a mistake
TheSchmu
  • 574
  • 5
  • 25
2

I don't like dropping guard clauses under any circumstances. Whoever uses this class, all objects created should be valid. If you allow null to be injected through the constructor, you're allowing an invalid object to be constructed. Later on, something will break when a method is called.

It is not the question whether this class is internal or not. The question is will you make sure that in all places all measures are taken to produce non-null value when calling the constructor? Even if your answer is "yes", the next question is why would you waste time and energy checking that?

Just leave the guard clause and you will know that all objects of this class will be constructed properly. Otherwise, if you inadvertently pass null to the constructor, some totally unrelated class will fail and you will have hard time tracing the error back to this constructor.

On a related note, some guard clauses (those that test conditions other than null) are often a cause to reconsider design. You may find this article interesting - Why do We Need Guard Clauses?

Zoran Horvat
  • 10,924
  • 3
  • 31
  • 43
0

IMHO it's perfectly fine to inject a null object, this is frequently used in testing. I often inject mocks with default behavior in my unit tests when I don't care about that dependency.

I'd probably replace the null check with throwing an exception or remove it altogether. It currently doesn't do anything since the default value of the someDependency variable is null anyway.

NeddySpaghetti
  • 13,187
  • 5
  • 32
  • 61
  • 1
    I forgot to add the exception thrown, the question is updated. – Thaoden Jan 02 '15 at 11:05
  • It is far better to use the [null object pattern](https://sourcemaking.com/design_patterns/null_object) than to inject a `null` object pointer. This way, you don't have to complicate the class with `null` checking. – NightOwl888 Mar 28 '18 at 19:21