1

次のことを考慮してください

ClassAMasterClassには、とのインスタンスを取り、 typestringという名前のプロパティを公開するコンストラクタがあります。Namesstring[]

ClassBと を取るコンストラクタがIJuicePresserありIEnumerable<string>ます。

ClassCを取るコンストラクタがありIEnumerable<string>ます。

手動で、このようなことをしてそれらを結び付けます。

var masterClass = new MasterClass();
var juicePresser = JuicePresser.Create("default");
var classA = new ClassA(masterClass, "string");
var names = classA.Names;
var classB = new ClassB(juicePresser, names as IEnumerable<string>);
var classC = new ClassC(Array.Reverse(names));

これらの登録/解決を処理するように DryIoc を設定するにはどうすればよいですか?

4

1 に答える 1

3

これらすべてのランタイム名をコンストラクターから対応するメソッドに移動する方がよい場合があります。ただし、一致するDryIocセットアップは次のとおりです。

.NET フィドルでライブ

using System;
using System.Collections.Generic;
using System.Linq;
using DryIoc;

public class Program
{
    public static void Main()
    {
        var c = new Container();

        c.Register<MasterClass>();

        c.Register<JuicePresser>(Made.Of(() => JuicePresser.Create("default")));

        // an example how to inject a primitive value: "string" in this case 
        c.Register<ClassA>(made: Parameters.Of.Type<string>(_ => "string"));

        // service key is optional, just to distinguish the list of strings for consumer.
        c.Register<string[]>(
            Made.Of(_ => ServiceInfo.Of<ClassA>(), factory => factory.Names),
            serviceKey: "names"); 

        // register reverse names using ReverseHelper method
        c.Register<string[]>(
            Made.Of(() => ReverseHelper(Arg.Of<string[]>("names"))),
            serviceKey: "reverse-names"); 

        // specify the names and required type (string[]) for injection
        c.Register<ClassB>(made: Parameters.Of.Type<IEnumerable<string>>(typeof(string[]), serviceKey: "names"));

        // specify reverse names for injection
        c.Register<ClassC>(made: Parameters.Of.Type<string[]>(serviceKey: "reverse-names"));

        var classB = c.Resolve<ClassB>();
        var classC = c.Resolve<ClassC>();


        Console.WriteLine(string.Join(" - ", classB.Names.ToArray()));
        // outputs: a - string - z

        Console.WriteLine(string.Join(" - ", classC.Names));
        // outputs: z - string - a
    }

    public static T[] ReverseHelper<T>(T[] target) {
        Array.Reverse(target);
        return target;
    }

    public class MasterClass {}

    public class JuicePresser 
    {
        public readonly string Name;

        private JuicePresser(string name) { Name = name; }

        public static JuicePresser Create(string name) 
        {
            return new JuicePresser(name);
        }
    }

    public class ClassA 
    {
        public readonly string[] Names;

        public ClassA(MasterClass master, string name) {
            Names = new[] { "a", name, "z" }; // for example
        }
    }

    public class ClassB 
    {
        public readonly JuicePresser Presser;   
        public readonly IEnumerable<string> Names;

        public ClassB(JuicePresser presser, IEnumerable<string> names) {
            Presser = presser;
            Names = names;
        }
    }

    public class ClassC
    {

        public readonly string[] Names;

        public ClassC(string[] names) {
            Names = names;
        }
    }
}

アップデート:

次の部分を少し説明します。

c.Register<string[]>(
    Made.Of(_ => ServiceInfo.Of<ClassA>(), factory => factory.Names),
    serviceKey: "names"); 

DryIoc は、サービス作成のためのコンストラクターだけでなく、静的メソッドとインスタンスメソッド (ファクトリー メソッド)、プロパティ、およびフィールドの使用もサポートしています。ここにウィキのトピックがあります。

上記の例では、オブジェクトNamesのプロパティをファクトリ メソッドとして使用して、サービス タイプ「string[]」をサービス キー「names」に登録します。ClassA

詳しく見てみましょう:

// Registering service of ClassA. It means that it can be resolved / injected directly,
// or/and we can use it as a factory for resolving further services
c.Register<ClassA>(made: Parameters.Of.Type<string>(_ => "string"));

// Registering service of type "string[]"
c.Register<string[]>(
    // Made.Of enables specifying factory method to use for "string[]" resolution, instead default constructor selection rules.
    Made.Of(
        // 1) Specifying what factory object should be used,
        // Here we say to use ClassA service registered in container 
        requestNotUsedHere => ServiceInfo.Of<ClassA>(), 

        // 2) Specify that Names property of resolved ClassA object
        // should be used for "string[]" resolution
        classA => classA.Names),

    // As the "string[]" is not very distinctive (unique) service type 
    // (you might register other "string[]" with different meaning), 
    // we identify the names with "names" service key. So when injected or
    // resolved, you need to specify the service key in addition to type.
    serviceKey: "names");

request => ServiceInfo.Of<TFactory>()静的ファクトリ メソッド、プロパティ、フィールドで登録する場合は、 partを指定する必要はありません。ところで、requestパラメータは工場の条件選択に使用できます。

于 2016-06-20T14:12:13.630 に答える