2

Microsoft Extensibility Framework (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 に答える