首页 > 编程语言 >C#进阶-快速了解IOC控制反转及相关框架的使用

C#进阶-快速了解IOC控制反转及相关框架的使用

时间:2024-08-26 15:24:36浏览次数:12  
标签:进阶 C# public 对象 MyTestMessage Message IOC class

目录

一、了解IOC

1、概念

2、生命周期

二、IOC服务示例

1、定义服务接口 

2、实现服务

三、扩展-CommunityToolkit.Mvvm工具包

Messenger信使

方式一(收发消息)

方式二(收发消息)

方式三(请求消息)


一、了解IOC

IOC,即控制反转(Inversion of Control),它通过将对象的创建和管理责任从应用程序代码中转移到外部容器或框架中,实现了对象之间的松耦合和依赖性反转。

1、概念

  • 依赖注入(Dependency Injection, DI)

    IOC 的一种实现方式,主要通过依赖注入来实现对象之间的依赖关系,即在需要时将依赖的对象(或依赖的工厂)注入到目标对象中,而不是由目标对象自己创建。DI注入三方式:构造函数注入、属性注入、方法注入。
  • 容器(Container)

    IOC 容器是负责管理和注入对象的工具或框架,它可以配置、创建和组装对象,同时解决对象之间的依赖关系。常见的 IOC 容器包括 Spring Framework(Java)、Unity(C#)、Guice(Java)、Dagger(Android)等。
  • 松耦合(Loose Coupling)

    通过IOC,对象之间的依赖关系由外部容器来管理,使得对象之间的耦合度降低。这样,当需要改变某个对象的依赖关系时,只需调整配置,而不需要修改对象本身的代码。

2、生命周期

单例(Singleton)

单例生命周期保证在整个应用程序生命周期内只存在一个对象实例。无论有多少个请求,IOC 容器始终返回同一个实例。这种方式适合那些需要在应用程序中共享状态或资源的对象,确保了对象的唯一性和共享性。

services.AddSingleton<IApplicationService,ApplicationService>

作用域(Scoped)

作用域生命周期指定对象的生命周期与特定的作用域相关联,例如每个 HTTP 请求或每个事务。在每个作用域内,只会创建一个对象实例,并且在作用域结束时销毁。这种方式在需要限定对象生命周期到特定范围内的情况下非常有用,例如在 Web 应用中处理请求时

services.AddScoped<IApplicationService,ApplicationService>

瞬时(Transient)

瞬时生命周期意味着每次请求时都会创建一个新的对象实例。这种方式适合那些无需长时间维持状态的对象,每次请求都需要一个全新的、独立的对象实例。在 IOC 容器中,每次解析时都会创建一个新的对象。

services.AddTransient<IApplicationService,ApplicationService>

二、IOC服务示例

添加NuGet包:Microsoft.Extensions.DependencyInjection

1、定义服务接口 

    public interface IService
    {
        /// <summary>
        /// 注册服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TObject"></typeparam>
        void RegisterService<T, TObject>()  where T : class where TObject : class, T;


        /// <summary>
        /// 获取服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        T AccessService<T>() where T : class;
    }

2、实现服务

    public class IOCService : IService
    {
        private static readonly Lazy<IOCService> _instance= new Lazy<IOCService>(() => new IOCService());

        public static IOCService Instance=>_instance.Value;

        private IOCService()
        {
                
        }

        IServiceProvider serviceProvider;

        ServiceCollection container = new ServiceCollection();

        public void RegisterService<T, TObject>()
            where T : class
            where TObject : class, T
        {
            container.TryAddSingleton<T, TObject>();        //单例
            //container.TryAddScoped<T, TObject>();         //作用域
            //container.TryAddTransient<T, TObject>();      //瞬态
            serviceProvider = container.BuildServiceProvider();
        }

        public T AccessService<T>() where T : class
        {
            if (serviceProvider is null)
                return null;
            return serviceProvider.GetService<T>();
        }
    }

三、扩展-CommunityToolkit.Mvvm工具包

Messenger信使

用于不同界面传输数据 

方式一(收发消息)

1、创建消息 

  public class MyTestMessage
    {
        public MyTestMessage(string msg)
        {
            Message = msg;
        }

        public string Message { get; }
    }

2、发布消息(某界面)

WeakReferenceMessenger.Default.Send<MyTestMessage>(new MyTestMessage(sendMsg));

3、订阅消息(其它界面)

WeakReferenceMessenger.Default.Register<MyTestMessage>(this, (r, m) => 
{
    //处理接收到的消息
    Message = m.Message;
});

方式二(收发消息)

1、创建消息   

public class MyTestMessage
{
    public MyTestMessage(string msg)
    {
        Message = msg;
    }

    public string Message { get; }
}

2、发布消息(某界面)

WeakReferenceMessenger.Default.Send<MyTestMessage>(new MyTestMessage(sendMsg));

3、订阅消息(其它界面),实现接口IRecipient<T>

    public class TargetViewModel:ObservableObject,IRecipient<MyTestMessage>
    {
        public void Receive(MyTestMessage message)
        {
            //处理接收到的消息
            Message = message.Message;
        }

        public TargetViewModel()
        {
            WeakReferenceMessenger.Default.Register(this);
        }

        private string message="Init";
            
        public string Message
        {
            get => message;
            set => SetProperty(ref message, value);
        }

    }

方式三(请求消息)

1、创建消息

    public class MyTestMessage
    {
        public MyTestMessage(string msg)
        {
            Message = msg;
        }

        public string Message { get; }
    }

    public class MyRequestMessage : RequestMessage<MyTestMessage>
    { 
    
    }

2、发送请求消息(某界面)

MyTestMessage reply= WeakReferenceMessenger.Default.Send<MyRequestMessage>();
MessageBox.Show(reply.Message);

3、回复消息(其它界面)

WeakReferenceMessenger.Default.Register<TargetViewModel,MyRequestMessage>(this, (r, m) =>
{
    //回复
    m.Reply(new MyTestMessage("ReplyMsg"));
});

标签:进阶,C#,public,对象,MyTestMessage,Message,IOC,class
From: https://blog.csdn.net/rwo_bear/article/details/140851634

相关文章

  • 什么是友元?什么可以做友元?友元能干什么?(全局函数做友元,类做友元,成员函数做友元)c/c++
    一、什么是友元例如:你的生活中有一个特别好的朋友,你允许它进入你的房间(私有场所)也允许他进入客厅(相对公有场所),但是对于其他人你是不会允许他进入你的房间的,只允许他进入客厅。类对象也有这样类似的好朋友类,可以访问本类的私有成员,这个好朋友类就叫做这个类的友元,友元也可......
  • 【NOI】C++数据结构入门之一维数组(三)元素移动
    文章目录前言一、概念1.导入2.元素移动2.1逆序2.2删除2.3插入二、例题讲解问题:1009-数组逆序问题:1162-数组元素的删除问题:1211-数组元素的插入问题:1161.元素插入有序数组问题:1159.数组元素的移动三、总结四、感谢前言在继续我们的C++数据结构学习之旅......
  • jenkins安装及自动化部署-docker部署
    一、安装1.创建jenkins工作目录mkdir/home/chanfi/docker/jenkins2.下载JDK#进入工作目录下cd/home/chanfi/docker/jenkins#创建JDK目录mkdirjavacdjava#下载jdk(或到官网中下载:https://www.oracle.com/java/technologies/downloads/?er=221886)wgethttps://d......
  • 数据库性能诊断利器 聚好看DBdoctor亮相中国数据库技术大会
       2024年8月22-24日,备受瞩目的第15届中国数据库技术大会(DTCC2024)于北京隆总召开。数字化创新浪潮汹涌澎湃,数据库作为信息技术的核心基础设施,正以前所未用的速度推动各行各业的智能化升级。作为在数据库技术领域率先掌握前沿eBPF技术的企业,聚好看科技于本次大会展示自研数据......
  • 【文档智能 & RAG】浅看开源的同质化的文档解析框架-Docling
    前言RAG的兴起,越来越多的人开始关注文档结构化解析的效果,这个赛道变得非常的同质化。关于文档智能解析过程中的每个技术环节的技术点,前期文章详细介绍了很多内容:下面我们简单的看看Docling这个PDF文档解析框架里面都有什么技术。方法布局分析模型首先,Docling使用一......
  • OpenCV(cv::addWeighted()、cv::threshold())
    目录1.cv::addWeighted()函数定义:参数详解:公式:例子:2.cv::threshold()函数定义:参数详解:返回值:例子:3.总结:1.cv::addWeighted()cv::addWeighted()是OpenCV中用于将两幅图像按指定的权重进行加权求和的函数。主要用途包括图像融合、过渡效果生成等。函数定义:voidcv::add......
  • CSS处理font-weight不生效问题
    如何解决Android系统中文字体字重问题翻找了几天资料,发现NotoSansSC字体能支持中文/数字/英文字体100,300,400,500,700,900的字重,具体如下图所示:<linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Noto+Sans+SC:300,400,500,600,700"></link>.t......
  • JavaScript 对象访问器
    JavaScript访问器(Getter和Setter)Getter和Setter允许您定义对象访问器(被计算的属性)。<!DOCTYPEhtml><htmllang="en"><body><pid="demo"></p><script>constperson={nama:"DianDi......
  • [javascript] 使用 puppeteer 包模拟 chrome 自动化
    npmipuppeteerconstpuppeteer=require('puppeteer');functionsleep(ms){returnnewPromise(resolve=>setTimeout(resolve,ms));}asyncfunctionrun(){constbrowser=awaitpuppeteer.launch({headless:false,args:['--st......
  • 利用kafka和kafka connect插件debezium实现oracle表同步
    1.kafka安装1.1.java安装openjdk下载,建议使用17,至少应该高于版本11#进入家目录,解压下载的java包,配置环境变量tarvxfopenjdk-20.0.1_linux-x64_bin.tar.gz-C/usr/local/vi.bash_profile#注意要把JAVA的目录放到$PATH之前exportJAVA_HOME=/usr/local/jdk-20exportP......