I have a window called MainWindow
and a viewmodel called MainWindowViewModel
.
I want to look into MEF's container to see if I can find <WindowName>ViewModel
.
The code I have is:
CompositionContainer container;
var catalog = new AssemblyCatalog(typeof(App).Assembly);
container = new CompositionContainer(catalog);
container.ComposeParts(this);
container.SatisfyImportsOnce(this);
I saw the method
container.GetExports(Type, Type, String)
but it only allows me to get exports of the first Type
parameter. All I have is a string name.
I wanted to do something like
allExports.FirstOrDefault(e => e.GetType().Name.StartsWith(something))
Is there a way I can get an exported value by a string name
?
Since allExports is IEnumerable< Lazy< T >> you can't get each exported type without creating the associated value (by calling .Value), and then inspecting value type. And this is not really a good thing to create all values. All you can get is the typeof(T) by analyzing typeof(Lazy< T >), that's all.
Metadata is the good way to go :
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ExportViewModelAttribute : ExportAttribute, IViewModelMetadata
{
public ExportViewModelAttribute(Type declaredType)
: base(null, typeof(IViewModel))
{
this.DeclaredType = declaredType;
}
public Type DeclaredType { get; private set; }
}
with interface as :
public interface IViewModelMetadata
{
Type DeclaredType { get; }
}
then you export with :
[ExportViewModel(typeof(MyViewModel))]
public class MyViewModel: BaseViewModel, IViewModel
{
[...]
}
And then retreive it with a where clause on metadata
IViewModel vm = container.GetExports<IViewModel, IViewModelMetadata>().Where(i => i.Metadata.DeclaredType == typeof(MyViewModel)).Select(i => i.Value).FirstOrDefault();
or with
i => i.Metadata.DeclaredType.Name == "mysearchedViewModel"