2013-11-02 103 views
1

我正在使用StructureMap 2.6.4.0。我使用它的主要目标是简化我的测试。根据StructureMap文档(here),它对于临时模拟注入具有很好的功能(ObjectFactory.Inject <>())。ResetDefaults()方法在StructureMap中不起作用

纠正我,如果我错了,但这里是我该功能的理解:

  1. 您有映射到其接口的所有“真实”的实施有你的容器配置的代码在一个地方。
  2. 在每次测试运行之前,根据应用程序的相同代码初始化ObjectFactory。
  3. 如果任何测试需要使用“测试”来替换某个“真实”实现,那么它会在ObjectFactory上使用Inject方法注入“test”implpementation。
  4. 要恢复原始映射并删除注入模拟,您需要调用ResetDefaults()。

而我的问题是,在第4步。

这里是一个代码示例,该数字我的问题:

public interface IValueProvider 
{ 
    string GetValue(); 
} 

public class ValueProvider : IValueProvider 
{ 
    public string GetValue() 
    { 
     return "Value provider"; 
    } 
} 

public class TestValueProvider : IValueProvider 
{ 
    public string GetValue() 
    { 
     return "Test value provider"; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     ObjectFactory.Initialize(x => x.For<IValueProvider>().Use<ValueProvider>()); 

     var valueProvider = ObjectFactory.GetInstance<IValueProvider>(); 
     Console.WriteLine(valueProvider.GetValue()); 
     // I will see expected "Value provider" 


     ObjectFactory.Inject<IValueProvider>(new TestValueProvider()); 
     valueProvider = ObjectFactory.GetInstance<IValueProvider>(); 
     Console.WriteLine(valueProvider.GetValue()); 
     // I will see expected "Test value provider" 


     ObjectFactory.ResetDefaults(); 
     valueProvider = ObjectFactory.GetInstance<IValueProvider>(); 
     Console.WriteLine(valueProvider.GetValue()); 
     // I will see NOT expected "Test value provider". 
     // Doesn't ResetDefaults() have to restore a ValueProvider implementation? 
    } 
} 

所以,可能有人告诉我,我错了?或者它可能是StructureMap中的一个错误?

回答

1

ResetDefaults()方法将profile切换为String.Empty。你的情况已经是这样了。这并不会删除通过Inject<T>(T object)注册的插件类型。

Inject<T>(T object)方法注册对象作为默认为PluginType“T”。换句话说,它会覆盖您当前的默认值,即具体类型ValueProvider

StructureMap的文档日期,所以我的猜测是,在早期版本中它的工作它的文档中定律描述的方式,但已不再如此。

只有当你想覆盖配置的插件类型的在运行时的默认设置或使用StructureMap配置文件,以便使用Inject<T>(T object)方法。

StructureMap确实提供了一些方法来从容器中删除“弹出”类型。其中之一是:

ObjectFactory.Model.EjectAndRemoveTypes(match =>    
      match != null && 
        match == typeof (TestValueProvider) 
); 

此代码移除由Inject<T>(T object)方法制成的登记,但不恢复IValueProvider类型的默认实例。这意味着不再有IValueProvider的默认实例。

为此ObjectFactory.GetInstance<IValueProvider>()会抛出异常StructureMap Exception Code: 202 No Default Instance defined for PluginFamily ...

ObjectFactory.GetAllInstances<IValueProvider>().First()会给你回的ValueProvider实例。你期望的那个。

我不确定你在试图在这里测试什么,但如果他们是单元测试,你应该尽量避免需要一个IoC容器(这也意味着取决于ObjectFactory)。如果您确实需要容器,请使用​​的抽象,您可以管理和创建自己。一些链接支持这个其他SO问题是: