MEF不再加载参考 [英] MEF not loading a references again

查看:122
本文介绍了MEF不再加载参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的界面如下:

 [InheritedExport( typeof (ITransform))]
   公共 界面 ITransform
   {...}



现在,我有两个班级:

 命名空间 ProjectA
 {
     公共  Transform:ITransform {....}
 }



还有

 命名空间 ProjectB
{
    公共  Transform:ITransform {....}
}



我正在使用[DirectoryCatalog] [1]加载每个零件.每个项目都会被编译,其二进制文件(生成输出)的位置将作为DirectoryCatalog的输入,以供进一步编写.

提取ITransform零件的代码如下:

 公共 静态  class  ExtensionFactory
      {
          公共 静态 ITransform GetExtension(字符串 extensionPath)
          {
              IEnumerable< ITransform> extensions = 尝试
              {
                  AggregateCatalog目录=  AggregateCatalog();
                  catalog.Catalogs.Add( DirectoryCatalog(extensionPath));
                  CompositionContainer容器=  CompositionContainer(catalog);
                  container.ComposeParts(catalog);
                  扩展程序= container.GetExportedValues< ITransform>();
                  返回 extensions.FirstOrDefault();
              }
              捕获(例外){........}
              返回 extensions.FirstOrDefault();
          }
      }


我还有另一个项目ProjectXYZ(由第三方工具自动生成(Altova Mapforce 2012 SP1)).

对于ProjectA:

 命名空间 ProjectXYZ
{
    公共 classA {...}
}


对于ProjectB:

 命名空间 ProjectXYZ
{
    公共 classA {...}
    公共 classB {...}
}


ProjectA.Transform使用ProjectXYZ.ClassA,而ProjectB.Transform使用另一个ProjectXYZ实现的ProjectXYZ.ClassB.对于ITransform的不同实现,ProjectXYZ的实现和类别也有所不同. ProjectXYZ中的类是通过一些第三方工具自动生成的,我需要直接使用它们.因此,我无法对ProjectXYZ进行任何更改.

因此,当MEF首次加载ProjectA.Transform时,它还将同时加载ProjectXYZ以用作ProjectA的参考.当加载/导出ProjectB.Transform时,由于ProjectXYZ已经在MEF内存中,因此它使用可从ProjectA获得的ProjectXYZ引用.因此,当执行ProjectB.Transform时,它将搜索ProjectXYZ.ClassB,由于MEF已在ProjectA中获得可用的加载ProjectXYZ引用,因此无法获取.
如何解决这个问题. MEF正确加载了零件,但没有以期望的方式加载支持dll的引用.我也尝试了PartCreationPolicy属性,但是结果是相同的.

[1]:http://mef.codeplex.com/wikipage?title=使用%20Catalogs



请在stackoverflow上遵循相同的问题
http://stackoverflow.com/questions/9885056/mef-directorycatalog-not-over-ride-the-project-references-at-of-loading [解决方案

<我认为问题出在返回extensions.FirstOrDefault();中. MEF通常会返回与请求的导入匹配的所有对象.现在只有它找到的第一个.您可以添加元数据和延迟加载以从MEF获取正确的对象.

皮特

PS:只需阅读stackoverflow上给出的解决方案.正是您所需要的.




我已经深入研究了您的问题.这不是MEF问题.
问题是.NET的加载模型. (或更好的.net加载对象的方式)

当MEF加载时,它返回正确的对象.但是,当在加载projectB时查找类ProjectXYZ时,已经有一个ProjectXYZ dll加载了正确的程序集名称projectB所引用.并且,未加载projectB实际引用的dll加载程序.

您只需将添加的文件夹的顺序更改为
即可尝试自己

 extensionPath.Add( @" );
extensionPath.Add( @" ); 



然后你得到

Extension Loaded :This is for Project B :: 4
Extension Loaded :This is for Project B :: 4



解决问题的方法是重命名装配.当所有ProjectXYZ程序集都有自己的文件名时,您将获得预期的结果.

问候,
Piet


I have a interface as follows:

[InheritedExport(typeof(ITransform))]
   public interface ITransform
   {...}



Now, I have two classes:

namespace ProjectA
 {
     public class Transform:ITransform {....}
 }



And

namespace ProjectB
{
    public class Transform:ITransform {....}
}



I am using [DirectoryCatalog][1] for loading each parts. Each project is compiled and their binaries(build output) location is given as an input to DirectoryCatalog for further composition.

The code for fetching ITransform parts is as follows:

public static class ExtensionFactory
      {
          public static ITransform GetExtension(string extensionPath)
          {
              IEnumerable<ITransform> extensions = null;
              try
              {
                  AggregateCatalog catalog = new AggregateCatalog();
                  catalog.Catalogs.Add(new DirectoryCatalog(extensionPath));
                  CompositionContainer container = new CompositionContainer(catalog);
                  container.ComposeParts(catalog);
                  extensions = container.GetExportedValues<ITransform>();
                  return extensions.FirstOrDefault();
              }
              catch (Exception ex) {........}
              return extensions.FirstOrDefault();
          }
      }


I have another project ProjectXYZ(auto generated by third party tool(Altova Mapforce 2012 SP1)).

For ProjectA:

namespace ProjectXYZ
{
    public classA{...}
}


For ProjectB:

namespace ProjectXYZ
{
    public classA{...}
    public classB{...}
}


ProjectA.Transform uses ProjectXYZ.ClassA, whereas ProjectB.Transform uses ProjectXYZ.ClassB from another implementation of ProjectXYZ. The implementation and classes of ProjectXYZ varies across for different implementation of ITransform. The classes in ProjectXYZ are automatically generated through some third-party tools, which I need to use directly. So, I cannot make any changes to ProjectXYZ.

So, when first time MEF loads ProjectA.Transform, it also loads ProjectXYZ to be used as a reference for ProjectA. When ProjectB.Transform is getting loaded/exported, then as ProjectXYZ being already in MEF memory, it uses the ProjectXYZ reference available from ProjectA. Thus, when ProjectB.Transform is executing, it searches for ProjectXYZ.ClassB, which it does not gets as MEF has load ProjectXYZ reference available in ProjectA.

How to resolve this problem. The MEF loads the parts correctly, but it does not load the supporting dll''s references in a desired manner. I have also tried PartCreationPolicy attribute, but the results are same.

[1]: http://mef.codeplex.com/wikipage?title=Using%20Catalogs



Please follow same question on stackoverflow
http://stackoverflow.com/questions/9885056/mef-directorycatalog-not-override-the-project-references-at-time-of-loading[^]

解决方案

I think the problem is in the return extensions.FirstOrDefault(); MEF will normaly return all the objects that match the requested import. Now only the first one it finds. You can add meta data and lazy loading to get the right object from MEF.

Piet

PS: just read the solution given on stackoverflow. That is just what you need.


Hi,

I''ve look deeper into you''re problem. It not a MEF problem.
The problem is the loading model of .NET. (or better the way you''re objects are loaded by .net)

When MEF loads it returns the correct objects. But when looking for class ProjectXYZ when projectB is loaded there is already a ProjectXYZ dll loaded with the correct assembly name projectB is referring to. And the loader the dll actually referenced by projectB is not loaded.

You can try it you''re self just by changing the sequence of the added folders into

extensionPath.Add(@"E:\MEF\MEFForProjectB\ProjectB\bin\Debug");
extensionPath.Add(@"E:\MEF\MEFForProjectA\ProjectA\bin\Debug");



Then you get

Extension Loaded :This is for Project B :: 4
Extension Loaded :This is for Project B :: 4



The solution to you''re problem is renaming the assembly. When all ProjectXYZ assemblies have there own filename you get the expected result.

Regards,
Piet


这篇关于MEF不再加载参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆