1

MvcContrib のポータブル領域と MEF を使用してプラグイン フレームワークを構築しています。これにより、再コンパイルする必要なく (dll を bin/Modules フォルダーにドロップするだけで)、プラグイン プロジェクトを直接参照することなく、ポータブル領域をプラグインとして追加できます。

プラグインの開発中に、MyFramework と MyPlugin の 2 つのプロジェクトを使用したソリューションがあります。すべてがうまく機能します。プロジェクト MyFramework だけを含む別のソリューションがありますが、MyPlugin.dll は bin/Modules フォルダーにあります。を使用してカタログをインスタンス化するとき

string Path = HostingEnvironment.MapPath("~/bin");
string ModulesPath = HostingEnvironment.MapPath("~/bin/Modules");
var catalog = new AggregateCatalog(
    new DirectoryCatalog(Path)
    new DirectoryCatalog(ModulesPath)
);

MyPlugin.dll のアセンブリが読み込まれていることがわかりますが、パーツが見つかりません。ここで説明されているように、MEFx を使用して構成状態をダンプしようとしました。

string Path = HostingEnvironment.MapPath("~/bin");
string ModulesPath = HostingEnvironment.MapPath("~/bin/Modules");
var binCatalog = new DirectoryCatalog(Path);
var modulesCatalog = new DirectoryCatalog(ModulesPath);
var catalog = new AggregateCatalog(binCatalog, modulesCatalog);

using (var container = new CompositionContainer(modulesCatalog))
{
    var ci = new CompositionInfo(modulesCatalog, container);
    var stringWriter = new StringWriter();

    CompositionInfoTextFormatter.Write(ci, stringWriter);
    string compositionStateString = stringWriter.ToString();
    Console.WriteLine(s);
}

しかし、compositionStateString は単なる空の文字列です。

問題がどこから来ているのか理解できません。MyFramework は MyPlugin を直接参照していないため、2 つのプロジェクトが同じソリューションの一部としてコンパイルされているかどうかは問題ではありません。

追加情報:プローブ パスに bin/Modules があります。

カスタムのエクスポート属性でコントローラーを装飾して、コントローラーをエクスポートしています。

[ExportModuleControllerAttribute("NotificationsController")]
public class NotificationsController : BaseController
{
    //...
}

その属性は MyFramework で次のように定義されています。

[AttributeUsage(AttributeTargets.Class), MetadataAttribute]
public class ExportModuleControllerAttribute : ExportAttribute, INamedMetadata        
{
    public string[] Dependencies { get; set; }
    public string Name { get; set; }

    public ExportModuleControllerAttribute(string name, params string[] dependencies)
        : base(typeof(IController))
    {
        Dependencies = dependencies;
        Name = name;
    }
}

INamedMetadata インターフェイスと同様:

public interface INamedMetadata
{
    #region Properties
    string Name { get; }
    #endregion
}
4

3 に答える 3

3

モジュールdllでクラス(コントローラーだと思います)などをどのようにエクスポートしていますか?さらにコードを見てみましょう。カタログを設定するだけでは十分ではありません。実際にカタログに物を入れるように mef に指示する必要があります。

また、ci.PartDefinitions をカウントして、そこに何かがあるかどうかを確認します。実際、デバッガーで ci とコンテナー変数を調べて、それらに何が入っているかを確認してください。

また、なぜあなたはmodulesCatalogだけを調べているのですか?例えば、カタログを調べるべきではありません

 var ci = new CompositionInfo(catalog, container);

とにかく、これがあなたを正しい方向に向けてくれることを願っています。

于 2012-06-25T22:13:16.533 に答える
1

@ピーターはいくつかの良い点を指摘しています。また、Visual MEFX を試してみることをお勧めします。プロジェクトで見つけることができますmefcontrib-tools。これにより、アセンブリをインタラクティブに探索できます。一度に 1 つずつ追加して、エクスポートされたものがあるかどうかを確認できます。

セットアップに関する記事は次のとおりです: Visual MEFX の概要

于 2012-06-26T00:56:36.830 に答える