.NET: what exception should be thrown when a required property is not set?

Suppose I have a class:

public class Foo { public Bar RequiredProperty { get; set;} public void Baz() { if (this.RequiredProperty == null) { // Which exception should I throw? } } } 

My solution has a class that is designed to be reused without having to pass many arguments to the Bar method over and over again. So what should I do if Bar not initialized to a non-zero value?

Additional Information I essentially collapse my own code analyzer and formatter. Call it a lesson. One of the classes is the HtmlCodeFormatter , which has the following properties (in honor of dependency injection):

 public IFormatter Formatter { get; set; } public IParser Parsre { get; set; } 

This allows me to write any number of language-specific parsers and formatters. For example, I have CSharpParser and JavascriptParser . I also have an HtmlCodeFormatter , and have plans for another (dubious utility).

The idea is that you can instantiate an HtmlFormatter using an object initializer, for example:

 var formatter = new HtmlCodeFormatter() { Parser = new CSharpParser(); Formatter = new HtmlCodeFormatter(); }; formatter.Format("Console.WriteLine(\"Hello, world!\")); 

When HtmlCodeFormatter.Format is HtmlCodeFormatter.Format , it should be able to verify that both the parser and the formatter have been provided. This is not a problem, in fact, but I'm a little fixated on which exception to throw. I tend to have an InvalidOperationException , but I'm not quite sure what the best choice is.

+6
dependency-injection exception
source share
3 answers

I would throw an InvalidOperationException . MSDN Definition:

An exception is thrown when a method call is invalid for the current state of an object.

However , I recommend using constructor injection instead of setter injection. This ensures that you have valid parsers and formatting elements. If null is passed in the constructor, throw an ArgumentNullException .

+12
source share

Using Injection Injection , you implicitly tell the compiler, other developers, and DI containers that the dependency is optional . This is because no one forces you to assign a property value .

If dependency is really necessary, you need to reorganize the Injection constructor . This will make the necessary dependency:

 public class Foo { private readonly Bar bar; public Foo(Bar bar) { if (bar == null) { throw new ArgumentNullException("bar"); } this.bar = bar; } public Bar RequiredProperty { get { return this.bar; } } public void Baz() { // this.bar is now GUARANTEED to be initialized, // so no checks are required } } 

Note that the Guard Clause constructor (throwing an ArgumentNullException) effectively protects the invariants of the class, which further reinforced the readonly keyword.

With part of the dependencies of the class invariants, you no longer have a temporary connection , and now you can implement all the participants without worrying about whether the dependency has been assigned or not.

+7
source share

You can NotInitializedException .

+1
source share

All Articles