WPF应用程序开发:MVVM与依赖注入

当开发者第一次编写WPF应用程序时,他们可能会发现它与传统的Windows Forms应用程序非常相似,因此可能会选择将所有代码写在代码后台(code behind)。但随着时间的推移,代码量会变得庞大且难以管理。几天后,开发者会了解到WPF的数据绑定特性,这可以在一定程度上减少代码后台的代码量。

如果使用模型-视图-视图模型(Model View ViewModel,MVVM)设计模式,可以大大减少代码后台的代码量。这种设计模式实际上利用了WPF的数据绑定特性,并提供了良好的关注点分离。这样,视图(XAML)可以在一定程度上由其他人独立开发/设计,而核心开发人员可以专注于业务逻辑。关于MVVM的更多细节,可以在这里学习。

如果使用Unity依赖注入容器,关注点分离可以进一步增强。依赖注入是构建松耦合应用程序的主要技术。它提供了处理对象之间依赖关系的方法。例如,处理客户信息的对象可能依赖于访问数据存储、验证信息以及检查用户是否有权执行更新的其他对象。依赖注入技术可以确保客户类正确地实例化并填充所有这些对象,特别是在依赖关系可能是抽象的情况下。可以在这里了解更多关于Unity的信息。

Unity依赖注入容器的概念和工作过程可能在第一眼看起来像是阿拉丁神灯中的精灵。像处理精灵一样,Unity DI容器需要谨慎和智能地处理。本文主要介绍了如何通过一些示例代码轻松使用这种“魔法”。(为了方便,已经附上了这里讨论的示例应用程序的完整代码库。)

在这里,主要讨论了构造函数注入和属性注入,以便人们可以将其作为快速参考。Unity依赖容器可以被视为一个有用的对象“银行”。通常在银行里,存钱以便在需要时使用。因此,在应用程序初始化时,应该存储在应用程序生命周期中将被各种窗口/用户控件等需要的所有对象,如下所示: C# IUnityContainer container = new UnityContainer(); container.RegisterType(); container.RegisterType(); var window = container.Resolve(); window.Show();

在应用程序中,有一个TextDataServices,它主要返回一个硬编码的字符串,有一个TextViewModel,其中只有一个字符串属性,这个属性应该在某些UI标签中设置。在MainWindow.XAML中,有两个Label控件,一个在左边(LabelLeft),一个在右边(LabelRight),如下所示: XML <Label Content="{Binding Path=LabelContnet,FallbackValue=Left}" Height="28" HorizontalAlignment="Left" Margin="90,85,0,0" Name="LabelLeft" VerticalAlignment="Top" Width="222" Grid.ColumnSpan="2" /> <Label Content="{Binding Path=LabelContnet,FallbackValue=Right}" Grid.Column="1" Height="28" HorizontalAlignment="Left" Margin="90,85,0,0" Name="LabelRight" VerticalAlignment="Top" Width="222" />

现在让集中讨论这个XAML文件的代码后台(MainWindow.xaml.cs): C# public partial class MainWindow : Window { /// <summary> /// Initializes a new instance of the <see cref="MainWindow"> class. /// </see> /// </summary> /// <The text view model.> public MainWindow(ITextViewModel textViewModel) { InitializeComponent(); Loaded += MainWindow_Loaded; DataContext = textViewModel; /// <Following code actually throws exception as Dependency injected after constructed has been called.> /// <LabelLeft.Content = Services.GetData();> } [Dependency] public IDataServices Services { get; set; } /// <summary> /// Handles the Loaded event of the MainWindow control. /// </summary> /// <The source of the event.> /// <The <see cref="System.Windows.RoutedEventArgs"> instance containing the event data.> private void MainWindow_Loaded(object sender, RoutedEventArgs e) { LabelLeft.Content = Services.GetData(); } } 在构造函数中,可以看到有一个参数类型为ITextViewModel,这将由Unity在从OnStartup事件的App.xaml.cs中解析这个窗口时注入。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485