解析 DryIoc DI-Container 中的命名服务

问题描述

考虑以下两个类:

public class Number
{
    public int Value { get; set; }
}

public class Multiplier
{
    private readonly Number first;
    private readonly Number second;

    public Multiplier(Number first,Number second)
    {
        this.first = first;
        this.second = second;
    }

    public int Multiply() => this.first.Value * this.second.Value;
}

Multiplier 类依赖于 Number 的两个实例。我想使用 DryIoc DI-Container 将它们作为命名服务注入。执行此操作的代码如下所示:

var container = new Container();

container.RegisterInstance(new Number{Value = 2},serviceKey:"first");
container.RegisterInstance(new Number{Value = 4},serviceKey:"second");
container.Register<Multiplier>();

var consumer = container.Resolve<Multiplier>();

Console.WriteLine(consumer.Multiply());

代码失败并出现 DryIoc.ContainerException调用 Resolve 时),因为注册的实例无法解析为构造函数参数。我的问题基本上是:有什么方法可以让我指定哪个命名的 serviceKey 应该解析为哪个构造函数参数?

在 MEF 中,我将执行以下操作来实现此目的:

[Export(typeof(Multiplier))]
public class Multiplier
{
    private readonly Number first;
    private readonly Number second;

    [ImportingConstructor]
    public Multiplier([Import("first")]Number first,[Import("second")]Number second)
    {
        this.first = first;
        this.second = second;
    }

    public int Multiply() => this.first.Value * this.second.Value;
}

然后使用服务名称导出依赖项:

var container = new CompositionContainer(someCatalog);
container.ComposeExportedValue("first",new Number{Value = 2});
container.ComposeExportedValue("second",new Number{Value = 4});

var multi = container.GetExport<Multiplier>();

我如何使用 DryIoc 做到这一点?

解决方法

首先,您可以重复使用带有 DryIoc.MefAttributedModel.dll 扩展名的相同 MEF 代码。

单独使用 DryIoc,您需要指定参数名称(或类型,或位置)与 servicKey 之间的映射:

var container = new Container();

container.RegisterInstance(new Number {Value = 2},serviceKey:"first");
container.RegisterInstance(new Number {Value = 4},serviceKey:"second");

container.Register<Multiplier>(made: Parameters.Of
    .Name("first",serviceKey: "first")
    .Name("second",serviceKey: "second"));

var consumer = container.Resolve<Multiplier>();

此处有更多详细信息:https://github.com/dadhi/DryIoc/blob/master/docs/DryIoc.Docs/SpecifyDependencyAndPrimitiveValues.md#complete-example-of-matching-the-parameter-name-to-the-service-key