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
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...
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.
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.
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.
As it was written when the . NET Framework 3.5 was released, it was the first Dependency Injection framework to support lamda registrations.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With