I am using Prism 4 with MEF Extensions and the MVVM pattern. During initialization in a module I call RegisterViewWithRegion(RegionNames.MyRegion, typeof(MyView)) which works perfectly when the view is constructed like this:
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class MyView : UserControl
{
public MyView()
{
....
The view gets registered and everything is fine. As soon as I change the Export to a Custom Export Attribute the view can't be found anymore, although it is still in the container. This Custom Export Attribute is taken from the Stock Trader RI:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[MetadataAttribute]
public class ViewExportAttribute : ExportAttribute, IViewRegionRegistration
{
public ViewExportAttribute()
: base(typeof(object))
{ }
public ViewExportAttribute(string viewName)
: base(viewName, typeof(object))
{
ViewName = viewName;
}
public string RegionName { get; set; }
public string ViewName { get; set; }
}
and the interface is
public interface IViewRegionRegistration
{
string RegionName { get; }
string ViewName { get; }
}
By changing the Export Attribute to
[ViewExport(ViewName = "MyView", RegionName = RegionNames.MyRegion)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class MyView : UserControl
{
public MyView()
{
....
when calling RegisterViewWithRegion it throws an error: Activation error occured while trying to get instance of type MyView, key ""
Any advice? I was looking at this part of code the whole day without finding a solution.
Another day, another way... I will try to answer my question even though I have only limited knowledge about PRISM. In other words: I'm still learning.
The Custom Export Attribute taken from the Stock Trade RI is used by the AutoPopulateExportedViewsBehavior
. This behavior adds a view to its region automatically by checking the Export Attribute for the region name then adds the view to the corresponding region. But all views with this Custom Attribute now have a contract name of "object" which makes it impossible for the ServiveLocator to find them. This Custom Attribute is for a scenario with fixed region/view links.
A solution when working with a Custom Export Attribute is to get all exports of type "object" and the appropriate metadata:
MyView view;
var myList = container.GetExports<object, IViewRegionRegistration>();
foreach (Lazy<object, IViewRegionRegistration> lazy in myList)
{
if (lazy.Metadata.ViewName == "MyView")
{
view = lazy.Value as MyView;
region.Add(view);
break;
}
}
But I think when using ViewInjection and Prism Navigation it is better to just use the default [Export] attribute, then everything works smoothly.
Are you configuring the aggregate catalog in your MEF bootstrapper? If so, are you adding the assembly that contains your ViewExportAttribute and AutoPopulateExportedViewsBehavior classes? I believe this happens in the StockTraderRI's bootstrapper with this line:
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(StockTraderRICommands).Assembly));
The StockTraderRICommands class is in the same assembly as the ViewExportAttribute and AutoPopulateExportedViewsBehavior classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With