在Autofac中注册lambda期间访问上下文信息?

时间:2016-04-21 11:00:55

标签: c# inversion-of-control autofac

使用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>();

1 个答案:

答案 0 :(得分:1)

您需要的是基于“parent”组件注入组件。使用 Autofac ,您可以注册组件,这些组件不知道谁需要它们。

顺便说一句,您可以通过实施自定义模块来执行您想要的操作。例如:

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依赖项。

请注意,通过执行此操作,您可能拥有captive dependency:为组件构建的依赖项,但用于另一个组件。如果您的ILogger注册具有不同的范围,例如单一范围,则会发生这种情况。