考虑以下代码片段,我们使用ILogger
对所有应用程序实施BaseLogger
。但是,我们有一个场景,我们需要记录特定于客户的某个地方,例如数据库或某个企业应用程序监视器,因此我们CustomerSpecificLogger
也实现了ILogger
CustomerSpecificLogger
的cTor需要传入一种ILogger,在这种情况下,我们希望传入BaseLogger
的实例来执行两种日志记录功能。
我知道如何将ILogger
绑定到Ninject,但是如何绑定两个不同的ILogger并告诉Ninject何时使用它们?
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);
}
}
我试图四处寻找,但我正在努力解决这个问题。唉,我空手而归。
更新 如果我尝试绑定两者,希望它使用某种类型的索引来进行绑定,则会出错:
Bind<ILogger>().To<BaseLogger>();
Bind<ILogger>().To<CustomerSpecificLogger>();
错误:有多个匹配的绑定可用。
更新2 这在Ninject中称为ContextualBinding,并记录在案here
我想我现在已经弄明白了。
答案 0 :(得分:0)
WithConstructorArgument(名称,值)听起来不是吗?
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!");
}
}