如何在激活时获取激活对象已注入的实例?
How to get the instance into which the activated object has been injected at activation time?
我正在尝试利用 Ninject
来帮助我建立一个可能的服务树 classes。我想使用 InCallScope
注入一个 ILogger
实例,这样任何子服务 class 都会使用相同的记录器。
记录器实现有一个名为 RootService
的 属性,它将指向使用记录器的最上层服务 class 实例。在根据它来自哪个服务 class 对记录的事件进行分类时,我会使用它的信息(子 classes 不会定义另一个 "log scope",因此我使用 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
不提供对 "parent" 实例的访问,因此您只能访问它注入的类型,而不能访问实例。
此外,如果这就足够了,则无需实际使用 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;
}
}
我正在尝试利用 Ninject
来帮助我建立一个可能的服务树 classes。我想使用 InCallScope
注入一个 ILogger
实例,这样任何子服务 class 都会使用相同的记录器。
记录器实现有一个名为 RootService
的 属性,它将指向使用记录器的最上层服务 class 实例。在根据它来自哪个服务 class 对记录的事件进行分类时,我会使用它的信息(子 classes 不会定义另一个 "log scope",因此我使用 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
不提供对 "parent" 实例的访问,因此您只能访问它注入的类型,而不能访问实例。
此外,如果这就足够了,则无需实际使用 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;
}
}