MEF Parts not found for deployed app, but found in Debug mode
Asked Answered
B

2

11

I checked a lot of MEF questions here but I can't imagine what my problem is. Here's what's happening:

I have a desktop WPF app that I'm deploying with AdvancedInstaller. I use .NET 4.0 and MEF to compose parts. Some parts are in the main project, so they are inside the app.exe file. Other parts are inside class libraries that reference the main project, so they are inside somename.dll files.

The problem: While running the app from VS, both in Debug and in Release, everything is fine. Once I deploy the app, some of the dlls say that they have no parts (zero) to export.

I checked the following:

  • all dlls are available in the deployment and the catalog is finding the files
  • the export types and names are correct, after all, everything is working while in Visual Studio
  • when I try to add the parts from the dlls, I get that the number of parts is zero ONLY IN DEPLOYMENT.

This is the code that's not findind parts in the deployed app:

var catalog = new AggregateCatalog();
string path = Environment.CurrentDirectory.ToString();
DirectoryCatalog qualitycontrol = new DirectoryCatalog(".", "QualityControl.exe"); //this is my main assembly
DirectoryCatalog qualitymix;

catalog.Catalogs.Add(qualitycontrol); //this finds the parts and always works fine

if (File.Exists(path + @"\QualityMix.dll"))
{
    qualitymix = new DirectoryCatalog(".", "QualityMix.dll"); //the file exists in the deployment
    catalog.Catalogs.Add(qualitymix); //the "qualitymix" catalog shows more than 20 parts if run with VS, but 0 parts in deployment
}

The only thing that works (but it's very slow to start the app) is the following:

var catalog = new DirectoryCatalog(".", "*");

This has the problem that it needs to check more than 100 files present in the working directory, and I cannot deploy my plugin dlls in a different dir.

Why is it that a DirectoryCatalog looking at all files finds the parts, but a DirectoryCatalog looking at a single part does not? How can I debug this issue if it only happens in the deployed app?

---Edit: this problem is only happening with certain dlls, the files are found and for other dlls the parts are also found. I'm using the same Export/Import procedure in all dlls, but somehow some of them show no parts in deployment

Anything you can suggest will be helpfull, thank you guys!


NEW INFO!

I tried loading my dll with an AssemblyCatalog. It works in Visual Studio (Debug and Release) but when deployed I get the following errors:

1st try:

if (File.Exists(path + @"\QualityMix.dll"))
    {                           
        qualitymix = new AssemblyCatalog(Assembly.LoadFile(path + @"\QualityMix.dll")); //file is loaded and parts found in VS

         catalog.Catalogs.Add(qualitymix);
    }

Error: The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018).

Second try:

 if (File.Exists(path + @"\QualityMix.dll"))
    {
        var name = AssemblyName.GetAssemblyName(path + @"\QualityMix.dll");
        qualitymix = new AssemblyCatalog(Assembly.Load(name));

        catalog.Catalogs.Add(qualitymix);
    }

Error: Could not load file or assembly 'QualityMix.dll' or one of its dependencies. An attempt was made to load a program with an incorrect format.

I've looked for questions about these errors but nothing has been helpful so far. All projects are built for All CPUs, and the references look ok (this dll uses the same references as other projects that are loading ok).


Edit 2:

I tried the suggestion by @SuryaBhaskar to use LoadFrom instead of Load

 if (File.Exists(path + @"\QualityMix.dll"))
    {
        qualitymix = new AssemblyCatalog(Assembly.LoadFrom(path + @"\QualityMix.dll"));

        catalog.Catalogs.Add(qualitymix);
    }

But I get the same error: Could not load file or assembly 'QualityMix.dll' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Botanical answered 15/7, 2015 at 10:37 Comment(7)
Is Environment.CurrentDirectory the one you expected in deployed application? Check what it returns in both casesWeakling
Thanks @VMaleev for your suggestion. The CurrentDirectory is fine, it's finding the dll file ok.Botanical
I tried this solution to no avail: #9119724Botanical
Maybe it's loading QualityMix.dll from another location (GAC or AppDomain.BaseDirectory). As a last resort you can try running Process Monitor and see which location it is trying to load the file from.Stutz
Thanks @TedyPranolo, but all dlls are being loaded from the installation folder of the app (it's WPF, I don't use the GAC). To make sure there are no permissions problems I install it inside the Documents folder.Botanical
Sorry that didn't help. Maybe QualityMix.dll is not the culprit, rather another dll it is dependent on. I would love to give it a try if you could provide a test project that exhibits the same problem.Stutz
Hello @TedyPranolo, thank you for your suggestion. The dependencies of this particular dll have been checked, they are the same than the main project, and the main project is loading ok.Botanical
B
0

I managed to solve this issue by moving the code of the problematic dll to a new project. This solved the issue, somehow... though the reason remains a mistery to me.

Botanical answered 25/8, 2015 at 11:51 Comment(0)
P
-1

Use LoadFrom instead of LoadFile or Load.If you use Load it will have conflicts with other assemblies on current AppDomain

Plonk answered 11/8, 2015 at 14:40 Comment(5)
Thank you for your answer. Please provide a code example of your proposed solution to get a vote up.Botanical
container.ComposeParts(); var assemblies = aggregateCatalog.Parts.Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly).Distinct().ToList(); foreach (Assembly dll in assemblies) { //Based on conditions load your assembly on right assembly variable assmbly = Assembly.LoadFrom(dll.Location); }Plonk
Thanks @SuryaBhaskar, but you should edit your answer so it's easily visible for everybody. You'll get more votes the better your answer is. I'll try your approach and let you know.Botanical
the best approach is to take the code samples in the question and modify them with your proposed solution. This will get you the most votes, since it's easier for everybody to understand and shows that you care to give a good answer.Botanical
I have tried your approach but I get the same error as when using qualitymix = new AssemblyCatalog(Assembly.Load(name));Botanical

© 2022 - 2024 — McMap. All rights reserved.