Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor Injection Alternatives (Castle Windsor)

I like Constructor injection for dependency injection. It forces a clear declaration of concerns from a type and helps with testability.

I like Constructor injection, in most places...

Logging as an example where I do not like it. If I have a base class from which many other classes inherit, and I want all of those classes to use an instance of my ILogger (or whatever), and I don't want a static factory (Logger.Instance)...I don't want to have to declare a constructor on every sub-class that takes an ILogger.

So, I could have my base class declare the logger as a Property and have it injected that way

public class MyBaseClass 
{
   public ILogger Logger { get; set; }
}

...but

  1. That doesn't assure me that Logger actually gets injected and is not null.
  2. I don't like having ILogger with a public set

So...what other options do I have? (I'm using Castle Windsor).

I've contemplated making an interface

public interface IInitializable<T>
{
    void Initialize(T instance); 
}

public class MyBaseClass : IInitializable<ILogger>, ...could have other IInitializables too...
{
   protected ILogger Logger { get; private set; }

   public void Initialize(ILogger instance) 
   { 
         Logger = instance;
   }
}

Then having a facility on my container that automatically calls all implementations of IInitializable<T> upon type construction...

But I'm wondering what other peoples' thoughts are before I go that route...

like image 725
Jeff Avatar asked Dec 09 '10 17:12

Jeff


People also ask

What is Castle Windsor dependency injection?

Introduction. Dependency Injection (DI) is an established design pattern describing how objects acquire their dependencies. This pattern is often facilitated by an Inversion of Control (IoC) container, which is used at runtime. to resolve and inject dependencies as objects are instantiated.

What is the limitation of constructor injection?

The main disadvantage to Constructor Injection is that if the class you're building is called by your current application framework, you might need to customize that framework to support it. Some frameworks assume that your classes will have a parameterless constructor.

What is the best IoC container for C#?

You can waste days evaluating IOC containers. The top ones are quite similar. There is not much in this, but the best ones are StructureMap and AutoFac. At SSW we use Autofac on most projects.

When was .NET dependency injection introduced?

As it was written when the . NET Framework 3.5 was released, it was the first Dependency Injection framework to support lamda registrations.


2 Answers

You're overcomplicating this. The recommended and documented pattern to inject ILogger is to have NullLogger.Instance as default (i.e. a null object pattern) and make the Logger an optional dependency. There is nothing wrong with having a public setter for the logger. Using a custom IInitializable like the one you show will likely only complicate things and not contribute any real value.

I'll copy the sample from the documentation here for easy reference:

using Castle.Core.Logging;

public class CustomerService
{
   private ILogger logger = NullLogger.Instance;

   public CustomerService()
   {
   }

   public ILogger Logger
   {
      get { return logger; }
      set { logger = value; }
   }

   // ...
}

EDIT: it seems the question is actually about having different logger implementations depending on the context (which has little to do with the original question). If that's the case, use service overrides or handler selectors.

like image 65
Mauricio Scheffer Avatar answered Sep 28 '22 07:09

Mauricio Scheffer


In your case i would use property injection.

Property injection can be switched to mandatory as explained here: http://www.mail-archive.com/[email protected]/msg08163.html

like image 25
Gregor Slavec Avatar answered Sep 28 '22 09:09

Gregor Slavec