在特定情况下解析构造函数参数

时间:2018-01-04 10:25:41

标签: c# asp.net autofac

我有代码:

public class A
{
    public A(MyService myService)
    {
        // work with myService
    }
}

public class MyService
{
    public MyService(string className)
    {
        // here I want className == "A"
    }
}

MyService作业取决于它初始化的类名。所以我需要在容器配置中做类似

的东西
builder.RegisterType<MyService>()
    .AsSelf()
    .WithParameter(
        (i, c) => i.ParameterType == typeof(string) && i.Name == "className",
        (i, c) =>
        {
            // how can i find typeof(A) here on MyService building?
            return c.GetType().Name;
        });

或在其他地方解决className可靠的问题?

1 个答案:

答案 0 :(得分:0)

您可以创建一个自定义参数来负责创建MyService实例,此参数可以访问应创建MyService的上下文。

new ResolvedParameter(
    (p, i) => p.ParameterType == typeof(MyService),
    (p, i) => new MyService(p.Member.DeclaringType.ToString())
),

为了不自己创建MyService实例,您可以使用当前上下文并要求Autofac使用包含声明类型名称的NamedParameter解析它。

new ResolvedParameter(
    (p, i) => p.ParameterType == typeof(MyService),
    (p, i) => i.Resolve<MyService>(
                  new NamedParameter("className", p.Member.DeclaringType.ToString())
              )
),

您可以使用模块在每次注册中使用此自定义参数

public class MyServiceModule : Module
{
    protected override void AttachToComponentRegistration(
        IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        registration.Preparing += Registration_Preparing;

        base.AttachToComponentRegistration(componentRegistry, registration);
    }

    private void Registration_Preparing(Object sender, PreparingEventArgs e)
    {
        e.Parameters = e.Parameters.Union(new[] {
            new ResolvedParameter(
                (p, i) => p.ParameterType == typeof(MyService),
                (p, i) => i.Resolve<MyService>(
                            new NamedParameter("className", 
                                               p.Member.DeclaringType.ToString())
                          )
            ),
        });
    }
}

并在Autofac中注册您的模块

builder.RegisterModule<MyServiceModule>();

请记住,Preparing事件仅在每次创建实例时触发一次,如果您使用不同的实例生命周期范围(单例等)注册MyService,则className值可能不是预期的那个。