What could stop MEF or Prism loading my type?
Asked Answered
A

1

7

I have a class:

public abstract class XTimeViewModel : DevExpress.Xpf.Mvvm.ViewModelBase
{
  public bool PropertiesChanged { get; set; }

  [NotifyPropertyChangedInvocator]
  protected virtual void _onPropertyChanged(/*[CallerMemberName]*/ string propertyName = null)
  {
    PropertiesChanged = true;
    RaisePropertyChanged(propertyName);
  }
}

It is contained in an assembly called Common. When I try and add a DirectoryCatalog for a folder containing Common and other assemblies, and dependencies such as DevExpress.Xpf.Mvvm.v13.2:

var catalog = new DirectoryCatalog(unitPath, "*.dll");
AggregateCatalog.Catalogs.Add(catalog);

I get a ReflectionTypeLoadException, with a TypeLoadException stating:

"Could not load type 'Startup.ViewModels.ViewModel' from assembly 'G4S.XTime.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'."

I can't see why MEF can't load this type. When I try sample code:

var asm = Assembly.LoadFrom(@"C:\Development\XTime\Startup\Units\G4S.XTime.Common.dll");
var vm = asm.GetType("G4S.XTime.Common.XTimeViewModel");

Then vm contains the correct type, i.e. G4S.XTime.Common.XTimeViewModel.

Just a hunch, but none of my loaded modules are having Initialize called, and I think this error is close to the root cause of that.

If I reference the modules, and use AssemblyCatalog to load them, there is no problem at all and all works as it should. What could moving the assembly out to be loaded at runtime change to stop things working?

BTW, Common isn't a module itself , but just a dependency of several modules.

Anosmia answered 30/4, 2014 at 6:45 Comment(12)
Does the TypeLoadException have an InnerException? Anyway, you can try to use Fuslogvw.exe (Assembly Binding Log Viewer) to troubleshoot assembly load failures.Drunkometer
TypeLoadException doesn't have an exception, and my assembly binding log shows zero errors. This error seems to be somehow related to trying to load the type with reflection, later in the app, after assembly binding.Anosmia
Is the Startup.ViewModels.ViewModel derived from G4S.XTime.Common.XTimeViewModel?Setose
No. XTimeViewModel is derived from DevExpress.Xpf.Mvvm.ViewModelBase. It used to be just called ViewModel but the same in all other aspects. Startup is the solution name, and ViewModels a child namespace of Common. Very strange how it gets that type name.Anosmia
Did you try AssemblyCatalog instead of DirectoryCatalog? Also, make sure you have no unmatched imports in your ViewModelInduration
Possibly no member from the mentioned assembly is used in the code.Isidoro
@Induration AssemblyCatalog works, but I need a reference to a type in that assembly. What do you mean by 'unmatched' imports?Anosmia
@Anosmia I mean imports which are not satisfied during MEF composition.Induration
I see that in your troubleshooting you tried Assembly.LoadFrom, though Mef is using Assembly.Load using an assembly name instead of physical file path. Will Assembly.Load work?Morn
Try using the Fusion Log Viewer to troubleshoot: msdn.microsoft.com/en-us/library/e74a18c4(v=vs.110).aspxTrooper
There could be an exception in the constructor of either the view or view model.Veilleux
I had a problem similar your problem but its error was different: Unable to retrieve the module type {0} from the loaded assemblies. You may need to specify a more fully-qualified type name. Maybe your problem is similar to my problem and its about Get Module Type when we try to load modules dynamically by Assembly.Load... I solved my problem with an unusual way (by some simple changes in prism library!!!). If you want i can give you my Custom Prism v4 Dlls to test them in your project.Palaver
B
0

Most likely, your dll's are not in the same place as your startup exe. They are if they are directly referenced by the exe (by default, referenced dll's are copied to the output dir).

Since you mentioned the Initialize() methods not being called, maybe you are using Prism? if so, break into each step of the bootstrapper to see that the catalog is correct (i.e. all the types you think should be in there actually are in there).

You didn't show that the ViewModel under question is marked as [Export], too, so make sure that's there and put a break point in its ctor to make sure it is actually being instantiated after the catalog creation is complete (i.e. when you are creating the view the VM is attached to).

Try giving us the full exception trace to see what's really going on...sometimes the root is buried in those type load exceptions.

Batter answered 26/8, 2015 at 19:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.