【发布时间】:2009-11-11 01:23:32
【问题描述】:
谁能向我解释 Unity 应用程序块的用途是什么?我尝试浏览文档,但它都非常抽象。
Unity 块有哪些实际用途?
【问题讨论】:
标签: unity-container enterprise-library
谁能向我解释 Unity 应用程序块的用途是什么?我尝试浏览文档,但它都非常抽象。
Unity 块有哪些实际用途?
【问题讨论】:
标签: unity-container enterprise-library
控制反转
快速总结(此主题可阅读更多内容,我强烈建议阅读更多内容)...
来自企业模式和实践团队的 Microsoft Unity 是一个控制反转容器项目,简称 IoC。就像 Castle Windsor、StructureMap 等一样。这种类型的开发在 lamen 的术语中也称为松散耦合您的组件。
IoC 包含一个用于对象依赖注入的模式,在该模式中,您依赖外部组件来连接对象内的依赖关系。
例如,您不是访问静态管理器(几乎不可能进行单元测试),而是创建一个依赖于外部依赖项来执行操作的对象。让我们以 Post 服务为例,您希望在其中访问 DB 以获取 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、Castle 和 StructureMap 比较的博文。实际上我更喜欢 Castle Windsor,因为它的配置文件选项和个人扩展点。
【讨论】:
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 容器用作可配置的工厂类。有关 Unity 的更多信息,MSDN 有一些很棒的资源http://msdn.microsoft.com/en-us/library/cc468366.aspx。
其他好的 DI 框架包括 Spring.NET 和 Ninject
【讨论】: