我有一种情况,我希望自定义代码能够覆盖现有的注册。例如我有一个界面,
public interface IInterface{ int Num {get;set;}
默认情况下解析为,
public class CoreClass: IInterface{...}
(注意,此注册由 SMs Scan() 功能(WithDefaultConventions,SingleImplementationsOfInterface)完成
现在我想要一段自定义代码来加入 SM 初始化过程并用它自己的实现覆盖现有的 IInterface 注册,
public class CustomClass: IInterface {...}
这就是问题所在。如果我通过在我的自定义程序集上执行 Scan() 并使用与上述相同的 SM 约定(WithDefaultConventions、SingleImplementationsOfInterface)来进行此注册,那么在运行时执行 GetInstance 时会出现异常,
No Default Instance defined for PluginFamily IInterface
但是当我通过使用添加覆盖注册时,
x.For<IInterface>().Use<CustomClass>()
这一切都有效。
此外,当我使用以下方式询问容器时,
ObjectFactory.WhatDoIHave()
然后根据注册方法,我得到的结果略有不同。WhatDoIHave() 基本上会向您显示已注册的 PLUGINTYPE。Name 列显示注册的具体类型。当我 Scan() 并且有多个实现时,我会看到找到的具体类型的 .Net 类型名称。但是当我使用 For<>() 方法时,我看到了上面的多个实现,而且在 For<>() 语句中使用的具体类型旁边还有一个 GUID(我假设这表示默认注册?)
现在很多 SO 帖子表明最后一次注册获胜(这是我想要的行为)但我想知道的是这是否仅适用于显式注册(即使用 For<>)。当我 Scan() 时,我可以假设 SM 以更“不确定”的方式行事,并且不保证最后找到的实现获胜还是我错过了什么?
感谢和抱歉冗长的帖子!
编辑:[根据要求提供示例注册码]
ObjectFactory.Initialize(x =>
{
x.AddRegistry<CoreRegistry>();
x.AddRegistry<ClientRegistry>();
});
public class CoreRegistry : Registry
{
public CoreRegistry()
{
//Presentation
Scan(x =>
{
x.AssemblyContainingType<SomeCoreType>();
x.WithDefaultConventions();
x.SingleImplementationsOfInterface();
x.AddAllTypesOf<ConfigurableEntityViewModel>();
});
// Domain
Scan(x =>
{
x.AssemblyContainingType<AnotherCoreType>();
x.WithDefaultConventions();
x.SingleImplementationsOfInterface();
});
...
}
public class ClientRegistry : Registry
{
public ClientRegistry()
{
//Presentation
Scan(x =>
{
x.AssemblyContainingType<SomeClientType>();
x.WithDefaultConventions();
x.SingleImplementationsOfInterface();
});
}
}
所以我希望来自 ClientRegistry 的具体实现(例如 IInterface)将在容器中最后注册,因此将是“默认”注册,并在调用 GetInstance() 时返回。但事实并非如此,它会引发如上所述的错误。