WPF,MVVM IOC:服务定位器模式的替代方案.需要在后面的查看代码中依赖



遵循多个指南,我使用wpf .net 4.7.1和mvvm-light具有类似的应用程序布局。我是WPF BTW的新手。

app.xaml:

<Application x:Class="My.App" 
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:viewmodel="clr-namespace:My.ViewModel" 
         StartupUri="ViewMainView.xaml">
<Application.Resources>
    <ResourceDictionary>
        <viewmodel:ViewModelLocator x:Key="Locator" />
    </ResourceDictionary>
</Application.Resources>

将" ViewModeLocator"类注册为资源,并将WPF启动设置为" view/mainview.xaml"。

mainview.xaml:

<Window x:Class="My.View.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.DataContext>
    <Binding  Path="Main" Source="{StaticResource Locator}"/>
</Window.DataContext>

在使用视图定位器模式的情况下使用了ViewModeLocator。在此,将DataContext设置为" MainViewModel"(未显示(。尽管我不喜欢这样,但我可以在WPF XAML上下文中忍受它。但是,现在事实证明,我需要在视图的代码方面具有依赖性(而不是ViewModel(。

mainview.cs:

public partial class MainView : INotifyPropertyChanged
{
   public MainView()
   {
       // Need to access dependency here.          
   }
}

现在,我可以直接在该构造函数中调用ViewMododelocator,并从我的IOC容器中解析,但是我完全介入并接受了该模式。

我宁愿将依赖项注入ctor中,如果可能的话,我还将完全放置ViewModeLocator,并在此处注入ViewModel。

所以问题是,是否有一些标准的指导WPF应用程序使用我的容器?如果是的话,走这条路并不使用ViewModeLocator的东西是否可以?

您绝对不必使用 ViewModelLocator(旁注,服务定位器模式最近作为反pattern的批评,但我会让你组成你的自己的意见(。MVVM Light和其他库基本上使您可以使用工具套件。您不需要使用所有工具,也只能使用特定域所需的内容。

ViewModelLocator之外,有两种称为ViewModel FirstView First的模式都有其Pro和Cons。但是,这两者都提供了将代码解除的方法,这意味着以后再切换并不难。

对于使用MVVM Light构建应用程序的应用程序而没有服务定位器,我对视图的实现First方法看起来像这样。

我听说过ViewModel First是首选的观点,但是我首先发现视图对测试驱动开发(TDD(

更简单

app.xaml.cs(后面的应用程序代码(

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        var bootStrapper = new BootStrapper();
        //Container Builder
        var container = bootStrapper.BootStrap();
        var mainWindow = container.Resolve<MainWindow>();
        mainWindow.Show();
    }
}

bootstrapper.cs(在这种情况下,我正在使用autoFac,但您可以轻松替代。(

public class BootStrapper
{
    public IContainer BootStrap()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<MainWindow>().AsSelf();
        builder.RegisterType<MainWindowViewModel>().AsSelf();
        return builder.Build();
    }
}

mainWindowViewModel.cs

//I rolled my own ViewModelBase, but you can use MVVM Light's ViewModelBase
public class MainWindowViewModel : ViewModelBase
{
    public string DisplayProgram
    {
        get { return _displayProgram; }
        //MVVM Light's ViewModelBase uses RaisePropertyChanged();
        set { _displayProgram = value; OnPropertyChanged(); }
    }
    public void Initialize()
    {
        //Called from view code behind.
    }
}

mainwindow.xaml.cs(背后的mainwindow代码(

//When MainWindow.Show()..
public partial class MainWindow : Window
{
    private readonly MainWindowViewModel _viewModel;
    //Container resolves dependencies
    public MainWindow(MainWindowViewModel viewModel)
    {
        //Let base Window class do its thing.
        InitializeComponent();
        //Handle loaded event
        Loaded += MainWindowLoaded;
        //Hold on to the MainWindowViewModel, and set it as the windows DataContext            
        _viewModel = viewModel;
        DataContext = _viewModel;
    }
    private void MainWindowLoaded(object sender, RoutedEventArgs e)
    {
        _viewModel.Initialize();
    }
}

相关内容

  • 没有找到相关文章

最新更新