向所有类型注入具有特定值的字符串参数

Inject string parameter with specific value to all types

给出

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

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

当我解析 classes:

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

那么我如何设置 UnityContainer 以便它在解析任何实现 IFoo 的 class 时将值 "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,因为您无法在没有反射的情况下从 UnityContainer 访问 BuilderStrategy 的集合。

因此您只需将此扩展添加到 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);