详解c# 事件总线

详解C#事件总线攻略

事件总线是一种让不同对象之间相互通信的方式。它可以让多个对象在程序运行时相互协作,轻松实现松耦合(loose coupling)和高内聚(high cohesion)的编程状态。

事件总线的基础知识

事件总线是一个对象,它处理应用程序中的所有事件,并将它们发送给已经订阅这些事件的对象。这些对象被称为“事件订阅者”。

事件总线的实现方式

  • 委托和事件:在C#中,可以使用委托和事件来实现事件总线。事件总线是一个包含委托和事件的静态类。它负责管理应用程序中所有的事件和事件订阅者。
  • 消息传递机制:另一种实现事件总线的方式是通过消息传递机制,例如使用RabbitMQ或Azure Service Bus等消息队列服务。这种方式可以让事件总线跨越多个系统,实现分布式系统中的事件通信。

基于委托和事件的事件总线实现

委托

在C#中,委托是一种类型,它持有对方法的引用。委托可以被赋值给其他变量,传递给方法,存储在集合中等等。定义委托的方法签名必须和所指向的方法的签名完全一致。

public delegate void MyDelegate(int arg1, int arg2);

事件

事件是委托的一种特殊形式,它允许对象通知其他对象其发生的事情,而不需要知道这些其他对象的类型。事件是由委托和事件处理程序(event handler)组成的。

public event MyDelegate MyEvent;

实现事件总线

下面是一个简单的事件总线示例,包含了事件、委托和事件总线的基本实现。

public static class EventBus
{
    public delegate void EventHandler(object sender, EventArgs args);

    // 事件订阅字典,用于存储事件处理程序列表
    private static readonly Dictionary<Type, IList<EventHandler>> Subscribers = new Dictionary<Type, IList<EventHandler>>();

    // 发布事件
    public static void Publish<T>(object sender, T args)
        where T : EventArgs
    {
        IList<EventHandler> handlers;
        if (Subscribers.TryGetValue(typeof(T), out handlers))
        {
            foreach (var handler in handlers)
            {
                handler(sender, args);
            }
        }
    }

    // 订阅事件
    public static void Subscribe<T>(EventHandler handler)
        where T : EventArgs
    {
        IList<EventHandler> handlers;
        if (!Subscribers.TryGetValue(typeof(T), out handlers))
        {
            handlers = new List<EventHandler>();
            Subscribers.Add(typeof(T), handlers);
        }

        handlers.Add(handler);
    }

    // 取消订阅事件
    public static void Unsubscribe<T>(EventHandler handler)
        where T : EventArgs
    {
        IList<EventHandler> handlers;
        if (Subscribers.TryGetValue(typeof(T), out handlers))
        {
            handlers.Remove(handler);
        }
    }
}

在这个例子中,EventBus是一个静态类,它包含了事件订阅字典Subscribers和三个方法:Publish、Subscribe和Unsubscribe。事件订阅字典用于存储订阅某个类型的事件的所有处理程序。Publish方法用于发布事件,它会根据事件类型查找所有对应的事件处理程序,然后依次调用它们。Subscribe和Unsubscribe方法用于订阅和取消订阅事件。

示例1:事件总线在MVC框架中的应用

假设你正在开发一个MVC框架,并且需要实现控制器(Controller)和视图(View)之间的通信。下面是一个使用事件总线实现这个功能的简单示例。

public class Controller
{
    public Controller()
    {
        EventBus.Subscribe<ViewInitializedEventArgs>(OnViewInitialized);
    }

    private void OnViewInitialized(object sender, EventArgs args)
    {
        // 响应视图初始化事件
        var view = (View)sender;
        view.SetModel(new Model());
    }
}

public class View
{
    public View()
    {
        EventBus.Publish(this, new ViewInitializedEventArgs());
    }

    public void SetModel(Model model)
    {
        // 设置视图的模型
    }
}

public class ViewInitializedEventArgs : EventArgs
{
}

在这个示例中,Controller订阅了ViewInitializedEventArgs事件,并在事件发生时调用OnViewInitialized方法。View在构造函数中发布了ViewInitializedEventArgs事件。当View构造完成后,Controller会收到这个事件,并调用SetModel方法来设置View的模型。

示例2:在控制台应用程序中使用事件总线

下面是一个在控制台应用程序中使用事件总线的简单示例。

public static class Program
{
    public static void Main()
    {
        EventBus.Subscribe<MyEventArgs>(OnMyEvent);

        // 发布事件
        EventBus.Publish(null, new MyEventArgs(1, 2));
    }

    private static void OnMyEvent(object sender, EventArgs args)
    {
        var myArgs = (MyEventArgs)args;
        Console.WriteLine($"MyEvent handled: {myArgs.Arg1}, {myArgs.Arg2}");
    }
}

public class MyEventArgs : EventArgs
{
    public MyEventArgs(int arg1, int arg2)
    {
        Arg1 = arg1;
        Arg2 = arg2;
    }

    public int Arg1 { get; }
    public int Arg2 { get; }
}

在这个示例中,Main方法订阅MyEventArgs事件,并在事件发生时调用OnMyEvent方法。在Main方法中,它发布了一个MyEventArgs事件,并触发OnMyEvent方法。OnMyEvent方法将事件参数Arg1和Arg2输出到控制台。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解c# 事件总线 - Python技术站

(2)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • C# 内部类与Lambda表达式用法详解

    下面是“C# 内部类与Lambda表达式用法详解”的完整攻略: 1. C# 内部类 1.1 什么是内部类 在 C# 中,内部类又叫嵌套类,是指一个类定义在另一个类的内部。内部类可以访问外部类的成员,而外部类也可以访问内部类的成员。内部类可以使用 private、public、protected 和 internal 等访问修饰符,一般来说,内部类的访问修饰符…

    C# 2023年6月1日
    00
  • MASA MinimalAPI源码解析:为什么我们只写了一个app.MapGet,却生成了三个接口

    源码解析:为什么我们只写了一个app.MapGet,却生成了三个接口 1.ServiceBase 1.AutoMapRoute 源码如下: AutoMapRoute自动创建map路由,MinimalAPI会根据service中的方法,创建对应的api接口。 比如上文的一个方法: public async Task<WeatherForecast[]&g…

    C# 2023年5月9日
    00
  • C#常用目录文件操作类实例

    C#常用目录文件操作类实例 在C#的编程过程中,我们需要对文件和目录进行操作。为了方便开发,C#提供了一些常用的目录文件操作类。本文将详细介绍这些类的使用方法,并给出两个实例。 目录操作类 Directory类 Directory类提供了很多操作目录的方法,例如创建、删除、复制和移动目录等。 创建目录 创建目录的方法为: Directory.CreateDi…

    C# 2023年5月15日
    00
  • ASP.NET Core读取配置文件

    ASP.NET Core 读取配置文件是一种非常常见的操作,可以用于配置应用程序的行为。以下是 ASP.NET Core 基础之读取配置文件的完整攻略: 步骤一:创建 ASP.NET Core 应用程序 首先,需要一个 ASP.NET Core 应用程序。可以使用以下命令在 Visual Studio 中创建一个 ASP.NET Core 应用程序: 打开 …

    C# 2023年5月17日
    00
  • C#拼图游戏编写代码(2)

    下面详细讲解如何编写C#拼图游戏的代码,具体分为以下步骤: 1. 创建WinForm窗口 代码中首先需要创建一个WinForm窗口,作为整个游戏的主界面。 public partial class FormMain : Form { public FormMain() { InitializeComponent(); } } 2. 添加拼图图片并进行切割 接…

    C# 2023年5月15日
    00
  • web 容器的设计如何实现

    Web 容器是指可以在其中运行 Web 应用程序的软件环境,它负责处理用户的 HTTP 请求并返回 HTTP 响应。Web 容器设计的核心是它的请求处理机制,实现 Web 容器的设计需要考虑以下几个方面。 设计 Web 容器的工作流程 Web 容器处理 HTTP 请求的基本流程是:接收请求、解析请求、调度资源、执行响应、发送结果。 接收请求:Web 容器需要…

    C# 2023年6月6日
    00
  • C# using的本质及使用详解

    C#中的using语句是一个用于自动管理资源的语句块,它可以帮助我们避免手动管理资源时忘记释放资源的常见错误,从而提高代码的可读性、可维护性和安全性。在本文中,我将详细讲解using语句的本质和用法,以及几个使用示例。 什么是using语句? 在C#中,using语句被用于维护和管理对象的生命周期。它是一个便捷的语句块,允许我们使用或者初始化需要释放资源的对…

    C# 2023年6月6日
    00
  • relaxlife.net发布一个自己开发的中文分词程序

    下面我将为你详细讲解“relaxlife.net发布一个自己开发的中文分词程序”的完整攻略。 准备工作 首先,我们需要准备好以下工具和环境:- Python 3及以上版本;- 第三方中文分词库(如jieba);- Flask框架;- HTML、CSS、JavaScript基础知识。 开发过程 步骤一:安装第三方分词库 打开命令行终端,使用以下命令安装jieb…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部