如何使用 Unity 一次注入两个实现?
How can I inject two implementations as once with Unity?
我有一个 IConsole
界面,描述了如何将内容写入控制台,以及一个实现,upperCaseConsole
。
IConsole 使用 Unity 在 Foo
class 中注入。
public interface IConsole {
void WriteLine(string text);
}
public class upperCaseConsole: IConsole {
public void WriteLine(string text){
Console.WriteLine(text.ToUpper());
}
}
public class Foo{
private readonly IConsole console;
public Foo(IConsole console){
this.console = console;
}
public void WriteStuff(string stuff){
console.WriteLine(stuff);
}
}
我现在想更改文本写入控制台的方式。我已经很好地将实现与 foo 分离,我可以注入一个新的实现,而不是说 lowerCaseConsole
。
public class lowerCaseConsole: IConsole {
public void WriteLine(string text){
Console.WriteLine(text.ToLower());
}
}
我的问题是,尽管我做了最好的测试,但我不确定 lowerCaseConsole
是否能完成这项工作,我想 运行 两种实现同时进行一段时间。
如何在不复制 Foo
中的所有代码的情况下做到这一点?
我想避免类似的事情:
public class Foo{
private readonly IConsole lowerConsole;
private readonly IConsole upperConsole;
public Foo([Dependency("lower")] IConsole lowerConsole,
[Dependency("upper")] IConsole upperConsole){
this.lowerConsole = lowerConsole;
this.upperConsole = upperConsole;
}
public void WriteStuff(string stuff){
lowerConsole.WriteLine(stuff);
upperConsole.WriteLine(stuff);
}
}
注意:现实生活中的情况是我即将进行数据库更改。我想透明地开始写入新数据库,看看情况如何,但继续写入当前数据库,以防万一。
您可以使用命名注册来注入 IEnumerable<IConsole>
。这种方法可以很容易地扩展为更多的实现……或者您可以轻松地删除其中一个……
container.RegisterType<IConsole, LowerConsole>("LowerConsole");
container.RegisterType<IConsole, UpperConsole>("UpperConsole");
container.RegisterType<IEnumerable<IConsole>, IConsole[]>();
然后 Foo
的构造函数变得有点不同,WriteStuff
方法也...
public Foo(IEnumerable<IConsole> consoles)
{
this.consoles = consoles;
}
public void WriteStuff(string stuff)
{
foreach(var console in consoles)
{
console.WriteLine(stuff);
}
}
一个选择是创建第三个实现,其中包含其他两个的私有成员,并且调用它的 WriteLine
方法只会转发给其他两种类型。
public class BothCaseConsole : IConsole
{
private readonly LowerCaseConsole lcc = new LowerCaseConsole();
private readonly UpperCaseConsole ucc = new UpperCaseConsole();
public void WriteLine(string text)
{
lcc.WriteLine(text);
ucc.WriteLine(text);
}
}
然后把这个类型注入Foo
:
new Foo(new BothCaseConsole()).WriteStuff("Stuff to write");
我有一个 IConsole
界面,描述了如何将内容写入控制台,以及一个实现,upperCaseConsole
。
IConsole 使用 Unity 在 Foo
class 中注入。
public interface IConsole {
void WriteLine(string text);
}
public class upperCaseConsole: IConsole {
public void WriteLine(string text){
Console.WriteLine(text.ToUpper());
}
}
public class Foo{
private readonly IConsole console;
public Foo(IConsole console){
this.console = console;
}
public void WriteStuff(string stuff){
console.WriteLine(stuff);
}
}
我现在想更改文本写入控制台的方式。我已经很好地将实现与 foo 分离,我可以注入一个新的实现,而不是说 lowerCaseConsole
。
public class lowerCaseConsole: IConsole {
public void WriteLine(string text){
Console.WriteLine(text.ToLower());
}
}
我的问题是,尽管我做了最好的测试,但我不确定 lowerCaseConsole
是否能完成这项工作,我想 运行 两种实现同时进行一段时间。
如何在不复制 Foo
中的所有代码的情况下做到这一点?
我想避免类似的事情:
public class Foo{
private readonly IConsole lowerConsole;
private readonly IConsole upperConsole;
public Foo([Dependency("lower")] IConsole lowerConsole,
[Dependency("upper")] IConsole upperConsole){
this.lowerConsole = lowerConsole;
this.upperConsole = upperConsole;
}
public void WriteStuff(string stuff){
lowerConsole.WriteLine(stuff);
upperConsole.WriteLine(stuff);
}
}
注意:现实生活中的情况是我即将进行数据库更改。我想透明地开始写入新数据库,看看情况如何,但继续写入当前数据库,以防万一。
您可以使用命名注册来注入 IEnumerable<IConsole>
。这种方法可以很容易地扩展为更多的实现……或者您可以轻松地删除其中一个……
container.RegisterType<IConsole, LowerConsole>("LowerConsole");
container.RegisterType<IConsole, UpperConsole>("UpperConsole");
container.RegisterType<IEnumerable<IConsole>, IConsole[]>();
然后 Foo
的构造函数变得有点不同,WriteStuff
方法也...
public Foo(IEnumerable<IConsole> consoles)
{
this.consoles = consoles;
}
public void WriteStuff(string stuff)
{
foreach(var console in consoles)
{
console.WriteLine(stuff);
}
}
一个选择是创建第三个实现,其中包含其他两个的私有成员,并且调用它的 WriteLine
方法只会转发给其他两种类型。
public class BothCaseConsole : IConsole
{
private readonly LowerCaseConsole lcc = new LowerCaseConsole();
private readonly UpperCaseConsole ucc = new UpperCaseConsole();
public void WriteLine(string text)
{
lcc.WriteLine(text);
ucc.WriteLine(text);
}
}
然后把这个类型注入Foo
:
new Foo(new BothCaseConsole()).WriteStuff("Stuff to write");