OSGI的模块化示例.docx
- 文档编号:10129412
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:20
- 大小:889.28KB
OSGI的模块化示例.docx
《OSGI的模块化示例.docx》由会员分享,可在线阅读,更多相关《OSGI的模块化示例.docx(20页珍藏版)》请在冰豆网上搜索。
OSGI的模块化示例
模块化示例
Sample01:
一个简单的模块
1新建一个名为SimpleModuleShell的“控制台宿主应用程序”项目。
2添加一个新建项目,名称为SimpleModule项目,其项目路径指向SimpleModuleShell项目的bin\plugins文件夹,这样一个默认的模块便创建完成。
3新建的SimpleModule模块由Activator.cs文件和Manifest.xml文件组成。
4Manifest.xml是模块的配置信息,默认创建的内容如下。
xmlversion="1.0"encoding="utf-8"?
>
--定义一个模块,其特征名称为SimpleModule。
特征名称是唯一标识一个模块的名称。
-->
uiosp-bundle-manifest-2.0"Name="SimpleModule"SymbolicName="SimpleModule"Version="1.0.0.0"InitializedState="Active"> --模块激活器定义。 --> --模块本地程序集声明。 --> 这个模块配置定义了模块的特征名称是SimpleModule,激活器是SimpleModule.Activator,包含一个模块工程下的“bin\SimpleModule.dll”本地程序集。 一旦SimpleModuleShell运行,SimpleModule模块会被按装到系统并调用SimpleModule.Activator的Start方法启动模块,反之,一旦停止,Stop方法会被调用。 注意: Manifest.xml默认编辑器是UIOSP编辑器,它是一个图形化编写模块配置的工具,如下所示。 如果要查看Manifest.xml文件,按F7或者右键查看代码。 5Activator.cs是激活器的定义,在该模块我们定义的激活器如下。 usingSystem; usingSystem.Collections.Generic; usingUIShell.OSGi; namespaceSimpleModule { /// ///模块激活器,它是一个模块启动和停止的入口。 当模块被启动时,激活器的Start方法会被调用;如果是被停止,则其Stop方法会被调用。 ///一般而言,一个模块会在Start方法中向系统提供功能、注册服务、申请如线程等资源等,在Stop方法会执行回收操作,比如关闭功能、 ///卸载服务、释放资源等。 需要注意的是,在Start方法中申请的资源必须在Stop方法中得到释放,而且一个模块的Start/Stop方法在运行 ///过程可能会被调用多次,必须确保再次调用Start/Stop方法不会出现异常。 /// publicclassActivator: IBundleActivator { /// ///模块启动时调用的方法。 /// /// ///模块上下文是框架提供给模块唯一的对象。 publicvoidStart(IBundleContextcontext) { Console.WriteLine("SimpleModuleisstarted."); } /// ///模块停止时调用的方法。 /// /// publicvoidStop(IBundleContextcontext) { Console.WriteLine("SimpleModuleisstopped."); } } } 6运行SimpleModuleShell,SimpleModule模块默认会被启动。 该模块在启动时会在控制台输出“SimpleModuleisstarted.”。 7使用RemoteConsole查看模块运行状态,其结果如下 8在RemoteConsole输入“stop/start3”分别用于停止和启动SimpleModule模块,模块状态便发生改变,且激活器Stop/Start方法会被分别调用,并在控制台打印以下信息。 Sample02: 模块初始状态 1在Sample01基础上,修改Manifest.xml中Bundle节点,添加一个“InitializedState="Install"”的XML属性。 InitializedState是模块初始状态,可能为Install或者Active,如果不指定默认为Active。 或者在编辑器上直接取消“Startthebundlewhentheframeworkisactivated.” 2运行SimpleModuleShell,利用RemoteConsole查看UIOSP模块状态,如下。 此时,SimpleModule的状态为Install状态。 Sample03: 模块激活器与晚激活 1在Sample01基础上,修改Mainfest.xml中Activator配置节点,添加“Policy="Lazy"”属性。 模块有两种激活方式: 立即激活和晚激活。 立即激活意味着模块一旦被启动,其激活器的Start方法便会调用;而晚激活则会将激活器Start方法的调用推迟到“第一次尝试从该模块加载一个类”时机。 2运行SimpleModuleShell,通过RemoteConsole查看模块运行情况如下。 3为SimpleModule添加一个ClassLoadingToActivate类,该类为测试类,不做任何实现。 namespaceSimpleModule { publicclassClassLoadingToActivate { } } 4添加另一个模块LoadClassModule,该模块用于加载SimpleModule的ClassLoadingToActivate类,从而导致SimpleModule执行激活。 (1)修改Manifest.xml,将该模块初始状态变为Install,即默认为不启动;此外,添加对SimpleModule模块的依赖。 xmlversion="1.0"encoding="utf-8"? > --初始状态更改为Install,即默认不启动。 --> uiosp-bundle-manifest-2.0"SymbolicName="LoadClassModule"InitializedState="Install"> --添加对SimpleModule模块的依赖--> (2)在Activator中,加载ClassLoadingToActivate类。 namespaceLoadClassModule { publicclassActivator: IBundleActivator { publicvoidStart(IBundleContextcontext) { IBundlesimpleModule=context.GetBundleByName("SimpleModule"); TypeclassLoadingToActivateType=simpleModule.LoadClass( "SimpleModule.ClassLoadingToActivate"); } publicvoidStop(IBundleContextcontext) { //todo: } } } 5运行SimpleModuleShell,启动RemoteConsole查看模块运行情况如下。 6在RemoteConsole执行“start2”,启动LoadClassModule。 一旦LoadClassModule被启动,它的激活器会从SimpleModule加载ClassLoadingToActivate类,从而触发SimpleModule进入Active状态。 此时,在控制台上,将打印“SimpleModuleisstarted.”。 Sample04: 模块本地程序集 1在Sample01基础上,新建一个SimpleModuleLib类库程序集,并添加一个SayHello类。 namespaceSimpleModuleLib { publicclassSayHello { publicvoidHello(stringname) { Console.WriteLine(string.Format("Hello,{0}.",name)); } } } 2在SimpleModule中添加对SimpleModuleLib项目引用,并修改Manifest.xml的Runtime配置节点,添加一个“ xmlversion="1.0"encoding="utf-8"? > uiosp-bundle-manifest-2.0"SymbolicName="SimpleModule"> --添加模块依赖的本地程序集。 这样做的目的: (1)使CLR类加载器能够加载到该类; (2)支持类型晚加载。 --> 3Runtime配置节点定义了模块运行过程中需要的类型信息,Assembly配置节点定义了模块的本地程序集。 这样的定义,其目的是 (1)是CLR类加载其能够从不在标准文件目录下的程序集加载到所需的类型; (2)支持从程序集晚加载所需类型。 4运行SimpleModuleShell,结果如下。 5注意: 如果模块引用了一个程序集,但是在Manifest.xml的Runtime没有相关的本地程序集Assembly配置,在类型加载时,会发生类型查找不到的异常。 6Assembly配置节点Path属性是必填的项,它用于指定本地程序集相对于模块根路径的相对路径。 Sample05: 模块类型复用与依赖 1在UIOSP中,模块间可以实现类型复用。 这个示例基于Sample04之上,实现了类型复用的示例。 首先修改SimpleModule的Manifest.xml中的SimpleModuleLib本地程序集声明,为该声明一个Share属性。 Share属性则表示该程序集是否能够与其它Bundle复用。 xmlversion="1.0"encoding="utf-8"? > uiosp-bundle-manifest-2.0"SymbolicName="SimpleModule"> --添加模块依赖的本地程序集。 这样做的目的: (1)使CLR类加载器能够加载到该类; (2)支持类型晚加载。 --> --Share用于声明一个程序集是否可以被其它模块复用。 --> 或者通过编辑器添加一个如下程序集。 2新建一个DependencyModule控制台插件应用程序,然后浏览并引用SimpleModule模块下的bin\SimpleModuleLib.dll程序集,需要注意的是,我们必须把这个引用的“复制本地”变为false。 如下图。 3在Manifest.xml添加对SimpleModule程序集的依赖。 xmlversion="1.0"encoding="utf-8"? > uiosp-bundle-manifest-2.0"SymbolicName="DependencyModule"> --添加对SimpleModuleLib程序集的依赖。 --> 4在Activator使用SimpleModuleLib中的SayHello类。 namespaceDependencyModule { publicclassActivator: IBundleActivator { publicvoidStart(IBundleContextcontext) { //todo: SimpleModuleLib.SayHellosayHello=newSimpleModuleLib.SayHello(); sayHello.Hello("DependencyModule"); } publicvoidStop(IBundleContextcontext) { //todo: } } } 5运行SimpleModuleShell,结果如下。 Sample06: 模块启动级别 1模块启动级别在模块Manifest.xml,用于设置模块启动顺序、框架安全启动、屏蔽异常模块等。 框架系统模块启动级别为1,级别越小优先级越高。 框架默认启动级别为100,即小于等于100的模块会被框架启动,大于100则不会。 2在Sample01基础上,新建SimpleModule1和SimpleModule2控制台插件应用程序。 3分别设置SimpleModule、SimpleModule1和SimpleModule2的启动级别为2、3和4。 4运行SimpleModuleShell,其结果如下。 Sample07: 片段模块 1在Sample01基础上创建一个FragmentModule的控制台插件应用程序。 片段模块和宿主模块相比,它不是一个正常的模块,不能被启动、停止,不能从片段模块加载任何资源。 片段模块声明的所有配置最终将合并到它指定的宿主模块。 如果我们需要依赖一个片段的程序集,那么我们声明的依赖必须指向该片段模块的宿主模块。 2删除Activator.cs,修改Manifest.xml文件将Activator配置节删掉。 3修改Manifest.xml中Bundle配置节点,添加“HostBundleSymbolicName="SimpleModule"”属性,设置FragmentModule模块的HostBundle是SimpleModule。 4在FragmentModule添加一个SayHelloFromFragment类,如下。 namespaceFragmentModule { publicclassSayHelloFromFragment { publicvoidHello(stringname) { Console.WriteLine(string.Format("Hello,{0}.",name)); } } } 5在SimpleModule的Activator加载SayHelloFromFragment类型,并利用反射调用其Hello方法。 namespaceSimpleModule { publicclassActivator: IBundleActivator { publicvoidStart(IBundleContextcontext) { TypesayHelloFromFragmentType=context.Bundle.LoadClass( "FragmentModule.SayHelloFromFragment"); if(sayHelloFromFragmentType! =null) { objectsayHello=System.Activator.CreateInstance(sayHelloFromFragmentType); MethodInfohelloMethod=sayHello.GetType().GetMethod("Hello"); helloMethod.Invoke(sayHello,newobject[]{"FragmentModule."}); } } publicvoidStop(IBundleContextcontext) { } } } 6新建一个FragmentDependencyModule的控制台插件应用程序。 修改Manifest.xml添加对SimpleModule模块依赖,如下。 xmlversion="1.0"encoding="utf-8"? > uiosp-bundle-manifest-2.0"SymbolicName="FragmentDependencyModule"> 7在FragmentDependencyModule模块激活器中使用片段模块的SayHelloFromFragment类。 usingSystem; usingSystem.Collections.Generic; usingUIShell.OSGi; usingFragmentModule; namespaceFragmentDependencyModule { publicclassActivator: IBundleActivator { publicvoidStart(IBundleContextcontext) { SayHelloFromFragmentsayHelloFromFragment=newSayHelloFromFragment(); sayHelloFromFragment.Hello("FragmentDependencyModule"); } publicvoidStop(IBundleContextcontext) { //todo: } } } 8运行SimpleModuleShell,结果如下。 Sample08: 模块与程序集版本 1该框架支持多版本模块和程序集。 一个模块可以在Bundle配置定义添加一个Version属性来设置版本,一个程序集可以在Assembly配置定义添加一个Version属性设置程序集的版本号。 依赖于该模块或者程序集的模块可以在Dependency定义中设定依赖的版本范围或者是特定的版本。 2在Sample05基础之上,修改SimpleModule模块Manifest.xml,添加模块版本和程序集版本。 定义如下。 xmlversion="1.0"encoding="utf-8"? > --设置模块的版本号为1.2。 --> uiosp-bundle-manifest-2.0"SymbolicName="SimpleModule"Version="1.1"> --设置该模块一个共享程序集,否则会出现类型加载失败。 --> 3修改DependencyModule模块的Manifest.xml,设置版本依赖约束如下。 xmlversion="1.0"encoding="utf-8"? > uiosp-bundle-manifest-2.0"SymbolicName="DependencyModule"> --添加对SimpleModuleLib程序集的依赖,它设置的版本范围为0.0~2.0。 --> AssemblyName="SimpleModuleLib"AssemblyVersi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OSGI 模块化 示例
![提示](https://static.bdocx.com/images/bang_tan.gif)