难倒MVC MEF应用程序

时间:2012-10-23 20:50:15

标签: c# visual-studio mef

我正在尝试将Microsoft可扩展性框架(MEF)实现为基于MVC的示例Web应用程序。我在MEF Overview页面上使用SimpleCalculator示例解决方案。我的目标是一个可以从另一个项目动态加载DLL扩展的应用程序,以扩展Model的功能,本质上我希望MVC-Application成为插件的其他扩展的框架。首先是我的设置:

项目1(MVC-Application,MEF组件主机):

我按照以下方式装饰模型中的元素:

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ExpressionParserPOC.Models
{

    public class ExpressionModel
      {
            private CompositionContainer _container;

            [ImportMany]
            IEnumerable<Lazy<IExtensions,IExtensionName>> extensions { get; set; }

        public ExpressionModel()
        {
          var catalog = new AggregateCatalog();
          catalog.Catalogs.Add(new DirectoryCatalog("C:\\local_visual_studio\\ExpressionParserPOC\\ExpressionParserPOC\\Extensions"));

          //Create the CompositionContainer with the parts in the catalog
          _container = new CompositionContainer(catalog);
          _container.ComposeParts(_container);

          //TEST: Can we access the extensions?
          if (extensions != null)//<--NULL WHEN CONSTRUCTOR IS CALLED WHY? Expected GetMatrix() Function from DLL to be exposed
          {
            foreach (Lazy<IExtensions, IExtensionName> i in extensions)
            {
              Lazy<IExtensions, IExtensionName> foo = i;
            }
          }

        }

      }

  public interface IExtensions
  {
    double[][] GetMatrix(string matrix);
  }

  public interface IExtensionName
  {
    Char Symbol { get; }
  }

 }

要立即测试,我只是从Controller调用Model的构造函数:

namespace ExpressionParserPOC.Controllers
{
  public class HomeController : Controller
  {
    public ActionResult Index()
    {
      ViewBag.Message = "Enter an Expression for Octave to evaluate";

      //Instantiate an ExpressionModel composed of extensible parts
      var model = new ExpressionModel();
      return View(model);
    }

  }
}

项目2(DLL项目,MEF组件):

//PROJECT BUILD OUTPUTS TO THE EXTENSIONS DIRECTORY IN PROJECT 1 ABOVE
using System.ComponentModel.Composition;

namespace MyExtensions
{
  //Project 1 already added as a reference 
  [Export(typeof(ExpressionParserPOC.Models.IExtensions))]
  [ExportMetadata("Symbol", 'o')]
  public class Octave : MyExtensions.IExtensions
  {

      //Other class properties, constructors, functions, etc.

     #region FUNCTIONS
     public double[][] GetMatrix(string matrix) 
     {
         double[][] mat = new double[][];
         //Do Stuff
         return mat;
     }
     #endregion

  }

  public interface IExtensions : ExpressionParserPOC.Models.IExtensions
  {

  }

}

问题是当我从同一个项目中的Controller调用Model构造函数时,主机MVC应用程序项目中的扩展List永远不会被填充。我是MEF开发的新手,我不确定我做错了什么,因为我正在使用MVC应用程序,还有什么需要考虑的吗?为什么Project 1扩展列表不会被填充?我的界面定义错了吗?示例计算器应用程序是一个简单的命令行项目,似乎工作正常,我看到的唯一区别是外部DLL项目在同一个解决方案空间,而在我的示例中,解决方案空间是独立的。

1 个答案:

答案 0 :(得分:1)

ExpressionModel构造函数中存在一个微不足道的错误。你正在组成容器本身:)

_container.ComposeParts(_container);

问题应该立即显现,因为如果ExpressionModel的组成实际发生过,即使没有发现扩展,extensions属性也会被初始化为0项,但它不会'是null

您需要像这样编写当前模型实例:

_container.ComposeParts(this);

其他所有内容似乎都没问题,在纠正之后应该正常工作。