2

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

项目 1(MVC 应用程序,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; }
  }

 }

现在要测试,我只是从控制器调用模型的构造函数:

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
  {

  }

}

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

4

1 回答 1

1

ExpressionModel您在构造函数中有一个小错误。您正在编写容器本身:)

_container.ComposeParts(_container);

问题应该立即显而易见,因为如果ExpressionModel实际发生了组合,即使没有发现扩展,该extensions属性也会被初始化为 0 个项目,但它不会是null.

您需要像这样组合当前模型实例:

_container.ComposeParts(this);

其他一切似乎都很好,并且在此更正后应该可以正常工作。

于 2013-03-14T13:29:45.710 回答