C# 使用Unity解析类和接口的层次结构

C# 使用Unity解析类和接口的层次结构,c#,unity-container,C#,Unity Container,(从内存中写入) 尝试在SOLID中执行I。给定 public interface ISettingsReader { } public interface ISettingsWriter : ISettingsReader { } public class SettingsManager : ISettingsWriter { } myContainer.RegisterType<ISettingsWriter, SettingsManager>(); 我会假设,因为我已经

(从内存中写入)

尝试在SOLID中执行I。给定

public interface ISettingsReader
{
}

public interface ISettingsWriter : ISettingsReader
{
}

public class SettingsManager : ISettingsWriter
{
}

myContainer.RegisterType<ISettingsWriter, SettingsManager>();
我会假设,因为我已经注册了
SettingsManager
作为我的
ISettingsWriter
,并且
ISettingsWriter
继承了
ISettingsReader
,Unity会足够聪明地发现
setingsManager
也是
ISettingsReader

为什么我必须明确地做:

myContainer.RegisterType<ISettingsReader, SettingsManager>();
myContainer.RegisterType<ISettingsWriter, SettingsManager>();
myContainer.RegisterType();
myContainer.RegisterType();

两种基本类型都需要显式注册的原因是Unity需要明确知道在解析ISettingsReader时需要返回什么。您正在寻找的情况是接口之间的隐含转换,Unity不支持这种转换

作为隐式转换有问题的一个例子,接口可以有任意数量的不同实现:

public class SettingsContainer : ISettingsReader { ... }
public class SettingsThing2 : ISettingsReader { ... }
您可以设置您的注册,以便
IEnumerable
(或某些其他集合类型)自动解析为所有已注册的
ISettingsReader
实现。或者,您可能只需要一个
ISettingsReader
,Unity不知道该给您哪一个。我并不是说这是一个好的设计,但考虑到C语言的限制,这是可能的


Unity需要明确地知道在尝试解决它时需要哪个ISettingsReader实现。它不会尝试为您在接口之间执行强制转换。

当然,它应该足够聪明,以确定SettingsManager是ISettingsWriter!这是我注册的。是的,ISettingsReader可能有许多实现。但我只注册了一个——间接注册。如果我明确地注册了第二个,那么我希望它会被解决。如果我有一个由100个接口组成的链,并且只有一个实现,那么我是否需要注册其中的每一个接口,以便将它们用作DI?这没有任何意义。@HristoYankov对不起,这部分答案完全不清楚,我会修改它。尽管我认为您的回答强调了,如果您还没有注册一些东西,它怎么知道有一个类型实现?据我所知,Unity是一个包含直接类型映射的容器,它不进行隐式转换——看起来你在寻找它不支持的东西。但问题是,它是注册的<代码>B:C',A:B`->
A:C
如果(A是C){}
将产生
true
。我相信Unity可以检查它注册的实现,至少可以查找第一个实现
C
,不是吗?但你可能是对的,也许Unity根本不支持如此深刻的决心。@HristoYankov我觉得这就是你想问的问题,我认为这是一个非常好的观点。我无法指出设计者选择不进行此检查的确切原因,但我认为(我的观点)当您必须显式地将每个接口注册到每个实现时,它为您提供了更大的灵活性。否则,您可能依赖于依赖项注册的顺序,这不是一个好的场景,因为它可能会导致非常微妙的bug。
public class SettingsContainer : ISettingsReader { ... }
public class SettingsThing2 : ISettingsReader { ... }