Consider the following code snip where we implement ILogger
with all applications using BaseLogger
. But then we have a scenario where we need to log somewhere specific for a customer, such as a database or to some enterprise App monitor so we have CustomerSpecificLogger
that also implements ILogger
The cTor for CustomerSpecificLogger
requires a type of ILogger be passed in, in this case we want an instance of BaseLogger
passed in to perform both logging functions.
I know how to bind ILogger
with Ninject, but how do you bind two different ILoggers and tell Ninject when to use each?
interface ILogger
{
void Log(string msg);
}
class BaseLogger : ILogger
{
public void Log(string msg)
{
Console.WriteLine(msg);
}
}
class CustomerSpecificLogger : ILogger
{
private ILogger BaseLogger { get; set; }
CustomerSpecificLogger(ILogger baseLogger)
{
BaseLogger = baseLogger;
}
public void Log(string msg)
{
//Log to somewhere specific per customer request
BaseLogger.Log(msg);
}
}
I've tried searching around for this but I'm struggling with what this would be called. So alas, I'm coming up empty handed.
Update If I try to bind both, hoping that it uses some type of index to do the binding, it errors out:
Bind<ILogger>().To<BaseLogger>();
Bind<ILogger>().To<CustomerSpecificLogger>();
Error: More than one matching bindings are available.
Update 2 This is called ContextualBinding in Ninject and is documented here
I think I have this figured out now.
WithConstructorArgument(name, value) sounds like not?
using System;
using System.Reflection;
using Ninject;
using Ninject.Modules;
public interface ILogger
{
void Log(string msg);
}
public class BaseLogger : ILogger
{
public void Log(string msg)
{
Console.WriteLine(msg);
}
}
public class CustomerSpecificLogger : ILogger
{
private ILogger BaseLogger { get; set; }
public CustomerSpecificLogger(ILogger baseLogger)
{
BaseLogger = baseLogger;
}
public void Log(string msg)
{
//Log to somewhere specific per customer request
BaseLogger.Log(msg);
}
}
// kernel.Load() in Program.Main() automatically load and bind this.
public class Bindings : NinjectModule
{
public override void Load()
{
#if true // or some App.config, anything...
Bind<ILogger>().To<BaseLogger>().InSingletonScope();
#else
Bind<ILogger>().To<CustomerSpecificLogger>().InSingletonScope().WithConstructorArgument("baseLogger", new BaseLogger());
#endif
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
var logger = kernel.Get<ILogger>();
logger.Log("Hello!");
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.