如何使用serviceKey匹配parameter.name解析多个依赖?

How do you resolve multiple dependencies using serviceKey to match parameter.name?

我想知道如何让 DryIoc 解析 ExampleClass 上的 ITest?

这是将参数名称与服务密钥匹配,因为有多个注册可以找到正确的服务。

   public class Program
    {
        public void Main()
        {
            var container = new Container();
            
            container.Register<ITest, A>(serviceKey: "a");
            container.Register<ITest, B>(serviceKey: "b");
            container.Register<ExampleClass>();

            var example = container.Resolve<ExampleClass>();
        }
    }
    
    public interface ITest { }
    public class A : ITest { }
    public class B : ITest { }
    public class ExampleClass
    {
        public ExampleClass(ITest a, ITest b)
        {
        }
    }

使用Parameters.Ofhttps://www.fuget.org/packages/DryIoc.dll/4.2.5/lib/netstandard2.0/DryIoc.dll/DryIoc/Parameters

public class Program 
{ 
    public void Main() 
    { 
        var c = new Container();
        c.Register<ITest, A>(serviceKey: "a");
        c.Register<ITest, B>(serviceKey: "b");
        c.Register<ExampleClass>(made:
            Made.Of(parameters: Parameters.Of
                .Name("a", serviceKey: "a")
                .Name("b", serviceKey: "b")));
        var example = c.Resolve<ExampleClass>(); 
    }
}

您也可以省略 Made.Of(parameters:,因为 Parameters.Of 返回的 ParameterSelector 可以隐式转换为 Made:

        c.Register<ExampleClass>(made:
            Parameters.Of
                .Name("a", serviceKey: "a")
                .Name("b", serviceKey: "b"));

您可以在不显式列出参数的情况下将参数名称与服务密钥应用更通用的匹配,但考虑到您稍后将添加非键控参数,它会更加脆弱:

        c.Register<ExampleClass>(made:
            Parameters.Of.Details(
                (req, parInfo) => ServiceDetails.Of(serviceKey: parInfo.Name)));

另一个类型安全的选项是通过描述其位置参数的委托表达式 (Linq.Expressions.Expression<T>) 直接指定构造函数 - 此选项将在构造函数更改时通知您编译错误:

        c.Register<ExampleClass>(made:
            Made.Of(() =>
                new ExampleClass(
                    Arg.Of<ITest>(serviceKey: "a"),
                    Arg.Of<ITest>(serviceKey: "b"))));

以上方法适用于具体的注册,但同样可以在容器级别使用规则来完成:

var c = new Container(rules =>
    rules.With(parameters:
        Parameters.Of.Details(
            (req, parInfo) => req.ServiceType == typeof(ExampleClass) 
                ? ServiceDetails.Of(serviceKey: parInfo.Name) 
                : null)
));

注意:最后一个选项会影响性能,因为需要为所有注册检查规则。

可以应用相同的方法来使用 PropertiesAndFields.Of.

指定 属性 注入