I'm working on a legacy code base that seriously needs refactoring towards SOLID principles. We are adding the Simple Injector dependency injection container to the mix as a first step.
For one of the registrations I need something very much like the RegisterConditional example for Log4Net, i.e:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
Difference is that I want to inject an instance returned by a factory method that takes the c.Consumer.ImplementationType as input:
container.Register???(
typeof(ILogger),
c => LoggerProvider.GetLogger(c.Consumer.ImplementationType),
Lifestyle.Transient);
Can this be accomplished in Simple Injector?
I have read the answer to a similar question, but that does not suffice. The ImplementationType needs to be handed to the instance factory.
For the time being, I will implement a Logger<TParent> and use that in the RegisterConditional call:
public class Logger<TParent> : ILogger
{
private readonly ILogger _decoratedLogger;
public Logger()
{
_decoratedLogger = Logger.GetLogger(typeof(TParent));
}
}
Can this be accomplished in Simple Injector?
Yes and no.
No, this isn't supported using the RegisterConditional
and that's because Simple Injector tries to push you towards registering types, so it can verify and diagnose your object graph as much as possible. Preferred way is to create a proxy class much as is explained here. It basically explains your current solution, but has a Logger<T>
that inherits from LogImp
instead, since that leads to a simpler solution.
Yes, this is possible, but you'll have to revert to using a custom IDependencyInjectionBehavior
as explained here (the example is for Serilog, but can be easily rewritten to log4net). The first method however is preferred if possible.