mui
mui copied to clipboard
MefContentLoader not resolving Constructor parameter
Hi,
I'm trying to create a simple IoC/DI scenario following this guide.
- Note: I religiously followed every step, but still to no avail.
I'm getting this error:
System.Windows.Markup.XamlParseException: 'No matching constructor found on type 'TestMef.Pages.Settings.Appearance'. You can use the Arguments or FactoryMethod directives to construct this type.' Line number '19' and line position '6'. ---> System.MissingMethodException: No default constructor found for type 'TestMef.Pages.Settings.Appearance'. You can use the Arguments or FactoryMethod directives to construct this type.
at System.Xaml.Schema.XamlTypeInvoker.DefaultCtorXamlActivator.EnsureConstructorDelegate(XamlTypeInvoker type)
at System.Xaml.Schema.XamlTypeInvoker.DefaultCtorXamlActivator.CreateInstance(XamlTypeInvoker type)
at System.Xaml.Schema.XamlTypeInvoker.CreateInstance(Object[] arguments)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstanceWithCtor(XamlType xamlType, Object[] args)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(XamlType xamlType, Object[] args)
--- End of inner exception stack trace ---
at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
at System.Windows.Application.LoadComponent(Uri resourceLocator)
at FirstFloor.ModernUI.Windows.DefaultContentLoader.LoadContent(Uri uri)
at FirstFloor.ModernUI.Windows.DefaultContentLoader.<>c__DisplayClass0_0.<LoadContentAsync>b__0()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
Page with constructor parameter (DI via MEF):
[ContentExport("/Pages/Settings/Appearance")]
public partial class Appearance : UserControl, IContent
{
[ImportingConstructor]
public Appearance(IAppearanceViewModel vm) //<= Why the cause of Error? While other parameterless pages are working just fine.
{
InitializeComponent();
DataContext = vm;
}
public void OnFragmentNavigation(FragmentNavigationEventArgs e){ }
public void OnNavigatedFrom(NavigationEventArgs e){ }
public void OnNavigatedTo(NavigationEventArgs e){ }
public void OnNavigatingFrom(NavigatingCancelEventArgs e){}
}
//ViewModel decalaration (in a separate file)
[Export(typeof(IAppearanceViewModel))]
public class AppearanceViewModel
: NotifyPropertyChanged, IAppearanceViewModel
{
//skipped contents for brevity
}
App.xaml:
<Application x:Class="TestMef.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />
<ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml"/>
<ResourceDictionary Source="/Resources/AppResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
AppResources.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
xmlns:testMef="clr-namespace:TestMef">
<Style x:Key="ModernFrame" TargetType="mui:ModernFrame">
<Setter Property="ContentLoader" Value="{DynamicResource MefContentLoader}" />
</Style>
<Style x:Key="ModernTab" TargetType="mui:ModernTab">
<Setter Property="ContentLoader" Value="{DynamicResource MefContentLoader}" />
</Style>
<Style x:Key="MainWindow" TargetType="testMef:MainWindow">
<Setter Property="ContentLoader" Value="{DynamicResource MefContentLoader}" />
</Style>
</ResourceDictionary>
MefContentLoader:
[Export]
public class MefContentLoader : DefaultContentLoader
{
private readonly IEnumerable<Lazy<IContent, IContentMetadata>> contents;
[ImportingConstructor]
public MefContentLoader([ImportMany]IEnumerable<Lazy<IContent, IContentMetadata>> contents)
{
this.contents = contents;
}
protected override object LoadContent(Uri uri)
{
// lookup the content based on the content uri in the content metadata
var content = contents.Where(r => r.Metadata.ContentUri == uri.OriginalString)
.Select(r=>r.Value)
.FirstOrDefault();
if (content == null) throw new ArgumentException("Invalid uri: " + uri);
return content;
}
}
Please advise.
Thank you in advance.
MefContentLoader must get a default contructor. find another away to pass the contents of MefContentLoader