使用Ninject,我可以执行以下操作:
Bind<ILogger>().ToMethod(context =>
{
// Get type info
var type = context.Request.Target.Member.DeclaringType;
var logger = new ConcreteLogger(type);
Kernel.Get<IFoo>().DoFoo(logger);
return logger;
});
如何使用Autofac做到这一点?
这是我的代码:
builder.Register(context => {
var type = ?????
var logger = new ConcreteLogger(type);
context.Resolve<IFoo>().DoSomething(logger);
return logger;
}).As<ILogger>();
我可以在调试器中看到context
实际上是Autofac.Core.Resolving.InstanceLookup
具有成员的类型,ComponentRegistration.Target
但是由于InstanceLookup
属于内部类,所以无法访问它。
看来我可以做到这一点,但并没有为我提供需要这种注入类型的类的类型信息:
builder.Register(context => {
var lookup = c as IInstanceLookup;
var target = lookup.ComponentRegistration.Target as ComponentRegistration;
var logger = new ConcreteLogger(target.Activator.LimitType);
context.Resolve<IFoo>().DoSomething(logger);
return logger;
}).As<ILogger>();
您需要的是基于“父”组件注入一个组件。使用Autofac,您可以注册组件,而这些组件并不知道谁需要它们。
顺便说一句,您可以通过实现自定义Module来完成所需的操作。范例:
public class TestModule : Module
{
protected override void AttachToComponentRegistration(
IComponentRegistry componentRegistry,
IComponentRegistration registration)
{
registration.Preparing += (sender, e) =>
{
Parameter parameter = new ResolvedParameter(
(pi, c) =>
{
return pi.ParameterType == typeof(ILogger);
}, (pi, c) =>
{
var p = new TypedParameter(typeof(Type),
e.Component.Activator.LimitType);
return c.Resolve<ILogger>(p);
});
e.Parameters = e.Parameters.Union(new Parameter[] { parameter });
};
base.AttachToComponentRegistration(componentRegistry, registration);
}
}
并像这样注册模块:
builder.RegisterModule<TestModule>();
这样,每次解析一个组件时,它将添加一个新参数,该参数知道要构造的类型以创建ILogger
依赖项。
请注意,通过执行此操作,您可能会拥有专属的依赖关系:一种为组件构建但用于另一个组件的依赖关系。如果您的ILogger
注册具有不同的范围,例如单例范围,则可能会发生这种情况。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句