WPF仿网易云搭建笔记(5):信息流控制之IOC容器

文章目录

专栏和Gitee仓库

WPF仿网易云 Gitee仓库
WPF仿网易云 CSDN博客专栏

前言

上一篇文章中,我们简单讲解了一下父子通讯的逻辑。父子通讯是强绑定逻辑。这里我们将讲解消息订阅通讯的方式。消息订阅一般用于之间通讯。

IOC容器

IOC容器有许多容器,目前.NET 有两个最优的依赖注入框架

  • Microsoft.Extensions.DependencyInjection:微软官方依赖注入框架,听说在.net core 8.0得到了最强的性能提升
  • Autofac:听说也是最强的依赖注入框架,性能强,开销低,功能完善。

Dependency injection in ASP.NET Core
Autofac 官网
深入浅出依赖注入容器------Autofac
.NET Core 依赖注入 Microsoft.Extensions.DependencyInjection

当然,Prism也有自己的IOC容器。

WPF Prims框架详解

我们这里使用Prism的IOC容器。因为Prism提供了全套的解决方案

Prism IOC使用

我之前使用过微软的IOC,这里我就不展开说明了。IOC容器的使用都是大差不多的。

Prism.Unity 依赖注入(IOC)的使用

声明两个测试的服务类

csharp 复制代码
namespace BlankApp1.Services
{
    public class TestA_Service
    {
        public string Name { get; set; }

        public TestA_Service() {
            Name = "小王";
        }
    }
}
csharp 复制代码
namespace BlankApp1.Services
{
    public class TestB_Service
    {
        public TestA_Service TestA_Serivce { get; set; }

        public string Name { get; set; }


        public TestB_Service(TestA_Service testA_Serivce)
        {
            TestA_Serivce = testA_Serivce;
            Name = "小红";
        }
    }
}

MainWindow IOC 注入单例

我们目前所有注入的IOC容器实例都是单例注入,生命周期暂时不考虑。

在App.xaml里面注入IOC容器

csharp 复制代码
        /// <summary>
        /// 这里是IOC容器的注入端口
        /// </summary>
        /// <param name="containerRegistry"></param>
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //这里对TestA_Service进行修改,查看IOC容器是否为单例。
            containerRegistry.RegisterSingleton<TestA_Service>(sp =>
            {
                return new TestA_Service()
                {
                    Name = "小丽",
                };
            });
            containerRegistry.RegisterSingleton<TestB_Service>();
            //注入MainWindow,这里注入先后没有影响
            containerRegistry.RegisterSingleton<MainWindow>();
        }

MainWindow里面获取

csharp 复制代码
public MainWindow(TestB_Service testB_Service)
{
    InitializeComponent();
    ViewModel = (MainWindowViewModel)DataContext;
    ViewModel.MainWindow = this;
    ViewModel.TestB_Service = testB_Service;
}

结果:获取成功!

UserController无法使用

但是如果我们使用TitleView会怎么样?


原因是为什么?因为是因为我们使用的是父子组件构造,但是这样WPF默认使用的是New 一个新对象,是无参构造。所以会报这个错误。

官方解决方案

Composing the User Interface Using the Prism Library for WPF

官方的解决比较简单粗暴,官方认为所有的UserController都是Prism构造的,这里面使用的是Prism的Region方案。所有的信息流都是通过Messager去设置的,如果是这样设置的话,我们所有的父子通讯都失败了。而且由于Messager的单一化,导致我们无法复用组件,因为如果存在多个组件ViewA,你不能确认ViewA到底是哪个ViewA,这个和我们的单例注入相违背。

使用自定义IOC容器,完美解决

Prism最大的问题,就是他是侵入式框架,你必须按照Prism的解决方案才能解决问题。而且给的方案都比较死。

既然Prism不好用,直接上微软的IOC

为什么要用微软的IOC容器,一个是微软的好用,另一个是ASP.NET Core也都是微软的IOC。能用一个解决就不学新的。

.NET Core 依赖注入 Microsoft.Extensions.DependencyInjection

解决方案

App.xaml.cs

csharp 复制代码
/// <summary>
/// 全局静态IOC构造器
/// </summary>
public readonly static ServiceProvider ServiceProvider;

/// <summary>
/// 静态构造,这里以单例举例
/// </summary>
static App() {
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<TestB_Service>();
    services.AddSingleton<TestA_Service>(sp =>
    {
        return new TestA_Service()
        {
        	//测试是否被修改。默认小王,修改为小兰
            Name = "小兰"
        };
    });
    ServiceProvider = services.BuildServiceProvider();
    var res = ServiceProvider.GetService<MainWindowViewModel>();
}

ViewModel里面直接调用

csharp 复制代码
public MainWindowViewModel()
{
    //直接从构造器里面拿到单例
    TestB_Service = App.ServiceProvider.GetService<TestB_Service>();
}

运行结果

其实通过Service可以进行间接通讯。这里我就不展开说明了。

总结

因为父子组件开发的特点,所有的UserController都可能存在多个,所以UserController是不能进行IOC的。因为IOC会有两个源,一个是Xaml实例化,另一个是IOC容器。还有一个问题是Xaml语法是不能进行IOC的,而且由于生命周期的原因,IOC实例化之前会报错。所以直接放弃UserController的IOC注入。

但是Services服务类可以进行IOC注入,比如数据库操作,网络通讯,业务逻辑(比如用户登录)。

我们目前已经完美解决了WPF 的信息流控制。通过WPF的组件化开发,消息订阅,IOC容器。大大降低了WPF项目的耦合,让我们可以将所有复杂的WPF 程序进行无限拆分。
DataContext强绑定,依赖属性暴露 父子组件通讯,Message消息订阅 IOC构造 IOC取出 View ViewModel ViewA Services IOC容器

相关推荐
斯文的八宝粥4 小时前
WPF企业内训全程实录(下)
大数据·hadoop·wpf
Zhu7586 小时前
使用腾讯CNB构建Hadoop定制容器镜像
大数据·hadoop·分布式
百里香酚兰6 小时前
【python学习笔记】pyttsx3库疑似只播报一次语音
笔记·python·学习
TTBIGDATA7 小时前
【Ambari Plus】13.Spark 安装
大数据·hadoop·分布式·spark·ambari·sqoop·ambari plus
sunxunyong8 小时前
Hadoop租户创建
大数据·hadoop·分布式
chnyi6_ya9 小时前
论文阅读笔记:VideoWeaver — 面向智能体长视频生成的技能评估与进化
论文阅读·笔记·音视频
J_yyy9 小时前
基于Reactor的文件管理服务开发笔记
c++·笔记·reactor·多线程编程·muduo
浩瀚地学9 小时前
【Java基础复习】IO流(四)
java·开发语言·经验分享·笔记·学习
疯狂打码的少年9 小时前
【操作系统】板块总结 + 下期预告(软件工程)
笔记·软件工程
咸甜适中10 小时前
rust语言学习笔记——Tokio库(异步编程)
笔记·学习·rust·tokio