这个部分属于Weapsy的的展示层,里面涉及到很多的概念和技术.
概念:Entity,ViewModel,Task,MappingExtension,Framework,Install,Resource,Themes,Controller等。
技术:AutoMapper,Ninject。暂时主要用到这2个。外加一个Linq to Object的查询让我感觉到Linq真的很强大。
这个Linq下面会讲到,别急。。
因Global.asax做为整个应用程序的入口,起着非常重要的作用,所以这个部分从Global.asax开始。
从下图可以看出整个Gloabl的内容:
它继承了NinjectHttpApplication类并重写了CreateKernel,OnApplicationStarted方法。
CreateKernel用于加载当前的程序集并返回Ninject需要的核心。所以这里出现一个代表当前程序集--
ExectingAssembly属性也就非常正常了。此属性由构造函数进行初始化。代码如下:
public MvcApplication() { // cache executing assembly for future use ExecutingAssembly = Assembly.GetExecutingAssembly(); }
OnApplictaionStarted用于运行一启动任务,MVC路由注册、过滤器的设置和MVC视图引擎的修改。代码如下:
protected override void OnApplicationStarted() { base.OnApplicationStarted(); new StandardKernel(new InjectionModule()).Get<IInstallService>().EnsureInstalled(); ExecuteStartupTasks(); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new RazorViewEngine()); }
其中:
1 InjectionMoudle方法用于绑定接口和实现类,并通过Get,GetAll等方式来获取对应接口的对象,好处多多~~
Bind<IInstallService>().To<InstallService>();//绑定IInstallService到InstallService
在获取IInstallService具体实现类的实例后,进行服务的安装:调用EnsureInstalled并进行一些用户、角色、配置、模块定义、插件、主题、模板、站点信息、语言、邮件模板、邮箱帐号、页面、模块等一系列基础信息的安装。
2 ExecuteStartupTasks用于执行当前程序中所有实现IStartupTask接口的类。这个东西不做太多业务上的介绍,主要说下如何实现
- 获取当前运行程序集的路径,即: DLL的文件路径。
- 然后获取路径之下所有以*.dll为后缀的文件。
- 遍历并加载一个个DLL文件。
- 查询所有的继承IStartupTask类。这里使用Linq实现,非常的不错哇。
- 找到类后,创建改类的实例,并放入执行任务集合中。
Linq的代码:
var query = from t in asm.GetTypes() where t.IsClass && //这个对象必须是类 t.GetInterface(typeof(IStartupTask).FullName) != null select t; // add types to list of startup tasks foreach (Type type in query) { startupTasks.Add( (IStartupTask)Activator.CreateInstance(type) ); }
Activator不明白的可以看这里:Activator文档
3 ExecuteStartupTasks后面3句代码用来注册过滤器,路由。因和具体的控制器、路由相关,暂不解释。
4 倒数第二句用于清除视图引擎的配置。默认情况是Razor和ASPX均可。这里只支持Razor的视图引擎。
注: 这里的 Razor视图引擎继承自系统的Razor引擎。
相关代码:
public class RazorViewEngine : System.Web.Mvc.RazorViewEngine { public RazorViewEngine() { string ThemeName = WeapsyGlobal.Current.Theme.Folder; base.MasterLocationFormats = new string[] { "~/Themes/" + ThemeName + "/Views/Shared/{0}.cshtml", "~/Themes/" + ThemeName + "/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/Views/{1}/{0}.cshtml" }; base.AreaMasterLocationFormats = new string[] { "~/Themes/" + ThemeName + "/Areas/{2}/Views/Shared/{0}.cshtml", "~/Themes/" + ThemeName + "/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.cshtml" }; base.ViewLocationFormats = new string[] { "~/Themes/" + ThemeName + "/Views/{1}/{0}.cshtml", "~/Themes/" + ThemeName + "/Views/Shared/{0}.cshtml", "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/Views/Home/Index.cshtml" }; base.AreaViewLocationFormats = new string[] { "~/Themes/" + ThemeName + "/Areas/{2}/Views/{1}/{0}.cshtml", "~/Themes/" + ThemeName + "/Areas/{2}/Views/Shared/{0}.cshtml", "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; base.PartialViewLocationFormats = base.ViewLocationFormats; base.AreaPartialViewLocationFormats = base.AreaViewLocationFormats; } }
Note:Global.asax中虽然没有多少方法,但是内容还是很多的,特别是服务的安装,启动任务的执行需要自己多多研究。