结构图 - 覆盖注册

时间:2012-12-17 17:03:51

标签: c# dependencies registry structuremap code-injection

是否可以在注册表中注册接口,然后“重新注册”它以覆盖第一次注册?

即:

For<ISomeInterface>().Use<SomeClass>();
For<ISomeInterface>().Use<SomeClassExtension>();

我在运行时想要的是当我要求SomeClassExtension时我的对象工厂返回ISomeInterface

提前致谢!

2 个答案:

答案 0 :(得分:2)

好消息,我发现是的。这完全取决于注册表规则添加到对象工厂容器的顺序。因此,如果您正在使用多个注册表类,则需要找到一种方法来优先将它们添加到容器中。

换句话说,不是使用以错误的顺序获取所有.LookForRegistries()类的Registry,而是尝试找到所有Registry个文件,按照您想要的顺序设置它们并将它们手动添加到对象工厂容器中:

    ObjectFactory.Container.Configure(x => x.AddRegistry(registry));

这样,您就可以完全控制自己想要的规则。

希望有所帮助:)

答案 1 :(得分:2)

当我需要在SpecFlow测试中覆盖注册表的某些部分时,我只想添加我的问题解决方案。

我在搜索中很早就找到了这个帖子,但它并没有真正帮助我找到解决方案,所以我希望它能帮到你。

我的问题是“StoreRegistry”中的“DataContext”(由应用程序使用)使用“HybridHttpOrThreadLocalScoped”,我在测试中需要它是“Transient”。

The code looked like this:
[Binding]
public class MySpecFlowContext
{    
...
    [BeforeFeature]
    private static void InitializeObjectFactories()
    {
        ObjectFactory.Initialize(x =>
        {
            x.AddRegistry<StoreRegistry>();
            x.AddRegistry<CommonRegistry>();
        });
    }   
}

要覆盖范围设置,您需要在注册中明确设置它。 覆盖需要低于被覆盖的覆盖

The working code looks like this:
[Binding]
public class MySpecFlowContext
{    
...
    [BeforeFeature]
    private static void InitializeObjectFactories()
    {
        ObjectFactory.Initialize(x =>
        {
            x.AddRegistry<StoreRegistry>();
            x.AddRegistry<CommonRegistry>();
            x.AddRegistry<RegistryOverrideForTest>();
        });
    }    

    class RegistryOverrideForTest : Registry
    {
        public RegistryOverrideForTest()
        {
             //NOTE: type of scope is needed when overriding the registered classes/interfaces, when leaving it empty the scope will be what was registered originally, f ex "HybridHttpOrThreadLocalScoped" in my case. 
            For<DataContext>()
                .Transient()
                .Use<DataContext>()
                .Ctor<string>("connection").Is(ConnectionBuilder.GetConnectionString());
        }
    }
}