Safer C# Constructor-based Dependency Injection with readonly


Most people would have used the const keyword while doing C# development, but I had never heard of the readonly keyword before. Well, this weekend I had a friend point out this keyword and the first usage that came to mind was constructor-based dependency injection.


Here is the clarification of the differences between readonly and const from MSDN:



The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants e.g. public static readonly DateTime _creationTime = DateTime.Now;


So now I can create a class with a dependency (reference) that is injected in the constructor and I can be sure that no method in the class will change that injected dependency.


Using Martin Fowler’s MovieLister example, I can now have this:


public class MovieLister
{
    private readonly MovieFinder finder;
    public MovieLister(MovieFinder finder)
    {
        this.finder = finder;
    }
}


And if anyone tries to change that readonly local member variable in a method like…


public class MovieLister…
    public
void
MethodThatWontCompile()
    {
        this.finder = null; //Error because a readonly field cannot be assigned to
    }


…they’ll get an error on compilation: ‘A readonly field cannot be assigned to (except in a constructor or a variable initializer)’


So in summary, the readonly keyword provides us with a facility for ensuring that our constructor injected dependencies are not tampered with by other methods in the class.

Comments (2)

  1. Ranjan says:

    Neat way of doing dependency injection

  2. foo.bar says:

    Have you actually found this to be useful? Can’t you just give your finder a better name like "immutableFinder" and then just trust your programmers to not fiddle around with that variable?

    Readonly fields remind me of singletons where some objects can be instatiated, while others can’t. With readonly fields – you now have to mentally bifurcate your variables into ones that are valid L-values and some that aren’t.

    How do you feel about Singletons being evil?

    http://c2.com/cgi/wiki?SingletonsAreEvil