在依赖项解析期间获取 class 类型

Get class type during dependency resoluton

为我的 unity 容器注册类型时,我需要将调用 class 的类型传递到已解析对象的构造函数中。

这是 class 我将一些接口注入构造函数的地方。

namespace MyNamespace
{
    internal class ProcessingService: IProcessingService
    {
        private readonly ISomeClass1 someClass1;
        private readonly ISomeClass2 someClass2;

        public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
        {
            this.someClass1 = someClass1;
            this.someClass2 = someClass2;
        }
    }
}

SomeClass2 期望在构造函数中输入:

public class SomeClass2
{
    public SomeClass2(Type type)
    {
        //...
    }
}

这是我的 unity bootstrap class 我设置容器的地方。现在,对于ISomeClass2,解析为SomeClass2时,需要传入ProcessingService的类型。

namespace MyNamespace
{
    public class UnityBootstrap : IUnityBootstrap
    {
        public IUnityContainer Configure(IUnityContainer container)
        {
            return container
                .RegisterType<ISomeClass1, SomeClass1>()
                .RegisterType<ISomeClass2>(new InjectionFactory(fac =>
                {
                    // IMethodBase.GetCurrentMethod().DeclaringType is returning MyNamespace.UnityBootstrap
                    // whereas I need to get MyNamespace.ProcessingService
                    return new SomeClass2(MethodBase.GetCurrentMethod().DeclaringType);
                }));
        }
    }
}

有没有办法使用 InjectionFactory(或我的 Configure 方法中的其他方式)来做到这一点?

恕我直言,这个问题有两种观点:

1) 如果 SomeClass2 将始终使用类型 ProcessingService 那么您可以将类型参数直接传递到 InjectionFactory

container.RegisterType<ISomeClass2>(new InjectionFactory(_ =>
{
    return new SomeClass2(typeof(ProcessingService));
}));

2) 否则,如果类型参数在整个应用程序中不同,您应该考虑向接口 ISomeClass2 添加注册方法并从构造函数中注册类型以强调 dependency/variation.

public interface ISomeClass2
{
    void DoSomething();
    void RegisterProcessingServiceType(Type processingServiceType);
}

public class SomeClass2 : ISomeClass2
{
    private Type _type;

    public void DoSomething()
    {
        if(_type == null)
            throw InvalidOperationException("Register processing service type before doing stuff.");
        // actually do something
    }

    public void RegisterProcessingServiceType(Type serviceType)
    {
        _type = serviceType;
    }
}

internal class ProcessingService: IProcessingService
{
    private readonly ISomeClass1 someClass1;
    private readonly ISomeClass2 someClass2;

    public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
    {
        this.someClass1 = someClass1;
        this.someClass2 = someClass2;
        this.someClass2.RegisterProcessingServiceType(this.GetType());
    }
}

如果您可以控制 ProcessingService,您可以围绕 SomeClass2 创建一个通用包装器,然后使用开放式泛型注册它。但这需要您修改 ProcessingService.

的构造函数
public interface IGenericSomeClass2<T>: ISomeClass2 {}

public class GenericSomeClass2<T>: IGenericSomeClass2<T>
{
    private readonly ISomeClass2 someClass2;
    public GenericSomeClass2()
    {
        this.someClass2 = new SomeClass2(typeof(T));
    }
    // Pass-through implementation
}

public IUnityContainer Configure(IUnityContainer container)
{
    return container
        .RegisterType<ISomeClass1, SomeClass1>()
        .RegisterType(typeof(IGenericSomeClass2<>), typeof(GenericSomeClass2<>));
}

internal class ProcessingService: IProcessingService
{
    private readonly ISomeClass1 someClass1;
    private readonly ISomeClass2 someClass2;

    public ProcessingService(ISomeClass1 someClass1, IGenericSomeClass2<ProcessingService> someClass2)
    {
        this.someClass1 = someClass1;
        this.someClass2 = someClass2;
    }
}

如果您不控制 ProcessingService(或 SomeClass2 的其他消费者),您可以自定义这些消费者的注册。这种方法更具侵入性,因为您必须为每个消费者创建一个注入工厂。

container
    .RegisterType<IProcessingService, ProcessingService>(new InjectionFactory((c, type, name) =>
    {
        return new ProcessingService(c.Resolve<ISomeClass1>(), new SomeClass2(type));
    }));