Microsoft企业库中Unity应用程序块的用途?

时间:2009-11-11 01:23:32

标签: unity-container enterprise-library

有人可以向我解释Unity应用程序块的用途是什么?我试着查看文档,但它非常抽象。

Unity块的一些实际用途是什么?

2 个答案:

答案 0 :(得分:15)

控制倒置

快速总结(本主题提供更多阅读,我强烈建议阅读更多内容)...

Microsoft企业模式和实践团队中的Unity是一个控制反转容器项目,简称IoC。就像Castle Windsor,StructureMap等一样。这种类型的开发在lamen的术语中也被称为Loosely Coupling your components。

IoC包含对象的依赖注入模式,在这种模式中,您依赖外部组件来连接对象中的依赖项。

例如,您不是访问静态管理器(几乎不可能进行单元测试),而是创建一个依赖外部依赖关系来处理的对象。让我们选择一个Post服务,您可以在其中访问数据库以获得帖子。

public class PostService : IPostService
{
  private IPostRepository _postRepo;

  public PostService(IPostRepository postRepo)
  {
    _postRepo = postRepo;
  }

  public IList<Post> GetPosts()
  {
    return _postRepo.GetAllPosts().ToList();
  }
}

此PostService对象现在具有对IPostRepository的外部依赖性。请注意如何使用没有混凝土和静态管理器类?相反,您有一个简单接口的松散耦合 - 它使您能够连接实现IPostRepository的所有不同类型的具体类。

Microsoft Unity的目的是自动为您连接该IPostRepository。所以你永远不必担心这样做:

// you never have to do this with Unity
IPostRepository repo = new PostRepository();
IPostService service = new PostService(repo); // dependency injection
IList<Post> posts = service.GetPosts();

上面显示了必须实现两个具体类PostRepository()和PostService()的地方。这是将您的应用程序紧密耦合到需求/需要那些确切的实例,并使单元测试非常困难。

相反,您将在终点使用Unity(MVC中的控制器,或ASPX页面中的代码):

IUnityContainer ioc = new UnityContainer();
IPostService postService = ioc.Resolve<IPostService>();
IList<Post> posts = postService.GetPosts();

请注意,此示例中没有使用混凝土(显然除了UnityContainer和Post)!没有服务的混凝土,也没有存储库。这是最好的松散耦合。

这是真正的踢球者......

Unity(或任何IoC容器框架!)将检查IPostService是否存在任何依赖关系。它会看到它想要(取决于)IPostRepository的实例。因此,Unity将进入它的对象映射并查找实现向容器注册的IPostRepository的第一个对象,并返回它(即SqlPostRepository实例)。这就是IoC框架背后的真正力量 - 检查服务并自动连接任何依赖项的能力。

我需要完成关于UNity vs Castle vs StructureMap比较的博客文章。我实际上更喜欢Castle Windsor,因为它的配置文件选项和个人的可扩展性点。

答案 1 :(得分:4)

Unity应用程序块用于dependency injection。我认为DI的最简单定义来自this question

当你自己从冰箱里拿出东西时,你可能会引发问题。你可能会把门打开,你可能得到妈咪或爸爸不希望你拥有的东西。您甚至可能正在寻找我们甚至没有或已经过期的东西。

你应该做的是说明需要,“我需要在午餐时喝点东西”,然后当你坐下来吃饭时我们会确保你有东西。

举个例子,

IUnityContainer container = new UnityContainer();
ILunch lunch = container.Resolve<ILunch>();
Console.WriteLine(lunch.Drink); 

这会输出“Lemonade”,因为我们将Drink定义为依赖关系。

public class ILunch {
    [Dependency]
    public IDrink Drink { get; set; }
} 

就实用性而言,当您对其他对象具有依赖性并且您不希望开发人员必须手动设置它们时,依赖注入非常好。就这么简单。它也非常适合嘲笑。我能想到的最常用的例子是模拟数据层。有时数据库还没有准备好,所以我没有停止开发,而是有一个返回虚假数据的假层。数据对象通过DI访问,可以配置为返回访问伪层或真实层的对象。在这个例子中,我几乎使用DI Container作为可配置的工厂类。有关Unity的更多信息,MSDN有一些很棒的资源http://msdn.microsoft.com/en-us/library/cc468366.aspx

其他优秀的DI框架包括Spring.NETNinject