Click here to Skip to main content
15,886,110 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a interface as follows:

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


Now, I have two classes:

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


And

C#
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:

C#
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:
C#
namespace ProjectXYZ
{
    public classA{...}
}

For ProjectB:
C#
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[^]
Posted
Updated 26-Mar-12 21:39pm
v2

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.
 
Share this answer
 
v2
Comments
Saroop Trivedi 28-Mar-12 7:28am    
Hello Pietvredeveld : This is not a question of Metadata. Please refer below link I uploaded whole problem there.
http://stackoverflow.com/questions/9885056/mef-directorycatalog-not-override-the-project-references-at-time-of-loading
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

C#
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
 
Share this answer
 
v2
Comments
Saroop Trivedi 29-Mar-12 2:11am    
Hello Piet,
I can't able to rename the namespace of ProjectXYZ because this is a demo application In real world ProjectXYZ is third party tool library. and for every custom project of A and B it's create different internal mechanics for ProjectXYZ . I perform all the test as you mansion here.Let see what happen?
Thank you for spending your pleasure time behind my issue.
Regards,
Saroop
pietvredeveld 29-Mar-12 6:13am    
you're welcome
Saroop Trivedi 29-Mar-12 7:54am    
There is not such mechanism for virtual partisan in VM.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900