change set:42353
download :http://oxite.codeplex.com/SourceControl/ListDownloadableCommits.aspx
約定:在Oxite中,對實(shí)現(xiàn)了IOxiteModule接口的類稱之為Module或模塊。
在某種角度上,可以將Oxite看成是由一個個Module構(gòu)成的。Oxite項目Modules目錄下的各個Module可以看做是系統(tǒng)模塊,如Oxite.Modules.Core.OxiteModule、Oxite.Modules.Membership.MembershipModule等;而解決方案目錄Modules下的各個Module可以看做是自定義Module,如Oxite.Blogs.BlogsModule、Oxite.CMS.CMSModule。
一、IOxiteModule接口
每個Module都實(shí)現(xiàn)了IOxiteModule接口,下面看看IOxiteModule接口的定義:
1: public interface IOxiteModule
2: {
3: void Initialize();
4: void Unload();
5: void RegisterRoutes(RouteCollection routes);
6: void RegisterCatchAllRoutes(RouteCollection routes);
7: void RegisterFilters(IFilterRegistry filterRegistry);
8: void RegisterModelBinders(ModelBinderDictionary modelBinders);
9: void RegisterWithContainer();
10: }
由于目前Oxite官方文檔幾乎空白,而且又沒正式發(fā)布,各個方法的作用分別是猜測如下:
RegisterWithContainer:向依賴注入容器注冊Module所需的對象或?qū)嵗?
Initialize:初始化Module(OxiteModule類和PluginsModule類)
RegisterFilters:注冊自定義ActionFilter
RegisterModelBinders:注冊自定義ModelBinders
RegisterRoutes:設(shè)置路由規(guī)則
RegisterCatchAllRoutes:作用未知
在“Oxite分析之初始化”一文中曾提到過,當(dāng)Oxite初始化時,將會調(diào)用各個被加載的Module的除了Unload方法外的所有方法。而Unload方法將在Application_End方法中被間接調(diào)用用于清理一些資源。
具體查看LoadModules : IBootStrapperTask類的Execute方法:
1: OxiteConfigurationSection config = container.Resolve<OxiteConfigurationSection>();
2: IModulesLoaded modulesLoaded = this.container.Resolve<IModulesLoaded>();
3: RouteCollection routes = this.container.Resolve<RouteCollection>();
4: IFilterRegistry filterRegistry = this.container.Resolve<FilterRegistry>();
5: ModelBinderDictionary modelBinders = this.container.Resolve<ModelBinderDictionary>();
6: //...
7:
8: filterRegistry.Clear();
9:
10: modelBinders.Clear();
11:
12: //todo: (nheskew) get plugin routes registered on load in the right order instead of just clearing the routes before module init
13: routes.Clear();
14:
15: foreach (OxiteModuleConfigurationElement module in config.Modules)
16: {
17: IOxiteModule moduleInstance = modulesLoaded.Load(config, module);
18:
19: if (moduleInstance != null)
20: {
21: moduleInstance.RegisterWithContainer();
22: moduleInstance.Initialize();
23: moduleInstance.RegisterFilters(filterRegistry);
24: moduleInstance.RegisterModelBinders(modelBinders);
25:
26: this.container.RegisterInstance(modulesLoaded);
27:
28: //...
29: }
30: }
31:
32: routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
33:
34: routes.LoadFromModules(modulesLoaded);
35:
36: routes.LoadCatchAllFromModules(modulesLoaded);
37:
這里需要注意各個方法的調(diào)用順序,這一點(diǎn)可以查看PluginsModule的源碼。我們一般會認(rèn)為Initialize應(yīng)該被最先調(diào)用,但PluginsModule類的Initialize方法將會用到RegisterWithContainer方法中進(jìn)行的某些配置,所以RegisterWithContainer方法應(yīng)該最新被調(diào)用。
二、IOxiteDataProvider
Module不一定要實(shí)現(xiàn)IOxiteDataProvider。當(dāng)需要制定Module內(nèi)部數(shù)據(jù)訪問方式時,通過外部配置以及讓Module實(shí)現(xiàn)IOxiteDataProvider可以達(dá)到。
另外,Oxite配置的靈活性使得Module也可以不實(shí)現(xiàn)IOxiteDataProvider接口,而新建一個類來實(shí)現(xiàn)。目前Oxite版本中實(shí)現(xiàn)在了Module本身中。
通過這樣的配置,使得各個Module可以擁有自己特有的數(shù)據(jù)訪問方式,甚至于每個Module可以放在不同的數(shù)據(jù)庫或不同類型的數(shù)據(jù)庫中。在數(shù)據(jù)訪問上說,去除了與系統(tǒng)本身的耦合。
在“Oxite分析之初始化”一文中曾提到過web.config配置文件的自定義"oxite"配置節(jié)點(diǎn)。具體配置已經(jīng)移至單獨(dú)的Oxite.config,下面看看它的內(nèi)容:
1: <oxite>
2: <connectionStrings>
3: <add name="Sql" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Oxite.Database;Integrated Security=true;"/>
4: <!--<add name="Sql" connectionString="Data Source=.\SQLEXPRESS;AttachDBFileName=|DataDirectory|Oxite.Database.mdf;Integrated Security=true;User Instance=true;"/>-->
5: </connectionStrings>
6: <dataProviders defaultConnectionString="Sql">
7: <add name="Membership" type="Oxite.Modules.Membership.MembershipModule, Oxite" category="LinqToSql" />
8: <add name="Tags" type="Oxite.Modules.Tags.TagsModule, Oxite" category="LinqToSql" />
9: <add name="Comments" type="Oxite.Modules.Comments.CommentsModule, Oxite" category="LinqToSql" />
10: <add name="Plugins" type="Oxite.Modules.Plugins.PluginsModule, Oxite" category="LinqToSql" />
11: <add name="Blogs" type="Oxite.Modules.Blogs.BlogsModule, Oxite.Blogs" category="LinqToSql" />
12: <add name="CMS" type="Oxite.Modules.CMS.CMSModule, Oxite.CMS" category="LinqToSql" />
13: <add name="Conferences" type="Oxite.Modules.Conferences.ConferencesModule, Oxite.Conferences" category="LinqToSql" />
14: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" category="LinqToSql" />
15: </dataProviders>
16: <modules>
17: <add name="AspNetCache" type="Oxite.Modules.AspNetCache.AspNetCacheModule, Oxite" />
18: <add name="Membership" type="Oxite.Modules.Membership.MembershipModule, Oxite" dataProvider="Membership" />
19: <add name="FormsAuthentication" type="Oxite.Modules.FormsAuthentication.FormsAuthenticationModule, Oxite" />
20: <add name="Core" type="Oxite.Modules.Core.OxiteModule, Oxite" />
21: <add name="Tags" type="Oxite.Modules.Tags.TagsModule, Oxite" dataProvider="Tags" />
22: <add name="Files" type="Oxite.Modules.Files.FilesModule, Oxite" />
23: <add name="Comments" type="Oxite.Modules.Comments.CommentsModule, Oxite" dataProvider="Comments" />
24: <add name="Plugins" type="Oxite.Modules.Plugins.PluginsModule, Oxite" dataProvider="Plugins" />
25: <add name="Blogs" type="Oxite.Modules.Blogs.BlogsModule, Oxite.Blogs" dataProvider="Blogs" />
26: <add name="CMS" type="Oxite.Modules.CMS.CMSModule, Oxite.CMS" dataProvider="CMS" />
27: <add name="Conferences" type="Oxite.Modules.Conferences.ConferencesModule, Oxite.Conferences" dataProvider="Conferences" enabled="false" />
28: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" dataProvider="Search" />
29: <add name="Site" type="OxiteSite.App_Code.Modules.OxiteSite.OxiteSiteModule" />
30: </modules>
31: </oxite>
modules節(jié)點(diǎn)下的元素,有的具有dataProvider屬性(查看OxiteModuleConfigurationElement類的DataProvider屬性的定義)。比如name為"Search"的元素,dataProvider為"Search":
1: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" dataProvider="Search" />
其對應(yīng)的是dataProviders節(jié)點(diǎn)下的name為"Search"的元素:
1: <add name="Search" type="Oxite.Modules.Search.SearchModule, Oxite" category="LinqToSql" />
接著請看ModulesLoaded類的Load方法:
1: public IOxiteModule Load(OxiteConfigurationSection config, OxiteModuleConfigurationElement module)
2: {
3: if (module == null || !module.Enabled) return null;
4:
5: foreach (OxiteDataProviderConfigurationElement dataProvider in config.Providers)
6: {
7: if (dataProvider.Name == module.DataProvider)
8: {
9: Type dataProviderType = Type.GetType(dataProvider.Type);
10:
11: if (dataProviderType == null)
12: throw new TypeLoadException(string.Format("Could not load type '{0}'.", dataProvider.Type));
13:
14: IOxiteDataProvider dataProviderInstance = container.Resolve(dataProviderType) as IOxiteDataProvider;
15:
16: if (dataProviderInstance != null)
17: dataProviderInstance.ConfigureProvider(config, dataProvider, container);
18:
19: break;
20: }
21: }
22:
23: //…
25: }
OxiteConfigurationSection config為整個oxite配置節(jié)點(diǎn);OxiteModuleConfigurationElement module為oxite配置節(jié)點(diǎn)modules下的一個元素(比如name為"Search"的元素)
上述代碼的第5行開始,遍歷oxite.config配置中的dataProviders節(jié)點(diǎn)下的dataProvider元素,如果元素的name值等于module的dataProvider屬性,通過dataProvider元素的type屬性,獲取類型。接著判斷類型是否真的繼承于IOxiteDataProvier。如果是,調(diào)用類型的ConfigureProvider方法。
如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答??! 點(diǎn)擊進(jìn)入論壇