如何获取在激活时注入激活对象的实例?

时间:2016-02-08 12:40:01

标签: c# dependency-injection ninject

我正在尝试利用Ninject帮助我建立一个可能的服务类树。我想使用ILogger注入InCallScope实例,因此任何子服务类都将使用相同的记录器。

记录器实现有一个名为RootService的属性,它指向使用记录器的最上层服务类实例。我根据它来自哪个服务类对记录的事件进行分类时会使用它的信息(子类不会定义另一个“日志范围”,因此我使用InCallScope)。

我是否可以微调ILogger Ninject绑定,以便在激活ILogger实例时可以进行回调,并且我也有实例,最近它被注入了?所以我可以设置记录器的RootService属性。

1 个答案:

答案 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;
    }
}