2014-12-20 42 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

    不是问题!你绝对是在正确的轨道上。 –