1

我有一种情况,我希望自定义代码能够覆盖现有的注册。例如我有一个界面,

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() 时返回。但事实并非如此,它会引发如上所述的错误。

4

1 回答 1

1

我相信最后总是获胜也适用于 WithDefaultConventions。就扫描而言,我不知道是否可以保证始终以相同的顺序扫描程序集。我不确定它是否首先按文件名对程序集进行排序,或者执行一些其他逻辑,或者只是依赖于操作系统返回文件夹中文件的顺序。

我们在尝试使用 WithDefaultConventions 时遇到了很多问题,以至于我们已经禁止在我的公司使用它,并要求开发人员创建具有显式注册的注册表。

此外, SingleInterfaceImplementations似乎可能存在错误。我自己没有使用过这种方法,所以我不确定它是否应该将你的 IInterface 连接到 CustomClass。我知道 WithDefaultConventions 不会那样做。

最后一点;你没有显示你的扫描码。如果您多次使用 Initialize,它将从 StructureMap 中清除任何以前的注册。我们有一些问题,我们的一些注册表试图扫描和添加特定接口,但因为他们正在执行初始化,它清除了应用程序初始化。我们现在只允许从注册表中进行配置。

于 2013-09-05T12:32:30.150 回答