我正在尝试利用Ninject
帮助我建立一个可能的服务类树。我想使用ILogger
注入InCallScope
实例,因此任何子服务类都将使用相同的记录器。
记录器实现有一个名为RootService
的属性,它指向使用记录器的最上层服务类实例。我根据它来自哪个服务类对记录的事件进行分类时会使用它的信息(子类不会定义另一个“日志范围”,因此我使用InCallScope
)。
我是否可以微调ILogger
Ninject绑定,以便在激活ILogger
实例时可以进行回调,并且我也有实例,最近它被注入了?所以我可以设置记录器的RootService
属性。
答案 0 :(得分:1)
有OnActivation
绑定扩展,它是一个回调,在ILogger
实例化时执行。
所以你可以做到以下几点:
public class Test
{
[Fact]
public void Foo()
{
var kernel = new StandardKernel();
kernel.Bind<Service>().ToSelf();
kernel.Bind<Logger>().ToSelf()
.OnActivation((ctx, logger) =>
logger.Initalize(ctx.Request.Target.Member.DeclaringType));
var service = kernel.Get<Service>();
service.Logger.RootService.Should().Be(typeof(Service));
}
}
public class Logger
{
public Type RootService { get; private set; }
public void Initalize(Type rootService)
{
this.RootService = rootService;
}
}
public class Service
{
public Logger Logger { get; private set; }
public Service(Logger logger)
{
Logger = logger;
}
}
但是,IContext
不提供对“父”实例的访问,因此您只能访问它注入的类型,而不能访问实例。
此外,如果这应该足够了,不需要实际使用OnActivation
扩展名,你也应该能够这样做:
public class Test
{
[Fact]
public void Foo()
{
var kernel = new StandardKernel();
kernel.Bind<Service>().ToSelf();
kernel.Bind<Logger>().ToSelf()
.WithConstructorArgument(
typeof(Type),
ctx => ctx.Request.Target.Member.DeclaringType);
var service = kernel.Get<Service>();
service.Logger.RootService.Should().Be(typeof(Service));
}
}
public class Logger
{
private readonly Type _rootService;
public Logger(Type rootService)
{
_rootService = rootService;
}
public Type RootService
{
get { return _rootService; }
}
}
public class Service
{
public Logger Logger { get; private set; }
public Service(Logger logger)
{
Logger = logger;
}
}