2

私は PRISM と MEF を使用して WPF アプリケーションを作成しようとしてきましたが、シェルを起動して実行することができました。モジュールをオンデマンドで読み込めるようにしたいので、シェルに IModuleManager のインスタンスが必要です。ただし、インポートしようとすると、アプリケーションが壊れます。関連するコードは次のとおりです。

ブートストラップ:

public class Bootstrapper : MefBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return this.Container.GetExportedValue<Shell>();
    }

    protected override void InitializeShell()
    {
        base.InitializeShell();

        Application.Current.MainWindow = (Shell)this.Shell;
        Application.Current.MainWindow.Show();
    }

    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();

        // Add this assembly to export ModuleTracker
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));

        DirectoryModuleCatalog moduleCatalog = new DirectoryModuleCatalog();
        moduleCatalog.ModulePath = @".\Modules";
        moduleCatalog.Load();
        foreach (ModuleInfo moduleInfo in moduleCatalog.Modules)
        {
            this.ModuleCatalog.AddModule(moduleInfo);
        }

        DirectoryCatalog catalog = new DirectoryCatalog(@".\Modules");
        this.AggregateCatalog.Catalogs.Add(catalog);

        base.ConfigureAggregateCatalog();
    }

    protected override void ConfigureContainer()
    {
        //Export the Container so that it can be injected if needed.
        this.Container.ComposeExportedValue(Container);

        //Export the Module Catalog so that it can be injected if needed.
        this.Container.ComposeExportedValue(ModuleCatalog);

        base.ConfigureContainer();
    }

    protected override IModuleCatalog CreateModuleCatalog()
    {
        return new ConfigurationModuleCatalog();
    }
}

シェル:

[Export(typeof(Shell))]
public partial class Shell : Window, IPartImportsSatisfiedNotification
{
    [Import(AllowRecomposition = false)]
    private IModuleManager moduleManager;

    public Shell()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

    }

    public void OnImportsSatisfied()
    {

    }
}

私が得ている例外は次のとおりです。

No exports were found that match the constraint: 
ContractName    Shell
RequiredTypeIdentity    Shell

IModuleManager の [Import] 属性を削除すると、すべて正常に動作します。IModuleManager をエクスポートするために必要なことはありますか?

4

2 に答える 2

0

Bootstrapperの次の行にコメントを付けることで、この問題を解決しました。

this.Container.ComposeExportedValue(ModuleCatalog);

それが問題を引き起こしている理由はわかりませんが、この問題への洞察を歓迎します。

于 2013-03-12T16:25:01.247 に答える
0

注意しなければならないことの 1 つは、同じタイプに対して複数のエクスポートがあることです。これは、(同じ型のan を含む可能性がある)ComposeExportedValueだけでなく a も使用している場合に簡単に発生する可能性があります。DirectoryCatalogExport

Nuget には、 MEFXと呼ばれるこれらの問題を診断するための優れたパッケージがあります。

このライブラリを取得した場合は、次の行を追加して、何が起こっているのかを調べることができます

var compositionInfo = new CompositionInfo(AggregateCatalog, Container);
CompositionInfoTextFormatter.Write(compositionInfo, Console.Out);

this.Container.ComposeExportedValue(ModuleCatalog);プログラムからエラーを投稿しても構わない場合は、プログラムを終了したときに出力ウィンドウに何が表示されるかを確認したいと思います。

于 2013-03-29T21:43:55.470 に答える