在特定示例中注册简单类型 [英] Registering simple types in a specific example

查看:90
本文介绍了在特定示例中注册简单类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下内容

ClassA具有一个构造函数,该构造函数接受MasterClassstring的实例,并公开类型为string[]的称为Names的属性.

ClassA has a constructor that takes an instance of MasterClass and a string and exposes a property called Names of type string[].

ClassB具有一个采用IJuicePresserIEnumerable<string>的构造函数.

ClassB has a constructor that takes an IJuicePresser and a IEnumerable<string>.

ClassC具有一个采用IEnumerable<string>的构造函数.

ClassC has a constructor that takes an IEnumerable<string>.

我会手动执行以下操作将它们绑在一起.

Manually I would do something like this to tie them together.

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来为我处理这些注册/分辨率?

How can I set up DryIoc to handle these registrations/resolutions for me?

推荐答案

最好将所有这些运行时名称从构造函数移动到相应的方法.但这是按原样匹配的DryIoc设置:

It might be better to move all these run-time names from constructors to corresponding methods. But here is the matching DryIoc setup as-is:

在.NET Fiddle上直播

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;
        }
    }
}

更新:

解释一下该部分:

Update:

Explaining a bit the part with:

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

DryIoc支持不仅使用构造函数进行服务创建,还支持使用静态和实例方法(工厂方法),属性和字段.这是 Wiki主题

DryIoc has support for using not only constructors for service creation, but also static and instance methods (factory methods), properties and fields. Here is the wiki topic.

在上面的示例中,我们将ClassA对象的Names属性用作工厂方法,以将服务类型"string []"注册为服务键名称".

In example above we use Names property of ClassA object as factory method to register service type "string[]" with service key "names".

让我们详细看看:

// 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>()部分.顺便说一句,request参数可用于条件选择工厂.

If you want to register with static factory method, property, field, then you don't need to specify request => ServiceInfo.Of<TFactory>() part. BTW, request parameter can be used for conditional selection of factory.

这篇关于在特定示例中注册简单类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆