2013-11-02 63 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問題是: