如何获取在激活时已将激活对象注入到其中的实例

本文关键字:激活 注入 对象 实例 何获取 获取 | 更新日期: 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;
    }
}