棱镜和简单注射器

时间:2017-06-12 02:58:42

标签: mvvm uwp prism simple-injector

我正在使用简单的注入和棱镜尝试一个简单的HelloWorldGit Source

当应用程序启动时,会出现此错误

  

无法分配属性   ' Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel&#39 ;. [行:8   位置:5]"

           

抛出异常:' System.MissingMethodException'在Prism.Windows.dll中   抛出异常:' Windows.UI.Xaml.Markup.XamlParseException'在   HelloWorldPrism.exe WinRT信息:无法分配给属性   ' Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel&#39 ;. [行:8   位置:5]类型的例外   ' Windows.UI.Xaml.Markup.XamlParseException'发生在   HelloWorldPrism.exe但未在用户代码WinRT中处理   信息:无法分配给属性   ' Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel&#39 ;. [行:8   位置:5]附加信息:与此相关的文本   找不到错误代码。无法分配给属性   ' Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel&#39 ;. [行:8   位置:5]

     

e.StackTrace"在Windows.UI.Xaml.Application.LoadComponent(Object   component,Uri resourceLocator,ComponentResourceLocation   componentResourceLocation)\ r \ n at   HelloWorldPrism.Views.MainView.InitializeComponent()\ r \ n at   HelloWorldPrism.Views.MainView..ctor()"串

<Page
    x:Class="HelloWorldPrism.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:mvvm="using:Prism.Windows.Mvvm"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    mc:Ignorable="d"
    >
public MainViewModel(INavigationService navigationService)
{
    _navigationService = navigationService;
}

如果我添加一个无参数构造函数,它就可以正常工作。

public MainViewModel()
{
}

App.cs

protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
    Window.Current.Activate();
    return Task.FromResult(true);
}

protected override void CreateAndConfigureContainer()
{
    Logger.Log("Creating and Configuring Container", Category.Debug, Priority.Low);
    Container = CreateContainer();
}

protected override Container CreateContainer()
{
    return new Container();
}

protected override UIElement CreateShell(Frame rootFrame)
{
    var shell = Container.GetInstance<MainView>();
    shell.SetFrame(rootFrame);
    return shell;
}

protected override Type GetPageType(string pageToken)
{
    var type = Type.GetType(string.Format(CultureInfo.InvariantCulture, GetType().AssemblyQualifiedName.Replace(GetType().FullName, GetType().Namespace + ".Views.{0}View"), pageToken));
    if (type != null)
        return type;
    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ResourceLoader.GetForCurrentView("/Prism.Windows/Resources/").GetString("DefaultPageTypeLookupErrorMessage"), pageToken, GetType().Namespace + ".Views"), nameof(pageToken));
}

protected override Task OnInitializeAsync(IActivatedEventArgs args)
{
    Container.RegisterSingleton(SessionStateService);
    Container.RegisterSingleton(DeviceGestureService);
    Container.RegisterSingleton(NavigationService);
    Container.RegisterSingleton(EventAggregator);
    return Task.CompletedTask;
}

protected override void ConfigureViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => new 
    SimpleInjectorServiceLocatorAdapter(Container));
}

1 个答案:

答案 0 :(得分:2)

  

当应用程序启动时,会出现此错误

MainView.xaml中,您将AutoWireViewModel属性定义为true。将此属性设置为True后,ViewModelLocator将尝试根据特定约定实例化相应的ViewModel。由于View和ViewModel的名称符合约定,因此当您将此属性设置为true时,Prism将帮助您实例化相应的ViewModel。

Prism.mvvm命名空间内,ViewModelLocationProvider类定位视图模型,该视图模型的AutoWireViewModelChanged附加属性设置为true。并且ViewModelLocationProvider class:

的以下代码行引发了错误
/// <summary>
/// The default view model factory which provides the ViewModel type as a parameter.
/// </summary>
static Func<Type, object> _defaultViewModelFactory = type => Activator.CreateInstance(type);
  

System.MissingMethodException:'没有为此对象定义无参数构造函数。'

因为Activator.CreateInstance(Type)方法需要公共构造函数,所以请参阅MissingMethodException

  

如果我添加一个无参数构造函数,它就可以正常工作。

这似乎是正确的解决方案。如果您只是不想要ViewModel的无参数构造函数,您可以尝试实例化它并自己将DataContext设置为View。如果您怀疑这是Prism库的问题,也许您可​​以打开一个帖子here

<强>更新

根据@rubStackOverflow,它在ViewModelLocationProvider.SetDefaultViewModelFactory((viewMo‌​delType) => Container.GetInstance(viewModelType));方法上缺少OnInitializeAsync