Search code examples
c#wpfmefcaliburn.micro

Getting Information From Lazy Initialized Exports


I want to bind a (Imported with MEF2 Convention) IEnumerable<Lazy<IModule>> collection to a Menu.

IModule is an interface to ViewModels located in an external project.

My problem is, with Lazy<T>, I cannot figure out how I can obtain a MenuName (and what MenuParent it belongs under, if any) without instantiating the object, and this defeats the purpose of Lazy Initialization (there are a lot of Modules and each user needs to use a very small number). I use Caliburn.Micro for MVVM.

I have thought about storing the Menu structure in the Database, but this is added points of failure when other developers create new Modules or remove obsolete Modules, and is similar to hardcoding the menu.

MEF Export:

RegistrationBuilder builder = new RegistrationBuilder()
builder.ForTypesDerivedFrom<IModule>.Export<IModule>

MenuViewModel:

private IEnumerable<Lazy<IModule>> _modules;

public MenuViewModel(IEnumerable<Lazy<IModule>> modules)
{
    _modules = modules;
}

public IEnumerable<Lazy<IModule>> Modules
{
    get { return _modules; }
    set { _modules = value; }
}

I stopped here, because there is nothing to bind to. Lazy<IModule> doesn't contain any information about the type bound to it.

I am looking for a strategy to allow for MEF Exports of 3rd party plugins, the names of which I can display on a Menu, without hardcoding the menu.


Solution

  • The Value property of the Lazy<IModule> will initialize and return an IModule, but of course you need to instantiate them in order to be able to get any information from them.

    Instead of using a Lazy<T>, you could bind to some light-weight view model object. This means that you will have to create an additional type for each module but this shouldn't be an issue given your requirements.