I am currently in the process of removing Ninject from my project, and moving to using Simple Injector but there is one thing that I can not get working properly.
For my logging, in the registering of services, I was previously able to pass in a parameter into my logging class as such
_kernel.Bind<ILogger>().To<Logger>()
.WithConstructorArgument("name",
x => x.Request.ParentContext.Request.Service.FullName);
I am looking for a way to recreate this in Simple Injector. So far I have everything else working but this. I can get the logging to work, albeit without having the correct logger names being shown, by doing the following:
_container.Register<ILogger>(() => new Logger("test"));
Anyone got any experience in doing anything similar?
That registration is a form of context based injection. You can use one of the RegisterConditional
overloads for this.
RegisterConditional
however does not allow the use of factory methods to construct a type. So you should create a generic version of your Logger
class, as follows:
public class Logger<T> : Logger
{
public Logger() : base(typeof(T).FullName) { }
}
You can register it as follows:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);
But please do read this Stackoverflow question (and my answer) and question yourself if you aren't logging too much.
Context based injection is now supported in Simple Injector 3 by using the RegisterConditional
method. For example to inject a Logger into Consumer1 and a Logger into Consumer2, use the RegisterConditional overload that accepts a implementation type factory delegate as follows:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);
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