ExportAttribute, ImportAttribute, CompositionContainer and MEF in ASP.NET MVC 3

来源:互联网 发布:淘宝助理mac版本 编辑:程序博客网 时间:2024/05/20 12:46

Introduction

本文阐述了托管扩展框架Managed Extensibility Framework在ASP.NET MVC 3的应用。本文不处理MEFASP.NET MVC 3系统的复杂性

Section 1 MEF Basics

以微软观点,MEF不是控制系统的一个反演。然而MEF提供控制系统的反演能力
MEF中三个基本结构exportattribute importattributecompositioncontainer
使用ExportAttribute特性标记以下的代码:
  • class
  • field
  • property
  • indexer
  • method
使用ImportAttribute特性标记以下的代码:
  • field
  • property
  • indexer
  • argument.
例1 — 使用ExportAttribute标记类:
[ExportAttribute]public class A{  public void ShowMessage()  {    Console.WriteLine("this is class A");  }}
例2 — 使用ImportAttribute标记属性:
public class B{  [ImportAttribute]  public A PropertyA { get; set; }}
例3 — 使用ExportAttribute标记方法:
public class C{  [ExportAttribute]  public void DoSomething()  {   }}
另一个MEF 构造是CompositionContainer 类. 把 CompositionContainer应用在 标记了 ExportAttribute 或ImportAttribute特性的代码上. CompositionContainer 类尝试把exports 匹配 imports.
例4演示了一个完整的程序,定义标记了exportattribute的A类或importattribute的B类。compositioncontainer接收A和B类的实例该compositioncontainer返回一个组成部分。我选择用控制台应用程序实现。不像一个ASP.NET MVC 3应用程序,控制台应用程序只需要一个文件。这允许你容易看到MEF结构的作用
namespace MefExample4{  using System;  using System.ComponentModel.Composition;  using System.ComponentModel.Composition.Hosting;  [ExportAttribute]  public class A  {    public void ShowMessage()    {      Console.WriteLine("this is class A");    }  }  [ExportAttribute]  public class B  {    [ImportAttribute]    public A PropertyA { get; set; }  }  class Program  {    static void Main(string[] args)    {      // Declare a composition container.      CompositionContainer compositionContainer = new CompositionContainer();      // Feed the container instances of A and B.      compositionContainer.ComposeParts(new A(), new B());      // Retrieve the composed part.      B b = compositionContainer.GetExportedValueOrDefault<B>();      // Use the imported construct of B.      b.PropertyA.ShowMessage();    }  }}

Section 2- MEF in ASP.NET MVC 3

1. You mark pieces of code that MEF should take care of with ExportAttributes and ImportAttributes.

Example 8 —MessageSource类 标记 ExportAttribute
namespace MefMvc01{  using System.ComponentModel.Composition;  [ExportAttribute]  public class MessageSource  {    public MessageSource()    {      this.Message = "this message is from MessageSource";    }    public string Message { get; private set; }  }}

Example 9 —  HomeController类标记 ExportAttribute
namespace MefMvc01.Controllers{  using System.ComponentModel.Composition;  using System.Web.Mvc;  [ExportAttribute]  public class HomeController : Controller  {    [ImportAttribute]    private MessageSource messageSource;    public ActionResult Index()    {      return View(this.messageSource);    }  }}

2. You create an instance of a CompositionContainer. You supply it with your marked code.

Example 11 — 定义CompositionContainer
protected void Application_Start(){  AreaRegistration.RegisterAllAreas();  RegisterGlobalFilters(GlobalFilters.Filters);  RegisterRoutes(RouteTable.Routes);  CompositionContainer compositionContainer = new CompositionContainer();  compositionContainer.ComposeParts(new HomeController(),                                    new MessageSource());}

3. You implement the IDependencyResolver interface.

在例12, 在工程增加 实现了IDependencyResolver接口MefDependencySolver .IDependencyResolver 接口定义了两个方法 : GetService and GetServices.
namespace MefMvc01{  using System;  using System.Collections.Generic;  using System.ComponentModel.Composition;  using System.ComponentModel.Composition.Hosting;  using System.Web.Mvc;  public class MefDependencySolver : IDependencyResolver  {    public MefDependencySolver(CompositionContainer compositionContainer)    {      this.compositionContainer = compositionContainer;    }    private CompositionContainer compositionContainer;    public object GetService(Type serviceType)    {      string name = AttributedModelServices.GetContractName(serviceType);      return compositionContainer.GetExportedValueOrDefault<object>(name);    }    public IEnumerable<object> GetServices(Type serviceType)    {      return this.compositionContainer                 .GetExportedValues<object>(serviceType.FullName);    }  }}

原地址


0 0