Wpf 是否每次ModelView在MVVM中使用模型时都需要使用DI和IoC?
我不熟悉应用程序的.NET MVVM结构,对其原理只有基本的了解,如解耦、绑定、命令等。我正在使用MVVM Light framework简化常见的MVVM问题,如消息传递和服务位置 有一件事我不明白:我是否需要在每次使用ViewModel中的模型类时调用SimpleIoC? 例子: 我有一个简单的视图,一个与之对应的视图模型和一个带有一个classWpf 是否每次ModelView在MVVM中使用模型时都需要使用DI和IoC?,wpf,dependency-injection,inversion-of-control,mvvm-light,Wpf,Dependency Injection,Inversion Of Control,Mvvm Light,我不熟悉应用程序的.NET MVVM结构,对其原理只有基本的了解,如解耦、绑定、命令等。我正在使用MVVM Light framework简化常见的MVVM问题,如消息传递和服务位置 有一件事我不明白:我是否需要在每次使用ViewModel中的模型类时调用SimpleIoC? 例子: 我有一个简单的视图,一个与之对应的视图模型和一个带有一个class设置的模型 main window.xaml <Window ...> <Window.Resources>
设置的模型
main window.xaml
<Window ...>
<Window.Resources>
<viewModels:MainWindowModel x:Key="ViewModel" />
</Window.Resources>
<DockPanel DataContext="{StaticResource ViewModel}">
<Button Command="{Binding DoSomeCommand}" />
</DockPanel>
</Window>
设置.cs
public class MainWindowModel: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ICommand DoSomeCommand { get; private set; }
protected void RaisePropertyChangedEvent(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public MainWindowModel()
{
DoSomeCommand = new RelayCommand(DoSome);
}
public void DoSome()
{
var data = Settings.Instance; //singleton
//... do some with data ...
Debug.Log($"{data.Prop1}, {data.Prop2}, {data.Prop3}");
}
}
public static class Settings
{
//... singleton implementations ...
public int Prop1 { get; set; } // implementation of getters and setters
public int Prop2 { get; set; }
public int Prop3 { get; set; }
}
这段代码有一个巨大的缺点:DoSome()
方法是不可单元测试的。好的,让我们解决这个问题:
public class MainWindowModel: INotifyPropertyChanged
{
//...
private Settings _data;
public MainWindowModel()
{
_data = Settings.Instance;
DoSomeCommand = new RelayCommand(() => DoSome(_data));
}
public void DoSome(Settings data)
{
//... do some with data ...
Debug.Log($"{data.Prop1}, {data.Prop2}, {data.Prop3}");
}
}
现在我可以模拟或存根设置类并测试DoSome()
但我知道“Settings”类可以在不同的实现中,比如“SettingsXML”(XML数据)、“SettingsRegistry”(窗口注册表数据)、“SettingsINI”(INI文件中的数据,wierd,但为true)。为了避免潜在的问题,我在接口中重写了它:
public interface ISettings
{
public int Prop1;
public int Prop2;
public int Prop3;
}
public static class Settings: ISettings
{
//... singleton implementations ...
public int Prop1 { get; set; } // implementation of getters and setters
public int Prop2 { get; set; }
public int Prop3 { get; set; }
}
public class MainWindowModel: INotifyPropertyChanged
{
//...
private ISettings _data;
public void DoSome(ISettings data)
{
... do some with data ...
Debug.Log($"_data.Prop1}, {data.Prop2}, {data.Prop3}");
}
}
我觉得一切都很好DoSome()
是可测试的,设置
实现可能不同。有一件事困扰着我:MainWindowModel
知道设置的实际类别(\u data=settings.Instance
)
在MVVM结构中可以吗
是否真的需要使用一些IoC,编写一些带有ISettings类的依赖注入的“SettingsRapper”类,然后使用\u data=SimpleIoc.Default.GetInstance
如果Settings
class不是singleton,我该怎么办
对不起,如果我对DI和IoC的基本概念完全错误的话。如果你能纠正我,我将不胜感激
有一件事困扰着我:MainWindowModel
知道设置的实际类别(\u data=settings.Instance
)
不应该。它应该只知道它正在使用的接口
创建MainWindowModel
类时,您可以将ISettings
类本身注入ISettings
,而不是将ISettings
对象传递给DoSome
方法:
public MainWindowModel(ISettings settings) { ... }
然后,您可以让ViewModelLocator
负责创建视图模型类:
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<ISettings>(() => Settings.Instance);
SimpleIoc.Default.Register<MainViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
}
公共类ViewModelLocator
{
公共ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(()=>SimpleIoc.Default);
simpleoc.Default.Register(()=>Settings.Instance);
SimpleIoc.Default.Register();
}
公共主视图模型主视图
{
收到
{
返回ServiceLocator.Current.GetInstance();
}
}
}
感谢您提供的信息,它比setingswrapper
类更有意义。是的,这只是从传递给ViewModelLocator中的SimpleIoc.Default.Register
方法的工厂操作中返回一个新实例的问题:SimpleIoc.Default.Register(()=>new Settings())代码>。
<DockPanel DataContext="{Binding Main, Source={StaticResource Locator}}">
<Button Command="{Binding DoSomeCommand}" />
</DockPanel>