Simon
Simon

Reputation: 2116

Best practice for handling null with dependency injection c#

If I have

IMyService _myService;
public MyController(IMyService myService){
    _myService = myService;
}

and I'm using say unity to resolve my dependency...

Is it best practice to check if myService is null and if so should I throw an excpetion or create a new concrete implementation?

Upvotes: 3

Views: 5675

Answers (4)

Mikolaj
Mikolaj

Reputation: 1909

The Dependency Injection Provider should prevent you from injecting null references.

If you want to for some reasons inject the depenecy manually and null reference is not expected you can add null-checking as a pretty one-line expression with null-coalescing operator ?? and throw ArgumentNullException including the name of injected reference.

The null-coalescing operator ?? returns the value of its left-hand operand if it isn't null; otherwise, it evaluates the right-hand operand and returns its result. The ?? operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null.

private readonly IMyService _myService;
public MyController(IMyService myService)
{
    _myService = myService ?? throw new ArgumentNullException(nameof(myService));
}

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236278

First, Unity will not provide null as parameter value. It either will create instance of type registered for IMyService, or it will throw exception:

Exception is: InvalidOperationException - The type IMyService does not have an accessible constructor.


At the time of the exception, the container was:

Resolving Foo.MyController,(none)

Resolving parameter "myService" of constructor Foo.MyController(Foo.IMyService myService) Resolving Foo.IMyService,(none)

So, there is nothing to worry about null injected by Unity (or other dependency injection framework). But if controller can be instantiated manually it is possible that someone will pass null to constructor. Passing null is a very bad smell - that means something went wrong in your system. So, best option is checking service value and throw ArgumentNullException:

public MyController(IMyService myService)
{
    if (myService == null)
       throw new ArgumentNullException("myService");

    _myService = myService;
}

If injection of service should be optional. Then I suggest you to use property injection instead of constructor injection.

Upvotes: 4

mart
mart

Reputation: 224

Nope, if you are working with a DI framework that framework has to throw an exception when it can't resolve the dependency. You never create a concrete implementation thath is the whole point of use an inyector for your dependencies. Imagine you add:

if (myServices == null) _myService = new ConcreteService()

If you do that when you make the unit test for that controller if you choose to test the scenario when you passa a null IMyService you will be unable to mock that object because you are not inyecting it.

Upvotes: 1

Steven Liekens
Steven Liekens

Reputation: 14113

If it's okay for the dependency to be null (in which case it is by definition not a dependency, by the way), you should make it an optional parameter.

IMyService _myService;
public MyController(IMyService myService = null){
    _myService = myService;
}

In all other cases, throw an ArgumentNullException.

Upvotes: 1

Related Questions