I have searched for an answer for this question all day without coming up with any solutions directly applicable to my case, or anything that works (in the one case I found that was applicable).
I have a Caliburn.Micro framework set up to use MEF, and I load my modularized elements just fine. The one thing missing is getting WPF to recognize the resources I use in one of my modules.
How modules are loaded in my app bootstrapper
[ImportMany]
private IEnumerable<IMyModule> _myModules;
protected override void Configure()
{
// Because Configure() is also called from SelectAssemblies(), we cannot instantiate MEF again because it will create conflicts.
if (_configured)
{
return;
}
AggregateCatalog aggregateCatalog = new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
aggregateCatalog.Catalogs.Add(new DirectoryCatalog(ConfigurationManager.AppSettings["MyModuleFolderLocation"]));
aggregateCatalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly));
_container = new CompositionContainer(aggregateCatalog);
CompositionBatch batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(_container);
_container.Compose(batch);
_container.SatisfyImportsOnce(this);
_configured = true;
}
protected override IEnumerable<Assembly> SelectAssemblies()
{
// SelectAssemblies() is called before Configure(), so manually force Configure() to run first so that MEF is instantiated properly
Configure();
if (!_configured)
{
throw new Exception("Unable to configure assemblies");
}
List<Assembly> assemblies = new List<Assembly>();
assemblies.Add(Assembly.GetExecutingAssembly());
// Need to add all module assemblies so that Caliburn will be able to find the View for a ViewModel
foreach(IMyModule myModule in _myModules)
{
Assembly assembly = myModule.GetType().Assembly;
assemblies.Add(assembly);
}
return assemblies.Distinct();
}
This works just fine to get a module to be displayed properly.
But when a module has used an image, this image is never displayed, because this kind of loading apparently doesn't take resources into account. I create a Resources.resx file in the module project and add an image to that. The image file that is presented in Visual Studio then has a Build Action that says "Resource" and "Do not copy (to output directory)". This should mean that the image is embedded in the resulting DLL file.
The image is placed in a folder called "Resources" in the module project, and the XAML use it like this:
<Image Source="/Resources/myImage.png" />
The image is displayed in the preview in Visual Studio, but is not displayed when the application runs.
What I have tried that didn't work
- Referencing the image in another way:
<Image Source="pack://application:,,,/Resources/myImage.png" />
- Getting the resources in BAML form and reinserting them into the executing assembly, like in this question: Instantiate ResourceDictionary xaml from other Assembly (which causes an OutOfMemoryException on this line
var reader = new Baml2006Reader(stream);
) - A lot of other answers that reference ResourceDictionary, but I have a Resource.resx file (which only generates an internal class that is not a ResourceDictionary)
The question remains
How can I get WPF/Caliburn.Micro to recognize resources from a DLL loaded by MEF?