Prism 4 文档 ---第3章 管理组件间的依赖关系
- 容器移除了组件需要去定位它的依赖对象和管理这些对象的生命周期的任务。
- 容器实现了在不影响组件的情况下改变依赖的实现方法。
- 容器可以通过模拟依赖组件而使得测试更加容易。
- 容器通过更容易的添加新组件到系统中增强了应用程序的可维护性。
在使用Prism应用程序中,容器还有一些特殊的优势:
- 容器在模块被加载时才将模块的依赖关系注入
- 容器被用来注册和解析视图模型和视图
- 容器可以创建模块的视图并且注入到视图中
- 容器注入到组合服务中,例如区域管理和事件聚合器
- 容器被用来注册模块特有的服务
注意:
- 它们都可以在容器中注入类型
- 它们都可以在容器中注入实例
- 它们都可以创建注册类型的实例
- 它们都可以在构造方法中进行注入
- 它们都可以在属性中进行注入
- 它们都可以通过声明属性来管理那些需要标记的类型和依赖关系
- 它们都可以在一个对象图表中解析依赖关系
- 可以解析未注册的具体类型
- 可以解析公开的泛型类
- 使用监听来捕获被注入者调用的内容,并向这些目标对象中添加额外的功能
- 在目录中发现程序集
- 使用下载XAP文件并发现程序集
- 当发现心类型时,重组属性和集合
- 自动的导出(发现)子类型
- 依赖.NET框架
这些容器拥有不同的能力并且工作原理也不相同,但是Prism类库可以工作在这些容器之上并且提供相似的功能。当考虑使用何种容器时,记住上文中所述的特点并决定哪种容器更合适你。
- 考虑是否将组件注册/解析到容器中是合适的
- 考虑在你的场景中,注册到容器和解析实例的性能影响是否可以接受。例如,你需要在当前的视角中创建10000个多边形来绘制某个表面,那么容器接卸这么多的多边形实例的开销将会造成非常大的性能负担,因为它是使用反射的方式来创建每个实例的。
- 如果依赖关系比较多或者层次比较深,那么创建它们的花费也是比较大
- 如果组件不依赖任何其他组件或者不被其他组件依赖,那么把它放到容器中将是没有意义的
- 如果组件拥有单独的一套依赖关系,并且这些依赖关系是完整的并且不会改变,那么将它放到容器中也是没有意义的
- 根据组件的生命周期来决定它是被注册为一个单例还是注册为一个实例
- 如果组件是一个全局服务扮演着一个单一资源的管理角色时,就像日至服务,将它们注册为单例形式。
- 如果组件要在多个用户见保持共享状态,那么注册为单例形式
- 如果组件在每次注入时都需要一个独立的依赖实例,那么就不能注册为单例形式。例如,每个视图都需要一个视图模型的实例。
- 考虑你将使用代码还是使用配置文件来配置容器
- 如果你想集中的管理不同的服务,那么使用配置文件来配置容器
- 如果你要根据特定的条件注册特定的服务,那么使用代码来配置容器
- 如果你拥有模块级服务,考虑使用代码来配置容器,因为那样这些服务才会在加载时被注册
注意:
- 你可以向容器中注册一个类型或者一张关系图,在适当的时候,容器将会创建你所指定的类的实例
- 你可以向容器中将一个已经存在的对象注册为一个单例形式。容器将会返回这个已存在对象的引用。
在初始化过程中,一种类型可以注册另外的类型,就像视图和服务。注册后就可以向整个容器提供它们的依赖关系,也可以通过其他类型来访问它们。为了做到这一点,类型需要在模块的构造器中向容器注入。以下代码是Commanding QuickStart示例代码中OrderModule是如何注册一个类型的。
public class OrderModule : IModule |
取决于你所选取的容器,注册也可以在代码外通过配置文件来实现。例如,参加第4章"Modular Application Development."中的"Registering Modules using a Configuration File"
注意:
与配置文件相比,通过代码来注册的优势在于,当模块被加载时才会注册。
MEF使用了基于属性的方式向容器中注册类型。因此,向容器中添加类型注册变的非常简单:为类型添加一个[Export]属性,如下代码所示,
[Export(typeof(ILoggerFacade))] |
使用MEF注册的另一种方法是将一个特定实例注册到容器中,如示例Modularity for Silverlight with MEF QuickStart中的QuickStartBootstrapper中注册函数ConfigureContainer所实现的这样,如下:
protected override void ConfigureContainer() |
类型注册之后,它可被作为一个依赖来解析或者注册。当一个类型被解析时,容器需要创建一个新的实例,并将依赖关系注入到新创建的对象中。
一般来讲,当一个类型被解析时,会发生以下三种情况之一:
- 如果这个类型还未被注册,容器将会抛出一个异常
- 如果类型被注册为单例形式,容器将返回单例实例对象。如果这是该类型的首次被调用,那么容器将会创建实例对象,并且把保存以备以后使用。
- 如果这个类型未被注册为单例形式,容器将返回新的实例
以下代码是Commanding QuickStart实例中的两个视图OrdersEditorView和OrdersToolBar是如何被容器解析,并且放置到其对应的区域中去的。
public class OrderModule : IModule |
OrdersEditorPresentationModel构造方法中包含以下依赖(IOrdersRepository和OrdersCommandProxy),当它们被解析时,它们就被注入了。
public OrdersEditorPresentationModel( IOrdersRepository ordersRepository, OrdersCommandProxy commandProxy ) |
protected override DependencyObject CreateShell() |
如实例Modularity for Silverlight with MEF QuickStart中的ModuleA,ILoggerFacade和IModuleTracker就是以如下代码的方式注入的。
[ImportingConstructor] |
另一种方式是使用属性注入,如Modularity for Silverlight with MEF QuickStart实例中的ModuleTracker类中向实例中注入ILoggerFacade的所示方法。
[Export(typeof(IModuleTracker))] |
Prism 类库提供了UnityServiceLocatorAdapter 和 MefServiceLocatorAdapter. 这两个类都实现了通过扩展ServiceLocatorImplBase实现了ISeviceLocator接口,下面插图展示了类之间的关系


虽然Prism类库没有依赖或者实现任何特定的容器,但通常情况下,应用程序会依赖于某个特定的容器。这意味特定的应用程序会依赖某个容器,但是Prism类库并不直接和任何容器发生关系的是合理的。例如Stock Trader RI和一部分的QuickStart使用Prism并且依赖于Unity容器,而另一部分QuickStart和示例则依赖于MEF。
IServiceLocator
public interface IServiceLocator : IServiceProvider |
public static class ServiceLocatorExtensions |
ModuleInitializer使用IServiceLocator在模块的加载过程中解析模块,如下代码所示:
IModule moduleInstance = null; |
protected virtual IModule CreateModule(string typeName) |
- 你是一个独立软件开发商(ISV),开发一个适用于多容器的第三方服务
- 你在一个使用多种容器的系统中设计一个服务
- "Unity Application Block" on MSDN:
http://www.msdn.com/unity - Unity community site on CodePlex:
http://www.codeplex.com/unity - "Managed Extensibility Framework Overview" on MSDN:
http://msdn.microsoft.com/en-us/library/dd460648.aspx - MEF community site on CodePlex:
http://mef.codeplex.com/ - "Inversion of Control containers and the Dependency Injection pattern" on Martin Fowler's website:
http://www.martinfowler.com/articles/injection.html - "Design Patterns: Dependency Injection" in MSDN Magazine:
http://msdn.microsoft.com/en-us/magazine/cc163739.aspx - "Loosen Up: Tame Your Software Dependencies for More Flexible Apps" in MSDN Magazine:
http://msdn.microsoft.com/en-us/magazine/cc337885.aspx - Castle Project:
http://www.castleproject.org/container/index.html - StructureMap:
http://structuremap.sourceforge.net/Default.htm - Spring.NET:
http://www.springframework.net/
Prism 4 文档 ---第3章 管理组件间的依赖关系的更多相关文章
- Prism 文档 第三章 管理组件之间的依赖关系
第3章:管理组件之间的依赖关系 基于Prism库的复合应用程 ...
- Ext JS 6学习文档-第3章-基础组件
Ext JS 6学习文档-第3章-基础组件 基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮, ...
- Ext JS 6学习文档-第6章-高级组件
Ext JS 6学习文档-第6章-高级组件 高级组件 本章涵盖了高级组件,比如 tree 和 data view.它将为读者呈现一个示例项目为 图片浏览器,它使用 tree 和 data view 组 ...
- Ext JS 6学习文档-第5章-表格组件(grid)
Ext JS 6学习文档-第5章-表格组件(grid) 使用 Grid 本章将探索 Ext JS 的高级组件 grid .还将使用它帮助读者建立一个功能齐全的公司目录.本章介绍下列几点主题: 基本的 ...
- Prism 4 文档 ---第7章 组成用户界面
一个应用程序的用户界面(UI)可以通用以下几种模式之一来构建: 窗体所需要所有的控件都包含在一个单独的XAML文件中,在设计时组合这个窗体. 窗体的逻辑区域被分割到单独的部分中,通常指哟过户控件.这些 ...
- Prism 4 文档 ---第4章 模块化应用程序开发
模块化应用程序是指将一个应用程序拆分成一系列的可以组合的功能单元.一个客户端模块封装了应用程序的一部分,并且通常是一系列相关的关注点.它可以包含一个相关的组件的集合,就像用户界面,应用程序功能,和一些 ...
- Prism 4 文档 ---第11章 部署Prism应用程序
要成功移动Prism应用到生产中,需要对部署计划为应用程序的设计过程的一部分.本章介绍了注意事项和你需要采取的准备以部署应用程序,以及你要在用户手中获得部署程序所需要采取的行动. Si ...
- Prism 4 文档 ---第8章 导航
作为同用户具有丰富的交互的客户端应用程序,它的用户界面(UI)将会持续不断的更新来反映用户工作的当前的任务和数据.用户界面可以进行一段时间相当大的变化作为用户交互的应用程序中完成各种任务.通过 ...
- Prism 4 文档 ---第6章 高级MVVM场景
在上一章中描述了如何通过将UI,表现逻辑,业务逻辑分别放到三个单独的类中(View,View Model,Model),实现这些类之间的交互(通过数据绑定,命令以及数据验证接口)以及实现一个策 ...
随机推荐
- 2018.9 ECNU ICPC/CCPC Trial Round #2 Query On Tree (树链剖分+线段树维护)
传送门:https://acm.ecnu.edu.cn/contest/105/problem/Q/ 一棵树,支持两种操作:给一条路径上的节点加上一个等差数列;求两点路径上节点和. 很明显,熟练剖分. ...
- Loadrunner自带协议分析工具:Protocol Advisor
录制脚本之前,选对协议很关键,否则错误的协议会导致Virtual User Generator 录制不到脚本,或录制的脚本不完整,有些应用可能需要选择多个协议才能完整的记录 客户端与服务器端的请求. ...
- 大数据相关的面试题(摘自网络)hbase,kafka,spark
1.讲讲你做的过的项目, 项目里有哪些难点重点呢? kafkaDirect ES /hive kafka producer 难点值得一提的有两点: 1.rdd中用到外部变量的时候如何处 ...
- HDFS datanode心跳与运维中的实际案例
分布式系统的节点之间常采用心跳来维护节点的健康状态,如yarn的rm与nm之间,hdfs的nn与dn之间.DataNode会定期(dfs.heartbeat.interval配置项配置,默认是3秒)向 ...
- TOSCA自动化测试工具--建立测试用例
1.测试链接 demowebshop.tricentis.com 测试login 2.检查元素 3.Modules模块,建立自己的文件夹,右键Scan Application , Desktop 4. ...
- iOS开发之XMPPFramework环境搭建和配置
1.mysql数据库安装和配置 官方下载地址:http://www.mysql.com/downloads/ 百度云盘地址: 安装软件参考:http://www.cnblogs.com/macro-c ...
- 对象转化为 xml字符串
public static string ToXml<T>(this T o) where T : new() { string retVal; using (var ms = new M ...
- 【工具】Swagger2写接口注释
一.遇到的问题 作为一名coder,经常需要向别人提供接口,或者调用别人的接口.于是就有了接口参数是什么意思,要怎么传参数,返回值是什么意思……有多少调用方,就会有多少人来询问这些参数.如果是长时间之 ...
- Servlet3.0异步请求
在Servlet3.0之前,Servlet采用Thread-Per-Request的方式处理请求 即每次Http请求都有一个线程从头到尾负责处理 如果一个请求需要进行IO操作,比如访问数据库.调用第三 ...
- 爬虫之动态HTML处理(Selenium与PhantomJS )动态页面模拟点击
动态页面模拟点击 #!/usr/bin/env python # -*- coding:utf-8 -*- # python的测试模块 import unittest from selenium im ...