700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 如何用MEF实现Asp.Net MVC框架

如何用MEF实现Asp.Net MVC框架

时间:2022-07-21 18:10:49

相关推荐

如何用MEF实现Asp.Net MVC框架

<?xml version="1.0" encoding="UTF-8"?> 目的是实现多个Controller类,View在不同的dll里, 供一个大框架调用。

原理:1.用MEF实现各个Controller类的dll的导出和导入。2.用[PartCreationPolicy(CreationPolicy.NonShared)]标记来实现每个Controller在Export时重新创建实例3.继承DefaultControllerFactory来创建我们自定义的ControllerFactory。4.用ControllerBuilder.Current.SetControllerFactory 调用我们创建的ControllerFactory类5.继承RazorViewEngine, 实现我们自定义的ViewEngine。6.用ViewEngines.Engines.Clear();

ViewEngines.Engines.Add();

7.继承VirtualPathProvider和VirtualFile实现我们自定义的VirtualPath, 来查找各个子模块的资源(View)

8.用System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider();

9.子模块中的改变,1:每个View的属性设置为Embedded Resource, 每个Controller类有Export和PartCreationPolicy属性。

1.修改Controller类:继承IPACSModule,添加[PartCreationPolicy(CreationPolicy.NonShared)]标签

[PartCreationPolicy(CreationPolicy.NonShared)]

public class PatientAdminController : Controller,IPACSModule

2.修改View的属性Build Action为Embedder Resource

3.修改XXXX.Cshtml, 添加@inherits System.Web.Mvc.WebViewPage, 如果Cshtml中有@model, 如:@model IEnumerable<UIH.PACS.Workstation.PatientAdmin.Models.OrderViewModel>

改为

@using System.Web.WebPages;

@using System.Web.Mvc;

@using System.Web.Mvc.Ajax;

@using System.Web.Mvc.Html;

@using System.Web.Routing;

@inherits System.Web.Mvc.WebViewPage<IEnumerable<UIH.PACS.Workstation.PatientAdmin.Models.OrderViewModel>>

@using (Ajax.BeginForm("Submit", new AjaxOptions { UpdateTargetId = "main" }))

{

}

具体代码:

1.框架层的实现:

using System; using System.Collections.Generic; using position; using position.Hosting; using System.IO; using System.Linq; using System.Reflection; using System.Web; using System.Web.Caching; using System.Web.Hosting; using System.Web.Mvc; using System.Web.WebPages; using UIH.PACS.Workstation.AddIn.Interface; using System.Globalization; using position.Primitives; namespace UIH.mon {public class ExtensionHelper{ [ImportMany(AllowRecomposition = true)] public IEnumerable<IPACSModule> PACSModules { get; set; } public CompositionContainer _container; public void Initialize() { AggregateCatalog catalog = new AggregateCatalog();catalog.Catalogs.Add(new AggregateCatalog( new DirectoryCatalog(System.bine(AppDomain.CurrentDomain.BaseDirectory, "bin")), new AssemblyCatalog(typeof(Controller).Assembly), new TypeCatalog(typeof(IPACSModule)) ));_container = new CompositionContainer(catalog);try { poseParts(this); } catch (CompositionException ex) { throw new SystemException(ex.Message, ex); }//Set Custom Controller ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());//Set Custom ViewEngine ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new CustomViewEngine());//Register a virtual path provider System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new CustomVirtualPathProvider()); }} public class CustomControllerFactory : DefaultControllerFactory{ protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) { //{call AddIn controller var export = MvcApplication._extHelper._container.GetExports<IPACSModule>() .Where(e => e.Value.GetType().Equals(controllerType)) .FirstOrDefault();if (null != export) { return export.Value as Controller; } else { return base.GetControllerInstance(requestContext, controllerType); } //end AddIn controller} } public override void ReleaseController(IController controller) { IDisposable disposable = controller as IDisposable; if (disposable != null) { disposable.Dispose(); }//base.ReleaseController(controller); }} public class CustomViewEngine : RazorViewEngine{ public CustomViewEngine() { base.AreaViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml"};base.AreaMasterLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" };base.AreaPartialViewLocationFormats = new string[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" };base.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/PACSModule/Views/{1}/{0}.cshtml", "~/PACSModule/Views/Shared/{0}.cshtml"};base.MasterLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/PACSModule/Views/{1}/{0}.cshtml", "~/PACSModule/Views/Shared/{0}.cshtml", "~/PACSModule/Views/{0}.cshtml"};base.PartialViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/PACSModule/Views/{1}/{0}.cshtml", "~/PACSModule/Views/Shared/{0}.cshtml", "~/PACSModule/Views/{0}.cshtml"};base.FileExtensions = new string[] { "cshtml"}; } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { var dllName = controllerContext.Controller.GetType().Module.Name;return base.CreatePartialView(controllerContext, partialPath.Replace("PACSModule", dllName)); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var dllName = controllerContext.Controller.GetType().Module.Name;RazorView razorView = new RazorView(controllerContext, viewPath.Replace("PACSModule", dllName), masterPath, false, base.FileExtensions, base.ViewPageActivator); return razorView; } protected override bool FileExists(ControllerContext controllerContext, string virtualPath) { var dllName = controllerContext.Controller.GetType().Module.Name;try { return base.FileExists(controllerContext, virtualPath.Replace("PACSModule", dllName));} catch (System.Exception ex) { return false; } }} public class CustomView : RazorView{ public CustomView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions, IViewPageActivator viewPageActivator) : base(controllerContext, viewPath, layoutPath, runViewStartPages, viewStartFileExtensions, viewPageActivator) { } protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance)

{ if (writer == null) { throw new ArgumentNullException("writer"); }WebViewPage layoutPath = instance as WebViewPage; if (layoutPath == null) { throw new InvalidOperationException("WebViewPage is null."); }layoutPath.VirtualPath = this.ViewPath; layoutPath.ViewContext = viewContext; layoutPath.ViewData = viewContext.ViewData; layoutPath.InitHelpers();WebPageRenderingBase viewStartPage = null; if (this.RunViewStartPages) { try { viewStartPage = StartPage.GetStartPage(layoutPath, "_ViewStart", new string[] { "cshtml" }); } catch { viewStartPage = GetStartPage(layoutPath, "~/Views/_ViewStart.cshtml"); } }WebPageContext pageContext = new WebPageContext(null, null, null); layoutPath.ExecutePageHierarchy(pageContext, writer, viewStartPage); } private static StartPage GetStartPage(WebViewPage childPage, string startPagePath) { StartPage startPage = null;startPage = childPage.VirtualPathFactory.CreateInstance(startPagePath) as StartPage; startPage.VirtualPath = startPagePath; startPage.ChildPage = childPage; startPage.VirtualPathFactory = childPage.VirtualPathFactory;return startPage; }

} public class CustomVirtualPathProvider : VirtualPathProvider{ private bool IsAppResourcePath(string virtualPath) { String checkPath = VirtualPathUtility.ToAppRelative(virtualPath);return checkPath.StartsWith("~/UIH", StringComparison.InvariantCultureIgnoreCase); } public override bool FileExists(string virtualPath) { return (IsAppResourcePath(virtualPath) || base.FileExists(virtualPath)); } public override VirtualFile GetFile(string virtualPath) { if (IsAppResourcePath(virtualPath)) { return new CustomVirtualFile(virtualPath); } else { return base.GetFile(virtualPath); } } public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart) { if (IsAppResourcePath(virtualPath)) { string[] parts = virtualPath.Split('/'); string assemblyName = parts[1]; Assembly asm = Assembly.Load(assemblyName.Replace(".DLL", "").Replace(".dll", "")); return new CacheDependency(asm.Location); } else { return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); } }} public class CustomVirtualFile : VirtualFile{ private string _virtualPath = ""; public CustomVirtualFile(string virtualPath) : base(virtualPath) { _virtualPath = VirtualPathUtility.ToAppRelative(virtualPath); } public override System.IO.Stream Open() { string[] parts = _virtualPath.Split('/'); string assemblyName = parts[1]; string resourceName = assemblyName.Replace(".DLL", "").Replace(".dll", "") + "." + parts[2] + "." + parts[3] + "." + parts[4]; //"UIH.PACS.Workstation.AddIn.Demo."+"Views." + "Controller." + "Action.cshtml"assemblyName = bine(HttpRuntime.BinDirectory, assemblyName);System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(assemblyName); if (null != assembly) { Stream resourceStream = assembly.GetManifestResourceStream(resourceName); return resourceStream; }return null; }} }

2.IPACSModule就是空接口, 用来各个子模块的controller的Export

[InheritedExport(typeof(IPACSModule))]public interface IPACSModule{ }

3.子模块的Controller使用

[PartCreationPolicy(CreationPolicy.NonShared)]public class TestController : Controller, IPACSModule{ // // GET: /Test/ public ActionResult Index() { return View(); } }

4. 子模块的View的使用

@inherits System.Web.Mvc.WebViewPage @{ViewBag.Title = "Demo/Test/Index.cshtml"; } <div class="content-wrapper"> This is Demo's index view for Test </div>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。