MediatR,中介者模式的超级实现!

MediatR,中介者模式的超级实现!

大家好啊,我是你们的羊哥!今天要给大家介绍一个特别好用的.NET工具 - MediatR。它是中介者模式的一个超级实现,能帮我们解决组件之间的通信问题。想象一下,如果我们的代码是一个大型公司,MediatR就像是公司的总机系统,帮助各个部门高效沟通,互不干扰。来看看这个神奇的工具吧!

MediatR是什么?MediatR是一个轻量级的中介者模式框架,它能帮助我们实现松耦合的组件通信。在大型项目中,各个模块之间经常需要交换信息,如果直接互相调用,代码会变得非常混乱。而有了MediatR,所有的通信都通过它来中转,让代码更清晰、更易维护。

快速入门首先,我们需要通过NuGet安装MediatR:csharp

Install-Package MediatR
Install-Package MediatR.Extensions.Microsoft.DependencyInjection

在Startup.cs中注册MediatR服务:csharp

public void ConfigureServices(IServiceCollection services)

    services.AddMediatR(cfg =>; cfg.RegisterServicesFromAssembly(typeof(Startup).Assembly));


基本用法示例让我们实现一个简单的订单创建功能:csharp

// 1. 创建请求类
public class CreateOrderCommand : IRequest<;int>;

    public string ProductName { get; set; }
    public int Quantity { get; set; }


// 2. 创建处理器
public class CreateOrderCommandHandler : IRequestHandler<;CreateOrderCommand, int>;

    public async Task<;int>; Handle(CreateOrderCommand request, CancellationToken cancellationToken)
    {
        // 模拟订单创建逻辑
        Console.WriteLine($"创建订单:{request.ProductName} x {request.Quantity}");
        return new Random().Next(1000); // 返回订单号
    }


// 3. 在控制器中使用
public class OrderController : ControllerBase

    private readonly IMediator _mediator;

    public OrderController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpPost]
    public async Task<;IActionResult>; CreateOrder([FromBody] CreateOrderCommand command
    {
        var orderId = await _mediator.Send(command);
        return Ok(orderId);
    }


通知(事件)处理MediatR不仅支持请求-响应模式,还支持通知模式:csharp

// 1. 定义通知
public class OrderCreatedNotification : INotification

    public int OrderId { get; set; }


// 2. 创建通知处理器
public class EmailNotificationHandler : INotificationHandler<;OrderCreatedNotification>;

    public async Task Handle(OrderCreatedNotification notification, CancellationToken cancellationToken)
    {
        // 发送邮件通知
        Console.WriteLine($"发送订单 {notification.OrderId} 创建成功邮件");
    }


public class SMSNotificationHandler : INotificationHandler<;OrderCreatedNotification>;

    public async Task Handle(OrderCreatedNotification notification, CancellationToken cancellationToken)
    {
        // 发送短信通知
        Console.WriteLine($"发送订单 {notification.OrderId} 创建成功短信");
    }


小贴士:通知处理器可以有多个,它们会并行执行!

管道行为MediatR还支持类似中间件的管道行为:csharp

public class LoggingBehavior<;TRequest, TResponse>; : IPipelineBehavior<;TRequest, TResponse>;

    private readonly ILogger<;LoggingBehavior<;TRequest, TResponse>;>; _logger;

    public LoggingBehavior(ILogger<;LoggingBehavior<;TRequest, TResponse>;>; logger)
    {
        _logger = logger;
    }

    public async Task<;TResponse>; Handle(TRequest request, RequestHandlerDelegate<;TResponse>; next, CancellationToken cancellationToken)
    {
        _logger.LogInformation($"处理请求 {typeof(TRequest).Name}");
        var response = await next();
        _logger.LogInformation($"完成请求 {typeof(TRequest).Name}");
        return response;
    }


注册管道行为:csharp

services.AddScoped(typeof(IPipelineBehavior<;,>;), typeof(LoggingBehavior<;,>;));

实战小技巧

命名规范:请求类建议以Command或Query结尾,处理器以Handler结尾。

职责单一:每个Handler只处理一种类型的请求,保持代码清晰。

异常处理:可以通过管道行为统一处理异常。

验证:可以使用FluentValidation结合管道行为进行请求验证。

小伙伴们,今天的.NET学习之旅就到这里啦!记得动手敲代码,有问题随时在评论区问羊哥哦。祝大家学习愉快,.NET学习节节高!

xmltodict,XML处理大师的Python利器!

xmltodict:XML处理大师的Python利器!

大家好!今天我要和大家分享一个处理XML数据特别好用的Python库 - xmltodict。作为一名经常需要处理各种数据格式的开发者,我深深体会到XML虽然是一种常见的数据格式,但用Python原生的XML解析方式总觉得不够优雅。xmltodict就像一位魔法师,它能够轻松地将XML转换成我们最熟悉的Python字典格式,让XML处理变得简单直观。让我们一起来探索这个XML处理神器吧!

安装和基本使用

首先,让我们安装xmltodict:

pip install xmltodict

最基本的XML转换:

import xmltodict
import json  # 用于美化输出

def basic_conversion():
    # 简单的XML字符串
    xml_string = '''
   
        张三
        25
        北京
    '''

    
    # 转换XML到字典
    data_dict = xmltodict.parse(xml_string)
    print("转换后的字典:")
    print(json.dumps(data_dict, indent=2, ensure_ascii=False))
    
    # 字典转回XML
    xml_back = xmltodict.unparse(data_dict, pretty=True)
    print("\n转回的XML:")
    print(xml_back)

basic_conversion()

小贴士:xmltodict在处理XML时会保留原始数据的层级结构,但会将所有数据转换为字符串类型。如果需要数值类型,需要手动转换。

复杂XML处理

处理嵌套和列表结构:

def complex_xml():
    # 包含列表和嵌套的XML
    xml_string = '''
   
       
           
                Python入门
                小明
               
                    编程
                    Python
               
           
           
                数据分析实战
                小红
               
                    数据
                    分析
               
           
       
    '''

    
    # 转换并访问数据
    data = xmltodict.parse(xml_string)
    
    # 遍历书籍
    books = data['library']['books']['book']
    print("所有书籍:")
    for book in books:
        print(f"\n书名:{book['title']}")
        print(f"作者:{book['author']}")
        print(f"标签:{', '.join(book['tags']['tag'])}")

complex_xml()

文件操作

读写XML文件:

def file_operations():
    # 写入XML文件
    data = {
        'students': {
            'student': [
                {
                    '@id''1',  # @符号表示属性
                    'name''李明',
                    'grade''90',
                    'subjects': {
                        'subject': ['数学''英语''物理']
                    }
                },
                {
                    '@id''2',
                    'name''王红',
                    'grade''85',
                    'subjects': {
                        'subject': ['语文''历史''地理']
                    }
                }
            ]
        }
    }
    
    # 写入文件
    with open('students.xml''w', encoding='utf-8'as f:
        xml_content = xmltodict.unparse(data, pretty=True)
        f.write(xml_content)
    print("XML文件已写入")
    
    # 读取XML文件
    with open('students.xml', encoding='utf-8'as f:
        content = f.read()
        data_back = xmltodict.parse(content)
    
    # 处理数据
    students = data_back['students']['student']
    print("\n学生信息:")
    for student in students:
        print(f"\nID: {student['@id']}")
        print(f"姓名: {student['name']}")
        print(f"成绩: {student['grade']}")
        print(f"科目: {', '.join(student['subjects']['subject'])}")

file_operations()

特殊情况处理

处理特殊XML结构:

def special_cases():
    # 处理包含CDATA的XML
    xml_with_cdata = '''
   
        的文本]]>
    '''

    
    data = xmltodict.parse(xml_with_cdata)
    print("CDATA内容:", data['message']['content'])
    
    # 处理命名空间
    xml_with_namespace = '''
   
          xmlns:f="http://www.friendfeed.com">
        标题
        内容
   
'''

    
    # 保留命名空间
    data_with_ns = xmltodict.parse(xml_with_namespace)
    print("\n带命名空间的内容:")
    print(json.dumps(data_with_ns, indent=2, ensure_ascii=False))
    
    # 忽略命名空间
    data_without_ns = xmltodict.parse(
        xml_with_namespace,
        process_namespaces=False
    )
    print("\n忽略命名空间的内容:")
    print(json.dumps(data_without_ns, indent=2, ensure_ascii=False))

special_cases()

工具类封装

封装常用的XML处理操作:

class XMLHelper:
    @staticmethod
    def load_xml(file_path):
        """从文件加载XML"""
        try:
            with open(file_path, encoding='utf-8'as f:
                return xmltodict.parse(f.read())
        except Exception as e:
            print(f"加载XML文件失败:{str(e)}")
            returnNone
    
    @staticmethod
    def save_xml(data, file_path):
        """保存字典到XML文件"""
        try:
            with open(file_path, 'w', encoding='utf-8'as f:
                xml_content = xmltodict.unparse(data, pretty=True)
                f.write(xml_content)
            returnTrue
        except Exception as e:
            print(f"保存XML文件失败:{str(e)}")
            returnFalse
    
    @staticmethod
    def extract_values(data, key):
        """递归提取指定键的所有值"""
        values = []
        
        if isinstance(data, dict):
            for k, v in data.items():
                if k == key:
                    values.append(v)
                values.extend(XMLHelper.extract_values(v, key))
        elif isinstance(data, list):
            for item in data:
                values.extend(XMLHelper.extract_values(item, key))
                
        return values

# 使用示例
helper = XMLHelper()
data = {
    'catalog': {
        'book': [
            {'title''Book1''price''29.99'},
            {'title''Book2''price''39.99'}
        ]
    }
}

# 保存XML
helper.save_xml(data, 'catalog.xml')

# 加载XML
loaded_data = helper.load_xml('catalog.xml')

# 提取所有标题
titles = helper.extract_values(loaded_data, 'title')
print("所有书籍标题:", titles)

练习题

创建一个简单的XML配置文件读取器,能够读取和修改配置项。

实现一个XML转CSV的工具,将XML数据转换为表格格式。

开发一个RSS订阅解析器,使用xmltodict处理RSS源。

总结

通过今天的学习,我们掌握了:

xmltodict确实是处理XML的得力助手!它不仅使用简单,还能让我们用最熟悉的字典方式来处理XML数据。记住,在处理XML时要注意数据类型的转换和特殊字符的处理。

希望这篇文章能帮助你更好地使用xmltodict。从简单的XML转换开始练习,逐步尝试更复杂的数据处理。如果遇到问题,记得查看官方文档和示例代码。

让我们继续用xmltodict这个强大工具,让XML处理变得更加简单有趣!

本站内容来自用户投稿,如果侵犯了您的权利,请与我们联系删除。联系邮箱:835971066@qq.com

本文链接:http://news.xiuzhanwang.com/post/2528.html

发表评论

评论列表

还没有评论,快来说点什么吧~

友情链接: