棱镜和简单的注射器
Prism and Simple Injector
我正在尝试使用简单的注入和棱镜进行简单的 HelloWorld
。
Git Source
应用程序启动时,出现此错误
Failed to assign to property
'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8
Position: 5]"
Exception thrown: 'System.MissingMethodException' in Prism.Windows.dll
Exception thrown: 'Windows.UI.Xaml.Markup.XamlParseException' in
HelloWorldPrism.exe WinRT information: Failed to assign to property
'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8
Position: 5] An exception of type
'Windows.UI.Xaml.Markup.XamlParseException' occurred in
HelloWorldPrism.exe but was not handled in user code WinRT
information: Failed to assign to property
'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8
Position: 5] Additional information: The text associated with this
error code could not be found. Failed to assign to property
'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8
Position: 5]
e.StackTrace " at 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()" string
<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));
}
When application starts, this error come up
在 MainView.xaml
中,您将 AutoWireViewModel
属性 定义为 true。一旦 属性 设置为 True
,ViewModelLocator
将尝试根据特定约定实例化相应的 ViewModel。由于您的 View 和 ViewModel 的名称符合约定,当您将此 属性 设置为 true 时,Prism 将帮助您实例化相应的 ViewModel。
在 Prism.mvvm
命名空间内,ViewModelLocationProvider
class 为 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: 'No parameterless constructor defined for this object.'
所以是Activator.CreateInstance(Type)
方法需要public构造器造成的,请看MissingMethodException
.
If I add a parameterless constructor it works normal.
看来这是正确的解决方案。如果你只是不想要 ViewModel
的无参数构造函数,你可以尝试实例化它并自己将 DataContext
设置为 View
。如果您怀疑这是 Prism 库的问题,也许您可以打开一个线程 here.
更新:
根据@rubWhosebug,OnInitializeAsync
方法缺少 ViewModelLocationProvider.SetDefaultViewModelFactory((viewModelType) => Container.GetInstance(viewModelType));
。
我正在尝试使用简单的注入和棱镜进行简单的 HelloWorld
。
Git Source
应用程序启动时,出现此错误
Failed to assign to property 'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8 Position: 5]"
Exception thrown: 'System.MissingMethodException' in Prism.Windows.dll Exception thrown: 'Windows.UI.Xaml.Markup.XamlParseException' in HelloWorldPrism.exe WinRT information: Failed to assign to property 'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8 Position: 5] An exception of type 'Windows.UI.Xaml.Markup.XamlParseException' occurred in HelloWorldPrism.exe but was not handled in user code WinRT information: Failed to assign to property 'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8 Position: 5] Additional information: The text associated with this error code could not be found. Failed to assign to property 'Prism.Windows.Mvvm.ViewModelLocator.AutoWireViewModel'. [Line: 8 Position: 5]
e.StackTrace " at 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()" string
<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));
}
When application starts, this error come up
在 MainView.xaml
中,您将 AutoWireViewModel
属性 定义为 true。一旦 属性 设置为 True
,ViewModelLocator
将尝试根据特定约定实例化相应的 ViewModel。由于您的 View 和 ViewModel 的名称符合约定,当您将此 属性 设置为 true 时,Prism 将帮助您实例化相应的 ViewModel。
在 Prism.mvvm
命名空间内,ViewModelLocationProvider
class 为 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: 'No parameterless constructor defined for this object.'
所以是Activator.CreateInstance(Type)
方法需要public构造器造成的,请看MissingMethodException
.
If I add a parameterless constructor it works normal.
看来这是正确的解决方案。如果你只是不想要 ViewModel
的无参数构造函数,你可以尝试实例化它并自己将 DataContext
设置为 View
。如果您怀疑这是 Prism 库的问题,也许您可以打开一个线程 here.
更新:
根据@rubWhosebug,OnInitializeAsync
方法缺少 ViewModelLocationProvider.SetDefaultViewModelFactory((viewModelType) => Container.GetInstance(viewModelType));
。