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.

asked Jun 7 '11 at 20:23
okieh
148110
 
    
Later that night... I finally found out that is has something to do with this part in the Custom Export Attribute:base(typeof(object)) - but still no knowledge of how to solve the RegisterViewWithRegion problem... – okieh Jun 7 '11 at 21:14

4 Answers

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.

answered Jun 8 '11 at 7:05
okieh
148110
 
 

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.

answered Oct 18 '11 at 22:33
 
    
I had the same issue as the original asker and this was the solution. – Dylan Nov 30 '11 at 16:02

The custom export attribute passes typeof(object) to the base constructor, which changes the contract exported so that it no longer matches the import. Change it so it calls the parameterless constructor.

As far as the activation error you'll need to look at the exception in more detail. The root cause is probably there somewhere, perhaps buried under an InnerException.

answered Jun 8 '11 at 3:58
Daniel Plaisted
12.9k22747
 

I encountered exactly the same problem and it was a hard one for a MEF/PRISM beginner. okieh describes the problem very well, I just want to post an alternative solution, coming from theStocktraderUI sample application:

The solution works (/seems to work) if you want View discovery without any form of config file, etc. where you have to register your views.

1. Modify the ViewExport custom event

[Export]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[MetadataAttribute]
public sealed class ViewExportAttribute : ExportAttribute, IViewRegionRegistration
{
public ViewExportAttribute()
: base(typeof(UserControl))
{ } public string ViewName { get { return base.ContractName; } } public string RegionName { get; set; }
}

The [Export] attribute is added and the base constructor is now called with UserControl instead of object. That way it can be discovered by MEF.

2. Modify AutoPopulateExportedViewsBehavior

[ImportMany(typeof(UserControl))]
public Lazy<UserControl, IViewRegionRegistration>[] RegisteredViews { get; set; }

The [ImportMany] attribute is added and the type of the Lazy initializiation is changed to UserControl. Now, all UserControls with IViewRegionRegistration-implementing MetaData-type are imported.

That's basically it. You can use the [ViewExport] as before. Note, that Views are limited to (sub)types of UserControl. I suppose this can be modified if you want to. And make sure your aggregate catalog imports the ViewExportAttribute and the AutoPopulateExportedViewsBehavior, as Nicolaus said...

This way, you don't need additional interfaces for your views and can still discover everything without hardcoded registration.

I hope it helps and let me know, if I missed any drawbacks of my solution.

http://stackoverflow.com/questions/6271167/prism-4-registerviewwithregion-custom-export-attributes

最新文章

  1. matlab 有趣小细节
  2. 重走java--Step 2
  3. Win7 64位 VS2013环境cuda_7.5.18的一些坑
  4. ThinkPHP中getField( )和field( )
  5. hdu5390 tree
  6. RM报表 刷新打印机列表
  7. (一)学习C#之浮点类型float小结
  8. 取得root权限后怎么删除程序
  9. Linux文件误删除恢复操作
  10. The CircuitCalculator.com Blog a blog with live web calculators Home About Policies Contact PCB
  11. VelocityTracker简单介绍
  12. HDU 2203 亲串(kmp)
  13. python进阶之time模块详解
  14. tree与GridView交互
  15. QML C++插件dll引用
  16. alibaba的FastJson(高性能JSON开发包) json转换
  17. Java 中 synchronized的用法详解(四种用法)
  18. Splay-Tree理解
  19. 深入理解Object提供的阻塞和唤醒API
  20. 单机ZooKeeper配置

热门文章

  1. 2019-2020-1 20199319《Linux内核原理与分析》第七周作业
  2. 谷歌对Intel 10nm进度不满
  3. 了解并安装Nginx
  4. Go语言标准库之fmt.Print
  5. hive不分区增量更新
  6. BZOJ1079 [SCOI2008]着色方案[组合计数DP]
  7. linux学习:【第2篇】之常见命令
  8. Java 工厂方法模式的简单示例
  9. 关于数字加载的动画 jquery
  10. JZOJ5358【NOIP2017提高A组模拟9.12】BBQ