Wpf 是否每次ModelView在MVVM中使用模型时都需要使用DI和IoC?

Wpf 是否每次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>

我不熟悉应用程序的.NET MVVM结构,对其原理只有基本的了解,如解耦、绑定、命令等。我正在使用MVVM Light framework简化常见的MVVM问题,如消息传递和服务位置

有一件事我不明白:我是否需要在每次使用ViewModel中的模型类时调用SimpleIoC? 例子: 我有一个简单的视图,一个与之对应的视图模型和一个带有一个class
设置的模型

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>