场景: 实现依赖倒置,使用Managed Extensibility Framework(MEF)是扩展性管理框架
准备: 定义好的接口,接口的实现类,引入命名空间,System.ComponentModel.Composition
[在控制台中的实现]
--------------------------------------------------------- namespace ConsoleApplicationDemo.IContract { public interface IExpor { string GetTxt(string name,string password); } }
---------------------------------------------------------------
using ConsoleApplicationDemo.IContract; using System.ComponentModel.Composition; namespace ConsoleApplicationDemo.Impl { [Export("ex1",typeof(IExpor))] public class Demo1 : IExpor { public string GetTxt(string name, string password) { return string.Format("{0}---{1}", name, password); } } } ---------------------------------------------------------------
using ConsoleApplicationDemo.IContract; using System.ComponentModel.Composition; namespace ConsoleApplicationDemo.Impl2 { [Export("ex2",typeof(IExpor))] public class Demo1:IExpor { public string GetTxt(string name, string password) { return string.Format("****{0}^^^^^^^{1}",name,password); } } }
---------------------------------------------------------------
使用到接口的类:
using System.ComponentModel.Composition; using ConsoleApplicationDemo.IContract; namespace ConsoleApplication.Demo { [Export] class DemoExpor { [Import("ex1")] public IExpor Expor { get; set; } [Import("ex2")] public IExpor Expor2 { get; set; } } }
---------------------------------------------------------------
调用:
static void Main(string[] args) { AggregateCatalog catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(Directory.GetCurrentDirectory())); catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); CompositionContainer tainer = new CompositionContainer(catalog); DemoExpor dd= tainer.GetExportedValue<DemoExpor>(); Console.WriteLine(dd.Expor.GetTxt("N@ME", "P@$$W0RD")); Console.WriteLine(dd.Expor2.GetTxt("N@ME", "P@$$W0RD")); Console.Read(); }
---------------------------------------------------------------
结果:
----------------------------------------------------------------------------------
MVC4 中MEF实现依赖倒置:
准备:接口,实现类,引入命名空间,System.ComponentModel.Composition
--------------------------------------------------------------- namespace MEFIOCDemo { public interface IAccountSiteContract { string Test(string name, string password); } }
using System.ComponentModel.Composition; using System.ComponentModel.Composition.Primitives; --------------------------------------------------------------- namespace MEFIOCDemo.Impl { [Export(typeof(IAccountSiteContract))] public class AccountContract:IAccountSiteContract { public string Test(string name, string password) { return string.Format("Name:{0}Password:{1}", name, password); } } }
---------------------------------------------------------------
//创建一个实现 IDependencyResolver 接口的MEF实现类 //Web应用程序的无状态性,即每次访问都是独立进行的,所以IOC组件产生的对象实例也必须唯一 //否则不同用户的操作就可能串线,产生相互干扰。 //使用HttpContext.Current.Items集合来保存 组合容器CompositionContainer的实例,以使每个用户的数据保持独立且同一用户的同一个Http请求中使用同一对象实例。 //另外考虑到可能会有某种情况下需要手动获取组合容器中的实例,把组合容器缓存到了当前上下文中的Application中。 //(参考 http://www.cnblogs.com/guomingfeng/archive/2013/05/21/mvc-ioc-mef.html MVC实用架构设计(二)——使用MEF实用IOC(依赖倒置) ) using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.ComponentModel.Composition.Primitives; using System.Web.Mvc; using System.Web; namespace MEFIOCDemo.IOC { public class IOCDemo:IDependencyResolver { private ComposablePartCatalog _catalog; private const string iocdemokey = "iocdemoKey"; public IOCDemo(ComposablePartCatalog log) { _catalog = log; } public CompositionContainer Container { get { if (!HttpContext.Current.Items.Contains(iocdemokey)) { HttpContext.Current.Items.Add(iocdemokey, new CompositionContainer(_catalog)); } CompositionContainer triner = (CompositionContainer)HttpContext.Current.Items[iocdemokey]; HttpContext.Current.Application["Container"] = triner; return triner; } } public object GetService(Type serviceType) { string contractName = AttributedModelServices.GetContractName(serviceType); return Container.GetExportedValueOrDefault<object>(contractName); } public IEnumerable<object> GetServices(Type serviceType) { return Container.GetExportedValues<object>(serviceType.FullName); } } }
---------------------------------------------------------------
在路由配置中初始化
using MEFIOCDemo.IOC; using System.ComponentModel.Composition.Hosting; namespace DemoMVC4 { // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明, // 请访问 http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); DirectoryCatalog catalog = new DirectoryCatalog (AppDomain.CurrentDomain.SetupInformation.PrivateBinPath); IOCDemo demod = new IOCDemo(catalog); DependencyResolver.SetResolver(demod); } } }
---------------------------------------------------------------
使用:
using System.ComponentModel.Composition; namespace DemoMVC4.Controllers { [Export] public class HomeController : Controller { [Import] private MEFIOCDemo.IAccountSiteContract accountContract; public ActionResult Index() { ViewBag.Title = accountContract.Test("ABC","p@ssw0rd"); return View(); } } }
页面上:
@{ ViewBag.Title = ViewBag.Title; } <h2>@ViewBag.Title</h2>
结果: