2014-12-20 38 views
2

我目前正試圖讓我的頭在結構映射中,因爲ObjectFactory靜態函數已被標記爲過時。結構圖IContainer實現

從長遠來看,我必須在MVC和WebApi應用程序中使用它。在以前使用時,將一行指向靜態方法的行放在global.asax中,以使用ObjectFactory初始化所有內容。

ObjectFactory.Initialize{ 
       container.For ..... 
} 

試圖將其轉換爲新的IContainer的方法,我想出了但是下面我想知道如果我實際上已經在不經意間實現我的方法,這經常提到反模式。

的靜態方法返回容器:

public class StructureMapConfig 
{ 
    public static IContainer GetContainer() 
    {    
     return new Container(container => 
     { 
      container.For<IUserService>().Use<UserService>(); 
      container.For<IStringService>().Use<StringService>(); 
      container.For<IUserRepository>().Use<UserRepository>();     
     }); 
    } 
} 

Userservice的contstructor看起來像這樣:

public class UserService : IUserService 
{ 
    private readonly IUserRepository _userRepository; 
    private readonly IStringService _stringService; 

    public UserService(IUserRepository userRepository, IStringService stringService) 
     { 
     _userRepository = userRepository; 
     _stringService = stringService; 
     } 

最後INITIALISE(這種情況在一個控制檯應用程序)看起來財產以後這樣的:

private static IUserService _userService; 
    private static IContainer _container; 

    static void Main(string[] args) 
     { 
     _container = StructureMapConfig.GetContainer(); 
     _userService = _container.GetInstance<IUserService>(); 
     } 

所以對我的問題。

  1. 我做錯任何事情嚴重錯在這裏
  2. 在UserService,我要傳遞的IContainer中和使用對象的工廠來獲得實例,或者我應該保留原樣。
  3. 從靜態方法返回IContainer最好的方法
  4. 如果這是一個MVC應用程序,是否最好在Global.asax中創建一次,或者控制器構造函數應該每次調用靜態方法。

感謝您的任何建議。

回答

4

要經過你的問題依次是:

  1. 我做錯任何事情嚴重錯在這裏

不,我沒有看到任何嚴重的問題在這裏。你可以做一些改進,我會盡快談論。

  • 在UserService,我應該傳遞的IContainer並使用 對象工廠來獲得實例還是應該保留原樣。
  • 通過IContainer實例注入UserService是正確的。如果你的控制器只需要UserService,那麼爲什麼要注入整個容器。真的,你只想注入最少的東西來減少不必要的耦合和依賴。

  • 從靜態方法的最佳方法
  • 在除去ObjectFactory然後返回的IContainer是,通過返回容器的一個實例對於那些不通過MVC的依賴關係解析進行管理的類,靜態方法是常見的方法。

  • 如果這是一個MVC應用程序,它是在 Global.asax中一旦建立這個或應所述控制器構造調用靜態 方法每次最佳實踐。
  • Global.asax.cs創建容器是你的最好的方法,因爲它是做一次就Application_Start,但請參閱下面的我使用每個HTTP請求嵌套容器的建議。

    改進: - StructureMap的登記的

    利用:

    而是直接引用的依賴關係是這樣的:

    public static IContainer GetContainer() 
    {    
        return new Container(container => 
        { 
         container.For<IUserService>().Use<UserService>(); 
         container.For<IStringService>().Use<StringService>(); 
         container.For<IUserRepository>().Use<UserRepository>();     
        }); 
    } 
    

    選擇使用StructureMap的登記來代替。這樣,您就可以將你的依賴關係(如MVC特定的依賴關係或的WebAPI特定的依賴,就像這樣:

    public class WebsiteRegistry : Registry 
    { 
        public WebsiteRegistry() 
        { 
         this.For<IUserService>().Use<UserService>(); 
         this.For<IStringService>().Use<StringService>(); 
         this.For<IUserRepository>().Use<UserRepository>();   
        } 
    } 
    

    然後加載註冊表這樣的:

    container.Configure(c => { 
        c.IncludeRegistry<WebsiteRegistry>(); 
        c.IncludeRegistry<TaskRegistry>(); 
    }); 
    

    HTTP上下文的貨櫃:

    在ASP.NET MVC或WebApi(或任何基於HTTP的應用程序)中使用StructureMap時,推薦的另一種模式是使用綁定到每個HTTP請求的嵌套容器,基本上涉及到crea在每個HTTP請求上創建一個新的嵌套容器,然後將其放置在請求的末尾。這可以確保在HTTP請求結束後即可處理諸如會話對象,數據庫連接或UoW上下文之類的依賴關係。

    我會推薦看看this article,它會詳細討論這個問題並討論如何設置它。

    這與StructureMap創建者Jeremy Miller經常推薦的StructureMap.MVC5包中使用的技術完全相同。

    自動註冊的依賴

    相反的註冊與StructureMap每個依賴人工,你可以採取的StructureMap's auto-registration優勢。您也可以指定自己的掃描約定。

    +0

    感謝JoeMighty,這裏有一些非常好的信息。很高興看到我離它不遠。再次感謝。 – Morn

    +0

    不是問題!你絕對是在正確的軌道上。 –