给定

interface IFoo ...
class MyClass1 : IFoo
{
    public MyClass1(string id) ...
}

class MyClass2 : IFoo
{
    public MyClass2(string id) ...
}
//new classes will be added


当我解析课程时:

UnityContainer container = ...;
container.Resolve(typeThatImplementsIFoo);


那么,在解决实现IFoo的任何类时,如何设置UnityContainer以便将值"123"注入到任何ctor参数"string id"

最佳答案

如果您编写了一个自定义BuilderStrategy,它将覆盖类的构造函数中的输入参数,则可以执行此操作。

我编写了一个用于简化的测试类。它们与您的班级相似:

    public interface IFoo {}

    public class MyClass : IFoo
    {
        public string Id;

        public MyClass(string id)
        {
            Id = id;
        }
    }

    public class MyClass2 : IFoo
    {
        public string Id;

        public MyClass2(string id)
        {
            Id = id;
        }
    }


它们是自定义BuilderStrategy和自定义UnityContainerExtension

    public class UnityExtension<TInterface> : UnityContainerExtension
    {
        private readonly string _paramName;
        private readonly object _paramValue;

        public UnityExtension(string paramName, object paramValue)
        {
            _paramName = paramName;
            _paramValue = paramValue;
        }

        protected override void Initialize()
        {
            var strategy = new BuildStrategy<TInterface>(_paramName, _paramValue);
            Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
        }
    }

    public class BuildStrategy<TInterface> : BuilderStrategy
    {
        private readonly string _paramName;
        private readonly object _paramValue;

        public BuildStrategy(string paramName, object paramValue)
        {
            _paramName = paramName;
            _paramValue = paramValue;
        }

        public override void PreBuildUp(IBuilderContext context)
        {
            if (typeof(TInterface).IsAssignableFrom(context.OriginalBuildKey.Type))
            {
                context.AddResolverOverrides(new ParameterOverride(_paramName, _paramValue));
            }
        }
    }


您需要自定义UnityContainerExtension,因为如果没有反射就无法从BuilderStrategy访问UnityContainer的集合。

因此,您只需要将此扩展名添加到UnityContainer并尝试解析所需的类型:

    var container = new UnityContainer();
    container.AddExtension(new UnityExtension<IFoo>("id", "123"));

    var class1 = container.Resolve<MyClass>();
    var class2 = container.Resolve<MyClass2>();

    // show 123
    Console.WriteLine(class1.Id);

    // show 123
    Console.WriteLine(class2.Id);

10-08 02:58