MatthiasGは、MEFでモジュールを定義する方法を示しています。ビュー自体はIModuleを実装していないことに注意してください。ただし、PRISMでMEFを使用することの興味深い部分は、起動時にモジュールをUIにインポートする方法です。
ここでは原則としてシステムの説明しかできませんが、正しい方向を示している可能性があります。すべてに対して常に多くのアプローチがありますが、これは私がベストプラクティスであると理解したことであり、私が非常に良い経験をしたことです。
ブートストラップ
PrismやUnityと同様に、すべてはで派生したBootstrapperから始まりMefBootstrapperますMicrosoft.Practices.Prism.MefExtensions。ブートストラッパーはMEFコンテナーをセットアップし、サービス、ビュー、ViewModels、モデルを含むすべてのタイプをインポートします。
ビュー(モジュール)のエクスポート
これはMatthiasGが参照している部分です。私の練習は、GUIモジュールの次の構造です。
- モデルは、属性を使用して、それ自体を具象型(インターフェースにすることもできます。MatthiasGを参照)としてエクスポートし- [Export(typeof(MyModel)]ます。マークを付け- [PartCreationPolicy(CreationPolicy.Shared)]て、インスタンスが1つだけ作成されることを示します(シングルトン動作)。
 
- ViewModelは、モデルと同じようにそれ自体を具象型としてエクスポートし、コンストラクターインジェクションを介してモデルをインポートします。 - [ImportingConstructor] public class MyViewModel(MyModel model){_model = model; } 
- ViewModelがモデルをインポートするのと同じ方法で、Viewはコンストラクタインジェクションを介してViewModelをインポートします 
- そして今、これは重要です。ビューは、「標準」- [Export]属性から派生した特定の属性を使用して自身をエクスポートします。次に例を示します。
 
[ViewExport(RegionName = RegionNames.DataStorageRegion)]
public partial class DataStorageView
{
    [ImportingConstructor]
    public DataStorageView(DataStorageViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;
    }
}
[ViewExport]属性
属性は2つのことを行います。属性[ViewExport]から派生しているため[Export]、MEFコンテナにビューをインポートするように指示します。何として?これはその定義に隠されています。コンストラクターの署名は次のようになります。
public ViewExportAttribute() : base(typeof(UserControl)) {}
[Export]タイプが。のコンストラクターを呼び出すことによりUserControl、すべてのビューがUserControlMEFコンテナーのように登録されます。
RegionName次に、ビューをプラグインするシェルUIのリージョンを決定するために後で使用されるプロパティを定義します。RegionNameプロパティは、インターフェイスの唯一のメンバーですIViewRegionRegistration。属性クラス:
/// <summary>
/// Marks a UserControl for exporting it to a region with a specified name
/// </summary>
[Export(typeof(IViewRegionRegistration))]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[MetadataAttribute]
public sealed class ViewExportAttribute : ExportAttribute, IViewRegionRegistration
{
    public ViewExportAttribute() : base(typeof(UserControl)) {}
    /// <summary>
    /// Name of the region to export the View to
    /// </summary>
    public string RegionName { get; set; }
}
ビューのインポート
さて、システムの最後の重要な部分は、シェルの領域にアタッチする動作です:動作AutoPopulateExportedViews。これにより、次の行を使用してMEFコンテナからすべてのモジュールがインポートされます。
[ImportMany] 
private Lazy<UserControl, IViewRegionRegistration>[] _registeredViews;
UserControlこれは、を実装するメタデータ属性がある場合、コンテナからとして登録されたすべてのタイプをインポートしますIViewRegionRegistration。属性がそうであるため[ViewExport]、これは、でマークされたすべてのタイプをインポートすることを意味します[ViewExport(...)]。
最後のステップは、ビューをリージョンにプラグインすることです。これは、bahviorがそのOnAttach()プロパティで実行します。
/// <summary>
/// A behavior to add Views to specified regions, if the View has been exported (MEF) and provides metadata
/// of the type IViewRegionRegistration.
/// </summary>
[Export(typeof(AutoPopulateExportedViewsBehavior))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class AutoPopulateExportedViewsBehavior : RegionBehavior, IPartImportsSatisfiedNotification
{
    protected override void OnAttach()
    {
        AddRegisteredViews();
    }
    public void OnImportsSatisfied()
    {
        AddRegisteredViews();
    }
    /// <summary>
    /// Add View to region if requirements are met
    /// </summary>
    private void AddRegisteredViews()
    {
        if (Region == null) return;
        foreach (var view in _registeredViews
            .Where(v => v.Metadata.RegionName == Region.Name)
            .Select(v => v.Value)
            .Where(v => !Region.Views.Contains(v)))
            Region.Add(view);
    }
    [ImportMany()] 
    private Lazy<UserControl, IViewRegionRegistration>[] _registeredViews;
}
注意してください.Where(v => v.Metadata.RegionName == Region.Name)。これは、属性のRegionNameプロパティを使用して、ビヘイビアーをアタッチしている特定のリージョンにエクスポートされたビューのみを取得します。
動作は、ブートストラッパーのシェルの領域に関連付けられます。
protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
    ViewModelInjectionBehavior.RegionsToAttachTo.Add(RegionNames.ElementViewRegion);
    var behaviorFactory = base.ConfigureDefaultRegionBehaviors();
    behaviorFactory.AddIfMissing("AutoPopulateExportedViewsBehavior", typeof(AutoPopulateExportedViewsBehavior));
}
私たちは完全に一周しました。これにより、MEFとPRISMで物事がどのように機能するかがわかります。
そして、あなたがまだ退屈していないなら:これは完璧です:
MikeTaultyのスクリーンキャスト