如何获取在激活时已将激活对象注入到其中的实例
本文关键字:激活 注入 对象 实例 何获取 获取 | 更新日期: 2023-09-27 18:33:44
我正在尝试利用Ninject
来帮助我建立一个可能的服务类树。我想使用 InCallScope
注入一个 ILogger
实例,以便任何子服务类都使用相同的记录器。
记录器实现有一个名为 RootService
的属性,它将指向使用记录器的最上层服务类实例。在根据记录的事件来自哪个服务类对记录的事件进行分类时,我会使用它中的信息(子类不会定义另一个"日志范围",因此我使用 InCallScope
)。
我可以微调 ILogger
Ninject 绑定,以便在激活ILogger
实例时进行回调,并且我也有最近注入的实例?因此,我可以在那里设置记录器的RootService
属性。
有一个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;
}
}