zoukankan      html  css  js  c++  java
  • MVC 插件式开发

    MVC 插件式开发

    在开发一个OA系统是,我们可能遇到 A模块. B模块 .C模块,这也模块组成一个完整的系统,买给客服。
    现在又有一个客服要我们做一个OA系统,唉我们发现,跟上一个OA系统差不多,但没有C模块。怎么办?

    修改源码,系统简单还好,但是一系统复杂到一定程度,修改源码改这改这就像重写了!

    怎么办,MVC插件式开发帮你解决问题,先看演示,再看代码。

    CCAV.WebSite 是主站,引用 CCAV.Modules.Category
     CCAV.Modules.Category 就像当于一个模块,具体看演示。


    通过主站可以访问到CCAV.Modules.Category 的控制器,如果 主站移除 对 CCAV.Modules.Category引用 将访问不到  CCAV.Modules.Category 你的控制器。
    这样刚才的问题就解决了!

    现在看一下主要代码。

    复制代码
     public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                VirtualPathConfig.Register();
    ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new RazorViewEngineExpand()); AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
    复制代码
    VirtualPathConfig.Register();/ 注册虚拟路径提供者以实现模块化拆分
    ViewEngines.Engines.Clear(); 移除全部视图引擎.....
    ViewEngines.Engines.Add(new RazorViewEngineExpand()); 假如自己的视图引擎
    复制代码
      /// <summary>
        /// 虚拟路径提供者配置
        /// </summary>
        public class VirtualPathConfig
        {
            /// <summary>
            /// 注册虚拟路径提供者以实现模块化拆分
            /// </summary>
            public static void Register()
            {
                GriffinVirtualPathProvider.Current.Add(new StaticFileProvider(new PluginFileLocator()));
                GriffinVirtualPathProvider.Current.Add(new ViewFileProvider(new PluginFileLocator(), new ExternalViewFixer()));
    
                HostingEnvironment.RegisterVirtualPathProvider(GriffinVirtualPathProvider.Current);
            }
        }
    复制代码
       HostingEnvironment.RegisterVirtualPathProvider(GriffinVirtualPathProvider.Current);注册新的虚拟路径提供者:
    StaticFileProvider  提供对图片、脚本、样式表等静态文件的访问
    ViewFileProvider   视图文件提供
    StaticFileProvider  ViewFileProvider  继承于 IViewFileProvider 看他们的内部实现

    复制代码
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Caching;
    using System.Web.Hosting;
    
    namespace ItCast.Foundation.Hosting
    {
        /// <summary>
        /// 自定义的虚拟路径提供者。
        /// </summary>
        public class GriffinVirtualPathProvider : VirtualPathProvider
        {
            private static readonly GriffinVirtualPathProvider Instance = new GriffinVirtualPathProvider();
            private readonly List<IViewFileProvider> fileProviders = new List<IViewFileProvider>();
    
            /// <summary>
            /// 初始化 GriffinVirtualPathProvider 类的新实例。
            /// </summary>
            private GriffinVirtualPathProvider()
            {
            }
    
            /// <summary>
            /// 获得实例。
            /// </summary>
            public static GriffinVirtualPathProvider Current
            {
                get
                {
                    return Instance;
                }
            }
    
            /// <summary>
            /// 添加一个新的文件提供者。
            /// </summary>
            /// <param name="fileProvider">文件提供者。</param>
            public void Add(IViewFileProvider fileProvider)
            {
                if (fileProvider == null)
                {
                    throw new ArgumentNullException("fileProvider");
                }
    
                this.fileProviders.Add(fileProvider);
            }
    
            /// <summary>
            /// 获取一个值,该值指示文件是否存在于虚拟文件系统中。
            /// </summary>
            /// <returns>
            /// 如果该文件存在于虚拟文件系统中,则为 true;否则为 false。
            /// </returns>
            /// <param name="virtualPath">虚拟文件的路径。</param>
            public override bool FileExists(string virtualPath)
            {
                foreach (var provider in this.fileProviders)
                {
                    if (provider.FileExists(virtualPath))
                    {
                        return true;
                    }
                }
    
                return base.FileExists(virtualPath);
            }
    
            /// <summary>
            /// 基于指定的虚拟路径创建一个缓存依赖项。
            /// </summary>
            /// <param name="virtualPath">主虚拟资源的路径。</param>
            /// <param name="virtualPathDependencies">一个路径数组,路径指向主要虚拟资源需要的其他资源。</param>
            /// <param name="utcStart">虚拟资源被读取的 UTC 时间。</param>
            /// <returns>
            /// 指定虚拟资源的 <see cref="T:System.Web.Caching.CacheDependency"/> 对象。
            /// </returns>
            public override CacheDependency GetCacheDependency(
                string virtualPath,
                IEnumerable virtualPathDependencies,
                DateTime utcStart)
            {
                foreach (var provider in this.fileProviders)
                {
                    var result = provider.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
                    if (result is NoCache)
                    {
                        return null;
                    }
    
                    if (result != null)
                    {
                        return result;
                    }
                }
    
                return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
            }
    
            /// <summary>
            /// 返回一个用于指定虚拟路径的缓存键。
            /// </summary>
            /// <param name="virtualPath">虚拟资源的路径。</param>
            /// <returns>
            /// 所指定虚拟资源的缓存键。
            /// </returns>
            public override string GetCacheKey(string virtualPath)
            {
                foreach (
                    var result in
                        this.fileProviders.Select(provider => provider.GetCacheKey(virtualPath)).Where(result => result != null))
                {
                    return result;
                }
    
                return base.GetCacheKey(virtualPath);
            }
    
            /// <summary>
            /// 从虚拟文件系统中获取一个虚拟文件。
            /// </summary>
            /// <param name="virtualPath">虚拟文件的路径。</param>
            /// <returns>
            /// <see cref="T:System.Web.Hosting.VirtualFile"/> 类的子代,该子代表示虚拟文件系统中的一个文件。
            /// </returns>
            public override VirtualFile GetFile(string virtualPath)
            {
                foreach (var provider in this.fileProviders)
                {
                    var file = provider.GetFile(virtualPath);
                    if (file != null)
                    {
                        return file;
                    }
                }
    
                return base.GetFile(virtualPath);
            }
    
            /// <summary>
            /// 返回指定虚拟路径的哈希值。
            /// </summary>
            /// <param name="virtualPath">主虚拟资源的路径。</param>
            /// <param name="virtualPathDependencies">一个路径数组,所包含的路径指向主要虚拟资源需要的其他虚拟资源。</param>
            /// <returns>
            /// 指定虚拟路径的哈希值。
            /// </returns>
            public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies)
            {
                foreach (
                    var result in
                        this.fileProviders.Select(provider => provider.GetFileHash(virtualPath, virtualPathDependencies)).Where(
                            result => result != null))
                {
                    return result;
                }
    
                return base.GetFileHash(virtualPath, virtualPathDependencies);
            }
        }
    }
    复制代码

    一开始进入这个方法 FileExists 判断文件是否存在,春在这位true

    复制代码
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.Hosting;
    
    namespace ItCast.Foundation.Hosting
    {
        /// <summary>
        /// Locator which loads views using the project structure to enable runtime view edits.
        /// </summary>
        /// <remarks>
        /// Works as long as you have used the structure which is described in the namespace documentation.
        /// </remarks>
        public class PluginFileLocator : IViewFileLocator
        {
            private readonly string basePath;
            private IEnumerable<string> allowedFileExtensions;
    
            /// <summary>
            /// Initializes a new instance of the <see cref="PluginFileLocator"/> class.
            /// </summary>
            public PluginFileLocator()
            {
                this.basePath = Path.GetFullPath(HostingEnvironment.MapPath("~") + @"..");
            }
    
            #region IViewFileLocator Members
    
            /// <summary>
            /// Get full path to a file
            /// </summary>
            /// <param name="uri">Requested uri</param>
            /// ~/Admin/Content/themes/Blog/Site.css            
            /// ~/Admin/Scripts/Blog/BlogAjax.js
            /// ~/Admin/Views/Blog/Home/Index.cshtml
            /// ~/Content/themes/Blog/Site.css
            /// ~/Scripts/Blog/BlogAjax.js
            /// ~/Views/Blog/Home/Index.cshtml
            /// <returns>
            /// Full disk path if found; otherwise <c>null</c>.
            /// </returns>
            public string GetFullPath(string uri)
            {
                var pathConfigs = PluginPathConfig.GetConfigs();
                var fixedUri = uri;
                if (fixedUri.StartsWith("~"))
                {
                    fixedUri = VirtualPathUtility.ToAbsolute(uri);
                }
    
                var path = string.Empty;
                foreach (var pattern in pathConfigs.Keys)
                {
                    var regex = new Regex(pattern, RegexOptions.IgnoreCase);
                    var match = regex.Match(fixedUri);
                    if (match.Length > 0)
                    {
                        path = Regex.Replace(fixedUri, pattern, pathConfigs[pattern], RegexOptions.IgnoreCase);
                        path = string.Format("{0}\{1}", this.basePath, path.Replace('/', '\'));
                        break;
                    }
                }
    
                if (!this.IsFileAllowed(uri))
                {
                    return null;
                }
    
                if (File.Exists(path))
                {
                    return path;
                }
    
                return null;
            }
    
            /// <summary>
            /// Set extensions that are allowed to be scanned.
            /// </summary>
            /// <param name="fileExtensions">File extensions without the dot.</param>
            public void SetAllowedExtensions(IEnumerable<string> fileExtensions)
            {
                this.allowedFileExtensions = fileExtensions;
            }
    
            /// <summary>
            /// determins if the found embedded file might be mapped and provided.
            /// </summary>
            /// <param name="fullPath">Full path to the file</param>
            /// <returns><c>true</c> if the file is allowed; otherwise <c>false</c>.</returns>
            protected virtual bool IsFileAllowed(string fullPath)
            {
                if (fullPath == null)
                {
                    throw new ArgumentNullException("fullPath");
                }
    
                var extension = fullPath.Substring(fullPath.LastIndexOf('.') + 1);
                return this.allowedFileExtensions.Any(x => x == extension.ToLower());
            }
    
            #endregion
        }
    }
    复制代码

    然后再获取缓存

    复制代码
        /// <summary>
            /// 返回一个用于指定虚拟路径的缓存键。
            /// </summary>
            /// <param name="virtualPath">虚拟资源的路径。</param>
            /// <returns>
            /// 所指定虚拟资源的缓存键。
            /// </returns>
            public override string GetCacheKey(string virtualPath)
            {
                foreach (
                    var result in
                        this.fileProviders.Select(provider => provider.GetCacheKey(virtualPath)).Where(result => result != null))
                {
                    return result;
                }
    
                return base.GetCacheKey(virtualPath);
            }
    复制代码

    缓存没找到,从虚拟文件系统中获取一个虚拟文件

    复制代码
      /// <summary>
            /// 从虚拟文件系统中获取一个虚拟文件。
            /// </summary>
            /// <param name="virtualPath">虚拟文件的路径。</param>
            /// <returns>
            /// <see cref="T:System.Web.Hosting.VirtualFile"/> 类的子代,该子代表示虚拟文件系统中的一个文件。
            /// </returns>
            public override VirtualFile GetFile(string virtualPath)
            {
                foreach (var provider in this.fileProviders)
                {
                    var file = provider.GetFile(virtualPath);
                    if (file != null)
                    {
                        return file;
                    }
                }
    
                return base.GetFile(virtualPath);
            }
    复制代码

    就是这样一个流程..................................

    资料:http://msdn.microsoft.com/zh-cn/library/system.web.hosting.virtualpathprovider(VS.80).aspx

    源码:http://pan.baidu.com/s/1pJsgaIf

    你可以看这篇文章:http://www.cnblogs.com/liek/p/3898168.html帮助你跟好的理解。

  • 相关阅读:
    梅特卡夫法则(Metcalfe's law)
    jffs2reset 实现分析
    uhttpd配置文件分析
    疑问????
    ubuntu 修改root密码
    原始套接字
    位操作
    linux命令readlink
    awk 中 FS的用法
    Python做简单爬虫(urllib.request怎么抓取https以及伪装浏览器访问的方法)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3900183.html
Copyright © 2011-2022 走看看