MatthiasG, MEF'deki modülleri tanımlama yolunu gösterir. Görünümün kendisi IModule uygulanmadığını unutmayın. Ancak, MEF'i PRISM ile kullanmanın ilginç kısmı, başlangıçta modüllerin UI'nize nasıl aktarılacağıdır.
Sadece burada prensipte sistemi açıklayabilir, ama doğru yönde bir işaret olabilir. Orada her şey için çok sayıda yaklaşımlar her zaman vardır, ancak bu ben en iyi uygulama olduğu anlaşılan budur ve ne çok iyi deneyimler yaptık:
Bootstrapping Prism ve Unity gibi
, hepsi ile başlar MefBootstrapper
'dan Microsoft.Practices.Prism.MefExtensions
'dan türetilen Bootstrapper. Önyükleyici MEF konteynırını kurar ve böylece servisler, görünümler, ViewModeller ve modeller de dahil olmak üzere her türlü ithalatı yapar.
İhracat Görünümler (modüller)
Bu MatthiasG bahsediyor parçasıdır.[Export(typeof(MyModel)]
özelliğini kullanarak,
onun somut türü olarak modeli ihracatı kendisini (çok iyi bir arayüz MatthiasG görebilir): My uygulama GUI modülleri için aşağıdaki yapıdır. Yalnızca bir örneğin oluşturulduğunu belirtmek için [PartCreationPolicy(CreationPolicy.Shared)]
ile işaretleyin (tekil davranış).
ViewModel sadece modeli gibi somut türü olarak kendini ihraç ve yapıcı enjeksiyon yoluyla Model alır:
[ImportingConstructor] genel sınıf MyViewModel (MyModel modeli) { _model = Model; }
Görüntüle yapıcı enjeksiyon yoluyla ViewModel ithal, aynı şekilde ViewModel Model
ithal Ve şimdi, bu önemli: türetilmiştir belirli bir özellik, Manzara ihracatı kendisini 'standart' [Export]
özniteliği. İşte bir örnek: o [Export]
özelliğinden kaynaklanmaktadır olduğundan, Görünüm ithal etmek MEF kabı söyler:
[ViewExport(RegionName = RegionNames.DataStorageRegion)]
public partial class DataStorageView
{
[ImportingConstructor]
public DataStorageView(DataStorageViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
[ViewExport] [ViewExport]
nitelik iki şey yapar
bağlıyor. Ne gibi? Bu en Definition gizli: yapıcı imza şöyle görünür:
public ViewExportAttribute() : base(typeof(UserControl)) {}
UserControl
türüne [Export]
yapıcısı arayarak, her görünüm MEF kapta UserControl
olarak tescil alır. İkincisi, daha sonra Shell UI'nizin hangi Bölgeye takıldığına karar vermek için kullanılacak bir RegionName
mülkünü tanımlar. RegionName özelliği, IViewRegionRegistration
arabiriminin tek üyedir. nitelik sınıfı: AutoPopulateExportedViews
davranış: Görüntüleme
İçe
/// <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; }
}
Şimdi, sistemin son önemli kısmı kabuğundan bölgelere takmak bir davranış vardır. Bu, bu çizgi ile MEF kaptan senin modülünün tüm ithal: bunlar IViewRegionRegistration
uygulayan bir meta veri niteliği, varsa
[ImportMany]
private Lazy<UserControl, IViewRegionRegistration>[] _registeredViews;
Bu, kaptan UserControl
olarak tescil her türlü ithal ediyor. [ViewExport]
özniteliğinizin anlamı, bu, [ViewExport(...)]
ile işaretlenmiş her tür içe aktardığınız anlamına gelir.
/// <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;
}
Bildirim .Where(v => v.Metadata.RegionName == Region.Name)
:
Son adım bu OnAttach()
mülkü içinde bahvior gösterdiği bölgelere içine Görüntüleme, takmaktır.Bu, yalnızca belirli bölge için dışa aktarılan Görünümleri almak için özniteliğin RegionName özelliğini kullanır, davranışı ekliyorsunuz. Biz tam daire, bu size şeyler MEF ile yerine düşmek nasıl bir fikir alır ve umut geldim
protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
ViewModelInjectionBehavior.RegionsToAttachTo.Add(RegionNames.ElementViewRegion);
var behaviorFactory = base.ConfigureDefaultRegionBehaviors();
behaviorFactory.AddIfMissing("AutoPopulateExportedViewsBehavior", typeof(AutoPopulateExportedViewsBehavior));
}
:
davranış Önyükleyici içinde kabuğundan bölgelere bağlanmıştır alır PRİZMA.
Ve hala sıkılmış değilseniz, Bu mükemmel: Görünüm yapıcısı içinde Mike Taulty's screencast
initialize görünümü modeli iyi bir yoldur. bunun gibi bir problemin var mı? – thumbmunkeys
Unity ile, görünüm modelini kapsayıcılarla başlatır. Beni mefte eşdeğer bir şekilde araştırıyor? Ama eğer iyi bir şekilde söylersen, çok fazla yapışmayacağım, teşekkürler. – user2147528