在特定示例中注册简单类型 [英] Registering simple types in a specific example
问题描述
请考虑以下内容
ClassA
具有一个构造函数,该构造函数接受MasterClass
和string
的实例,并公开类型为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
具有一个采用IJuicePresser
和IEnumerable<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:
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屋!