您现在的位置: 365建站网 > 365文章 > Oxite分析之Module

Oxite分析之Module

文章来源:365jz.com     点击数:420    更新时间:2009-09-16 11:53   参与评论

change set:42353

download :http://oxite.codeplex.com/SourceControl/ListDownloadableCommits.aspx

 

约定:在Oxite中,对实现了IOxiteModule接口的类称之为Module或模块。

在某种角度上,可以将Oxite看成是由一个个Module构成的。Oxite项目Modules目录下的各个Module可以看做是系统模块,如Oxite.Modules.Core.OxiteModule、Oxite.Modules.Membership.MembershipModule等;而解决方案目录Modules下的各个Module可以看做是自定义Module,如Oxite.Blogs.BlogsModule、Oxite.CMS.CMSModule。

JIX]6V28HQMV)NAM$UQB2NB

 

一、IOxiteModule接口

每个Module都实现了IOxiteModule接口,下面看看IOxiteModule接口的定义:

</>code

  1. 1: public interface IOxiteModule

</>code

  1. 2: {

</>code

  1. 3: void Initialize();

</>code

  1. 4: void Unload();

</>code

  1. 5: void RegisterRoutes(RouteCollection routes);

</>code

  1. 6: void RegisterCatchAllRoutes(RouteCollection routes);

</>code

  1. 7: void RegisterFilters(IFilterRegistry filterRegistry);

</>code

  1. 8: void RegisterModelBinders(ModelBinderDictionary modelBinders);

</>code

  1. 9: void RegisterWithContainer();

</>code

  1. 10: }

由于目前Oxite官方文档几乎空白,而且又没正式发布,各个方法的作用分别是猜测如下:

RegisterWithContainer:向依赖注入容器注册Module所需的对象或实例;
Initialize:初始化Module(OxiteModule类和PluginsModule类)
RegisterFilters:注册自定义ActionFilter
RegisterModelBinders:注册自定义ModelBinders
RegisterRoutes:设置路由规则
RegisterCatchAllRoutes:作用未知

在“Oxite分析之初始化”一文中曾提到过,当Oxite初始化时,将会调用各个被加载的Module的除了Unload方法外的所有方法。而Unload方法将在Application_End方法中被间接调用用于清理一些资源。

具体查看LoadModules : IBootStrapperTask类的Execute方法:

</>code

  1. 1: OxiteConfigurationSection config = container.Resolve<OxiteConfigurationSection>();

</>code

  1. 2: IModulesLoaded modulesLoaded = this.container.Resolve<IModulesLoaded>();

</>code

  1. 3: RouteCollection routes = this.container.Resolve<RouteCollection>();

</>code

  1. 4: IFilterRegistry filterRegistry = this.container.Resolve<FilterRegistry>();

</>code

  1. 5: ModelBinderDictionary modelBinders = this.container.Resolve<ModelBinderDictionary>();

</>code

  1. 6: //...

</>code

  1. 7:

</>code

  1. 8: filterRegistry.Clear();

</>code

  1. 9:  

</>code

  1. 10: modelBinders.Clear();

</>code

  1. 11:  

</>code

  1. 12: //todo: (nheskew) get plugin routes registered on load in the right order instead of just clearing the routes before module init

</>code

  1. 13: routes.Clear();

</>code

  1. 14:  

</>code

  1. 15: foreach (OxiteModuleConfigurationElement module in config.Modules)

</>code

  1. 16: {

</>code

  1. 17: IOxiteModule moduleInstance = modulesLoaded.Load(config, module);

</>code

  1. 18:  

</>code

  1. 19: if (moduleInstance != null)

</>code

  1. 20: {

</>code

  1. 21: moduleInstance.RegisterWithContainer();

</>code

  1. 22: moduleInstance.Initialize();

</>code

  1. 23: moduleInstance.RegisterFilters(filterRegistry);

</>code

  1. 24: moduleInstance.RegisterModelBinders(modelBinders);

</>code

  1. 25:  

</>code

  1. 26: this.container.RegisterInstance(modulesLoaded);

</>code

  1. 27:  

</>code

  1. 28: //...

</>code

  1. 29: }

</>code

  1. 30: }

</>code

  1. 31:  

</>code

  1. 32: routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

</>code

  1. 33:  

</>code

  1. 34: routes.LoadFromModules(modulesLoaded);

</>code

  1. 35:  

</>code

  1. 36: routes.LoadCatchAllFromModules(modulesLoaded);

</>code

  1. 37:  

 

这里需要注意各个方法的调用顺序,这一点可以查看PluginsModule的源码。我们一般会认为Initialize应该被最先调用,但PluginsModule类的Initialize方法将会用到RegisterWithContainer方法中进行的某些配置,所以RegisterWithContainer方法应该最新被调用。

二、IOxiteDataProvider

Module不一定要实现IOxiteDataProvider。当需要制定Module内部数据访问方式时,通过外部配置以及让Module实现IOxiteDataProvider可以达到。
另外,Oxite配置的灵活性使得Module也可以不实现IOxiteDataProvider接口,而新建一个类来实现。目前Oxite版本中实现在了Module本身中。
通过这样的配置,使得各个Module可以拥有自己特有的数据访问方式,甚至于每个Module可以放在不同的数据库或不同类型的数据库中。在数据访问上说,去除了与系统本身的耦合。

在“Oxite分析之初始化”一文中曾提到过web.config配置文件的自定义"oxite"配置节点。具体配置已经移至单独的Oxite.config,下面看看它的内容:

</>code

  1. 1: <oxite>

</>code

  1. 2: <connectionStrings>

</>code

  1. 3: <add name="Sql" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Oxite.Database;Integrated Security=true;"/>

</>code

  1. 4: <!--<add name="Sql" connectionString="Data Source=.\SQLEXPRESS;AttachDBFileName=|DataDirectory|Oxite.Database.mdf;Integrated Security=true;User Instance=true;"/>-->

</>code

  1. 5: </connectionStrings>

</>code

  1. 6: <dataProviders defaultConnectionString="Sql">

</>code

  1. 7: <add name="Membership" type="Oxite.Modules.Membership.MembershipModule, Oxite" category="LinqToSql" />

</>code

  1. 8: <add name="Tags" type="Oxite.Modules.Tags.TagsModule, Oxite" category="LinqToSql" />

</>code

  1. 9: <add name="Comments" type="Oxite.Modules.Comments.CommentsModule, Oxite" category="LinqToSql" />

</>code

  1. 10: <add name="Plugins" type="Oxite.Modules.Plugins.PluginsModule, Oxite" category="LinqToSql" />

</>code

  1. 11: <add name="Blogs" type="Oxite.Modules.Blogs.BlogsModule, Oxite.Blogs" category="LinqToSql" />

</>code

  1. 12: <add name="CMS" type="Oxite.Modules.CMS.CMSModule, Oxite.CMS" category="LinqToSql" />

</>code

  1. 13: <add name="Conferences" type="Oxite.Modules.Conferences.ConferencesModule, Oxite.Conferences" category="LinqToSql" />

</>code

  1. 14: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" category="LinqToSql" />

</>code

  1. 15: </dataProviders>

</>code

  1. 16: <modules>

</>code

  1. 17: <add name="AspNetCache" type="Oxite.Modules.AspNetCache.AspNetCacheModule, Oxite" />

</>code

  1. 18: <add name="Membership" type="Oxite.Modules.Membership.MembershipModule, Oxite" dataProvider="Membership" />

</>code

  1. 19: <add name="FormsAuthentication" type="Oxite.Modules.FormsAuthentication.FormsAuthenticationModule, Oxite" />

</>code

  1. 20: <add name="Core" type="Oxite.Modules.Core.OxiteModule, Oxite" />

</>code

  1. 21: <add name="Tags" type="Oxite.Modules.Tags.TagsModule, Oxite" dataProvider="Tags" />

</>code

  1. 22: <add name="Files" type="Oxite.Modules.Files.FilesModule, Oxite" />

</>code

  1. 23: <add name="Comments" type="Oxite.Modules.Comments.CommentsModule, Oxite" dataProvider="Comments" />

</>code

  1. 24: <add name="Plugins" type="Oxite.Modules.Plugins.PluginsModule, Oxite" dataProvider="Plugins" />

</>code

  1. 25: <add name="Blogs" type="Oxite.Modules.Blogs.BlogsModule, Oxite.Blogs" dataProvider="Blogs" />

</>code

  1. 26: <add name="CMS" type="Oxite.Modules.CMS.CMSModule, Oxite.CMS" dataProvider="CMS" />

</>code

  1. 27: <add name="Conferences" type="Oxite.Modules.Conferences.ConferencesModule, Oxite.Conferences" dataProvider="Conferences" enabled="false" />

</>code

  1. 28: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" dataProvider="Search" />

</>code

  1. 29: <add name="Site" type="OxiteSite.App_Code.Modules.OxiteSite.OxiteSiteModule" />

</>code

  1. 30: </modules>

</>code

  1. 31: </oxite>

modules节点下的元素,有的具有dataProvider属性(查看OxiteModuleConfigurationElement类的DataProvider属性的定义)。比如name为"Search"的元素,dataProvider为"Search":

</>code

  1. 1: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" dataProvider="Search" />

其对应的是dataProviders节点下的name为"Search"的元素:

</>code

  1. 1: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" category="LinqToSql" />

 

接着请看ModulesLoaded类的Load方法:

</>code

  1. 1: public IOxiteModule Load(OxiteConfigurationSection config, OxiteModuleConfigurationElement module)

</>code

  1. 2: {

</>code

  1. 3: if (module == null || !module.Enabled) return null;

</>code

  1. 4:  

</>code

  1. 5: foreach (OxiteDataProviderConfigurationElement dataProvider in config.Providers)

</>code

  1. 6: {

</>code

  1. 7: if (dataProvider.Name == module.DataProvider)

</>code

  1. 8: {

</>code

  1. 9: Type dataProviderType = Type.GetType(dataProvider.Type);

</>code

  1. 10:  

</>code

  1. 11: if (dataProviderType == null)

</>code

  1. 12: throw new TypeLoadException(string.Format("Could not load type '{0}'.", dataProvider.Type));

</>code

  1. 13:  

</>code

  1. 14: IOxiteDataProvider dataProviderInstance = container.Resolve(dataProviderType) as IOxiteDataProvider;

</>code

  1. 15:  

</>code

  1. 16: if (dataProviderInstance != null)

</>code

  1. 17: dataProviderInstance.ConfigureProvider(config, dataProvider, container);

</>code

  1. 18:  

</>code

  1. 19: break;

</>code

  1. 20: }

</>code

  1. 21: }

</>code

  1. 22:  

</>code

  1. 23: //…

</>code

  1. 25: }

OxiteConfigurationSection config为整个oxite配置节点;OxiteModuleConfigurationElement module为oxite配置节点modules下的一个元素(比如name为"Search"的元素)
上述代码的第5行开始,遍历oxite.config配置中的dataProviders节点下的dataProvider元素,如果元素的name值等于module的dataProvider属性,通过dataProvider元素的type属性,获取类型。接着判断类型是否真的继承于IOxiteDataProvier。如果是,调用类型的ConfigureProvider方法。

Tag标签: ASP.NET MVC,Oxite

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛

发表评论 (420人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称:
最新评论
------分隔线----------------------------

快速入口

· 365软件
· 杰创官网
· 建站工具
· 网站大全

其它栏目

· 建站教程
· 365学习

业务咨询

· 技术支持
· 服务时间:9:00-18:00
365建站网二维码

Powered by 365建站网 RSS地图 HTML地图

copyright © 2013-2024 版权所有 鄂ICP备17013400号