当前位置: 首页 > news >正文

.NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoMapper

目录

  • .NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoPapper
  • 技术栈简述
  • 项目地址:
  • 功能展示
  • 项目结构
  • 项目引用
  • 1. 新建模型
  • 2. Data层,依赖EF Core,实现数据库增删改查
  • 3. Bussiness层,实现具体的业务逻辑
  • 4. Service层,业务逻辑封装
  • 5. UI层,用户界面
        • 初始化应用程序的服务和组件
      • 主要组件
      • **IHost**主机构建器
        • 配置:通过`AddConfiguration`方法加载`appsettings.json`和环境变量。
        • 注册对象映射
        • 数据库配置
        • 注册应用程序服务
        • 注册视图模型
        • 注册视图
        • 定义AutoMapper映射规则
        • 应用程序启动与关闭
      • 示例
      • UI+ViewModelM界面交互处理
  • 参考

.NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoPapper

该应用程序旨在高效地管理日常工作中所需的AI Prompt,支持新增、编辑、删除、快速复制以及查询等功能。然而,这些功能本身并不是本文讨论的重点;更关注的是背后的技术实现与架构设计思路。功能灵感来自ChatHub - GPT-4o, Claude 3.5, Gemini 1.5 side by side

技术栈简述

  • MVVM设计模式 将应用程序分为三个核心组件:模型(Model)、视图(View)和视图模型(ViewModel)。这种分离关注点的方法提高了应用程序的可维护性和可测试性。
  • EFCore :一个轻量级的、可扩展的ORM(对象关系映射)框架,用于.NET平台。它允许使用C#代码来处理数据库操作,而不是直接编写SQL语句。
  • Code First模式:EFCore支持Code First开发模式,开发者可以直接通过C#类定义来创建数据库模型,然后EFCore会自动生成数据库架构。
  • IOC :一种设计原则,它倒置了传统程序设计中的控制流,使得高层模块不依赖于低层模块,两者都依赖于抽象。
  • DI :实现IOC的一种方式,它通过外部注入依赖来实现模块间的解耦。
  • AutoMapper:是一个对象到对象的映射库,它可以帮助开发者自动转换不同类型的对象,例如将数据库实体(Model)映射到视图模型(ViewModel)。

总体来讲,EFCore简化了数据库操作,而IOC和DI则提高了应用程序的可维护性和可测试性,AutoMapper的加入进一步减少了对象映射的复杂性。使用这些技术栈的组合,使得AI Prompt管理应用的开发更加高效、灵活和可靠。

项目地址:

https://github.com/Nita121388/NitasDemo/tree/main/08WPFArctitectureDemo

功能展示

软件启动后,会展示一个列表,其中包含了所有的AI Prompt(AI Prompt)。用户可以通过以下操作来管理这些Prompt:

  1. 查看所有Prompt:软件启动时,用户将看到一个包含所有AIPrompt的列表,方便快速浏览。
  2. 新增Prompt:用户可以通过点击“新增”按钮来添加新的AI Prompt。点击后,会弹出一个编辑界面,用户可以在这里输入标题和内容,完成新Prompt的创建。
  3. 编辑Prompt:在Prompt列表中,用户可以通过点击“编辑”按钮来修改现有的AIPrompt。编辑界面会加载当前Prompt的内容,用户可以对其进行修改。
  4. 删除Prompt:用户可以通过点击“删除”按钮来移除不再需要的AIPrompt。
  5. 使用Prompt:用户可以通过点击“使用”按钮来将选中的AI Prompt复制到系统剪贴板,用户就可以将Prompt粘贴到任何需要的AI对话系统中,以便快速输入或引用。
  6. 导出Prompt:用户可以通过点击“导出”按钮来保存当前所有的AI Prompt到一个Json文件中。这个操作允许用户将Prompt列表导出为JSON文件,方便备份或在其他设备上导入。
  7. 导入Prompt:用户可以通过点击“导入”按钮来从文件中加载AI Prompt。点击后,会弹出一个文件选择对话框,用户可以选择包含Prompt信息的文件进行导入。导入成功后,软件会将文件中的Prompt添加到现有的Prompt列表中。
    在这里插入图片描述

项目结构

应用分层架构通过将应用程序划分为UI层、服务层、业务逻辑层、数据访问层和领域模型层,实现了关注点分离。每个层级都有明确的职责,UI层负责用户界面,服务层提供业务操作接口,业务逻辑层处理具体的业务需求,数据访问层处理数据库交互,而领域模型层则定义了业务实体。

WFArchitectureDemo                                                         │                                                                            ├───────►UI                                                                  │         │                                                                  │         ├─────►Common                                                      │         │        Helper                                                    │         │        HostBuilders               //主机构建器(HostBuilder)    配置应用程序的各种设置│         ├─────►Converters                                                  │         │        PercentageConverter.cs                                       │         ├─────►ViewModels                                                  │         ├─────►Views                                                       │         ├─────►App.xaml                                                    │         │      App.xaml.cs                  //依赖注入与配置管理                                 │         ├─────►appsettings.json             //数据库设置                               │         └─────►MainWindow.xaml              //启动界面                                                                                                          │                                                                            ├────────►Service                                                            │         │                                                                  │         ├─────►IServices                    //服务接口                              │         │        IPromptService.cs                                         │         ├─────►Services                     //服务实现                                │         │        PromptService.cs                                          │         └─────►Result.cs                                                                                                                              │                                                                            ├────────►Business                                                           │         │                                                                  │         ├────►IManager                      //业务逻辑接口                              │         │      IPromptManager.cs                                           │         │                                                                  │         ├────►Manager                       //具体的业务逻辑                               │         │      PromptManager.cs                                            │         │                                                                  │         └────►DTO                           //数据传输对象                               │                PromptDTO.cs                                                │                PromptUsageDTO.cs                                           │                                                                            ├────────►Data                                //负责与数据库的直接交互,包括CRUD操作                              │         │                                                                  │         ├────►RepositoryFactory                                            │         │      RepositoryFactory.cs                                        │         │                                                                  │         ├────►IRepository                   //仓储模式、CURD接口  │         │      IRepository.cs│         │      IPromptRepository.cs                                        │         │      IPromptUsageRepository.cs                                  │         │                                                                  │         ├────►Repository                    //仓储模式、CURD实现                            │         │      PromptRepository.cs                                         │         │      PromptUsageRepository.cs                                   │         │                                                                  │         ├────►DatabaseContexts              //EF Core的数据库上下文                               │         │      DbContextFactory.cs                                         │         │      PromptDbContext.cs                                          │         │                                                                  │         └────►Migrations                    //数据迁移文件,管理数据库变化                               │                                                                            └────────►Domainn                             //领域模型                               │                                                                  └────►Models                                                       Prompt.cs                                                   PromptUsage.cs                                              

项目引用

  • CommunityToolkit.Mvvm
  • Microsoft.Xaml.Behaviors.Wpf
  • AutoMapper
  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.DependencyInjection
  • Microsoft.Extensions.Hosting
  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Sqlite
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.Design

以下为该项目一步一步一层层的实现大致过程和概述。

1. 新建模型

public class Prompt
{public long ID { get; set; }public string Title { get; set; }public string Content { get; set; }public bool IsDelete { get; set; }public DateTime CreateDateTime { get; set; }public DateTime UpdateDateTime { get; set; }public ICollection<PromptUsage> PromptUsages { get; set; } = new List<PromptUsage>();
}public class PromptUsage
{public long ID { get; set; }public long PromptID { get; set; }public DateTime CreateDateTime { get; set; }public Prompt Prompt { get; set; }
}

2. Data层,依赖EF Core,实现数据库增删改查

该层引用:

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Sqlite
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.Design
  1. 定义仓储接口IRepository
    public interface IRepository<T>
    {T Add(T entity);void Delete(long id);void Update(T entity);List<T> Get();List<T> Select(string filterSql,string orderBySql);T Get(long id);List<T> GetByForeignKey(long id);
    }
    
  2. IPromptRepository和IPromptUsageRepository都继承自IRepository 接口,在由PromptRepository和PromptUsageRepository
  3. PromptRepository和PromptUsageRepository依赖DbContextFactory提供的数据库上下文,具体实现增删改查
  4. PromptDbContext是构建数据访问层的核心,继承DbContext,使用 EF Core 来定义数据库上下文、配置实体和它们之间的关系。
     public class PromptDbContext : DbContext{public DbSet<Prompt> Prompts { get; set; }public DbSet<PromptUsage> PromptUsages { get; set; }public PromptDbContext(DbContextOptions options) : base(options){ } //设计时不能包含此行内容 protected override void OnModelCreating(ModelBuilder modelBuilder){// 配置 Prompt 实体modelBuilder.Entity<Prompt>(entity =>{entity.HasKey(e => e.ID);entity.HasMany(e => e.PromptUsages).WithOne(u => u.Prompt).HasForeignKey(u => u.PromptID);});// 配置 PromptUsage 实体modelBuilder.Entity<PromptUsage>(entity =>{entity.HasKey(e => e.ID);});}}
    
  5. Code First模式,生成迁移文件,创建数据库

    💡

    1. Microsoft.EntityFrameworkCore.Tools是一个包含了用于创建、更新和管理数据库迁移的命令行工具的程序包。这些工具允许开发者在不直接修改数据库架构的情况下,通过代码来跟踪和更新数据库的变化。这些迁移可以应用于不同的数据库环境,从而帮助实现数据库的持续集成和持续部署。
    2. Microsoft.EntityFrameworkCore.Design包则主要用于在设计时为EF Core提供支持和功能,包括生成代码和模型等。虽然它本身不直接提供迁移功能,但它是迁移功能所依赖的一个重要组件。
      在Vistual Studio →工具→NuGet包管理器→程序包管理器控制台,执行以下命令:
      在这里插入图片描述
    PM> Add-Migration Init
    Build started...
    Build succeeded.
    To undo this action, use Remove-Migration.
    PM> update-database
    Build started...
    Build succeeded.
    Applying migration '20241108031752_Init'.
    Done.
    PM> 
    
    然后可以看到项目中新增了文件夹Migrations,其包含20241114045010_init.cs和PromptDbContextModelSnapshot
  • 20241114045010_init.cs:包含了一个迁移类,它定义了数据库架构的变化。这个类包含了UpDown方法,分别用于应用迁移和撤销迁移。
  • PromptDbContextModelSnapshot:它包含了当前数据库上下文的模型快照。这个快照用于在添加新的迁移时比较模型的变化,确保迁移的准确性。

3. Bussiness层,实现具体的业务逻辑

Bussiness层调用Data层实现具体的业务逻辑,要依旧这层依赖倒置原则(Dependency Inversion Principle, DIP)——高层模块不应该依赖于低层模块,二者都应该依赖于其抽象;抽象不应该依赖于细节,细节应该依赖于抽象。IManager中是对外提供的接口,Manager中是具体的实现。

4. Service层,业务逻辑封装

Service层调用Bussiness层 可以进一步封装和抽象业务逻辑,使其更加模块化和可重用。

5. UI层,用户界面

初始化应用程序的服务和组件

App.xaml.cs开始,这是WPF应用程序的入口点。创建了一个继承自ApplicationApp类,并在其中初始化应用程序的服务和组件,处理启动和退出事件,并确保数据库的迁移和主窗口的显示。

主要组件

  1. IServiceProvider:提供对应用程序服务的访问。
  2. IHost:.NET Core的主机构建器,用于配置和启动应用程序。

IHost主机构建器

定义一个CreateHostBuilder方法,它使用Host.CreateDefaultBuilder来设置主机构建器,并通过一系列静态类来扩展IHostBuilder,来简化主机构建器的配置,以便在应用程序启动时注册所需的服务。

 public static IHostBuilder CreateHostBuilder(string[] args = null){return Host.CreateDefaultBuilder(args).AddConfiguration().AddAutoMapper().AddDbContext().AddServices().AddViewModels().AddViews();}

通过模块化配置,将不同的功能(如数据库访问、业务逻辑、视图模型等)分离到不同的类中,从而提高代码的可读性和可维护性。添加了以下组件:

配置:通过AddConfiguration方法加载appsettings.json和环境变量。
 public static IHostBuilder AddConfiguration(this IHostBuilder host){host.ConfigureAppConfiguration(c =>{c.AddJsonFile("appsettings.json");c.AddEnvironmentVariables();});return host;}
注册对象映射

在代码中涉及将DTO对象转为ViewModel,此处采用AutoMapper来实现便捷的映射

 public static IHostBuilder AddAutoMapper(this IHostBuilder host){host.ConfigureServices((context, services) =>{services.AddAutoMapper(typeof(App));});return host;}
数据库配置

通过AddDbContext方法配置Entity Framework Core,数据库上下文

public static IHostBuilder AddDbContext(this IHostBuilder host)
{host.ConfigureServices((context, services) =>{string connectionString = context.Configuration.GetConnectionString("sqlite");Action<DbContextOptionsBuilder> configureDbContext = o => o.UseSqlite(connectionString);// 注册 DbContextservices.AddDbContext<PromptDbContext>(configureDbContext);services.AddSingleton<DbContextFactory>(sp => new DbContextFactory(configureDbContext));services.AddSingleton<RepositoryFactory>(sp => new RepositoryFactory(configureDbContext));});return host;
}
注册应用程序服务
public static IHostBuilder AddServices(this IHostBuilder host)
{host.ConfigureServices(services =>{// 注册 IPromptManager 和 IPromptServiceservices.AddSingleton<IPromptManager, PromptManager>(sp =>{var repositoryFactory = sp.GetRequiredService<RepositoryFactory>();return new PromptManager(repositoryFactory);});services.AddSingleton<IPromptService, PromptService>(sp =>{var promptManager = sp.GetRequiredService<IPromptManager>();return new PromptService(promptManager);});});return host;
}

使用

 private IPromptService _promptService;private IMapper _mapper;public PromptsViewModel(){_promptService = App.Current.Services.GetRequiredService<IPromptService>();_mapper = App.Current.Services.GetRequiredService<IMapper>();}
注册视图模型
 public static IHostBuilder AddViewModels(this IHostBuilder host){host.ConfigureServices(services =>{services.AddTransient<PromptsViewModel>();});return host;}

使用:

 public MainWindow(){InitializeComponent(); ViewModel = App.Current.Services.GetRequiredService<PromptsViewModel>();ViewModel.Refresh();DataContext = ViewModel;}
注册视图
public static IHostBuilder AddViews(this IHostBuilder host)
{host.ConfigureServices(services =>{services.AddSingleton<MainWindow>();});return host;
}

使用

 Window window = _host.Services.GetRequiredService<MainWindow>();window.Show();
定义AutoMapper映射规则

AutoMapper用于简化对象之间的映射。创建了一个MappingProfile类来定义映射规则。

public class MappingProfile : Profile
{public MappingProfile(){// PromptUsageViewModel => PromptUsageDTOCreateMap<PromptUsageViewModel, PromptUsageDTO>();//PromptUsageDTO => PromptUsageViewModelCreateMap<PromptUsageDTO, PromptUsageViewModel>();// PromptViewModel => PromptDTOCreateMap<PromptViewModel, PromptDTO>().ForMember(dest => dest.Usages, opt => opt.MapFrom(src => src.Usages.ToList()));CreateMap<PromptDTO, PromptViewModel>().ForMember(dest => dest.Usages,opt => opt.MapFrom(src => src.Usages.ToList()));}
}

使用示例

var promptViewModel = _mapper.Map<PromptViewModel>(promptDTO);
应用程序启动与关闭

OnStartup方法中,启动主机(这会触发所有服务的注册和初始化),然后执行数据库迁移,最后显示主窗口。在OnExit方法中,停止并释放主机资源。

/// <summary>
/// 在应用程序启动时执行的操作。
/// </summary>
protected override void OnStartup(StartupEventArgs e)
{base.OnStartup(e); // 启动主机,这将触发所有服务的注册和初始化。_host?.Start();// 获取DbContextFactory服务的实例,用于创建数据库上下文。DbContextFactory contextFactory = _host.Services.GetRequiredService<DbContextFactory>();// 使用DbContextFactory创建数据库上下文实例,并应用所有未应用的迁移。// 这确保了数据库结构是最新的,以匹配应用程序的数据模型。using (var context = contextFactory.CreateDbContext()){context.Database.Migrate();}// 获取MainWindow服务的实例Window window = _host.Services.GetRequiredService<MainWindow>();// 显示主窗口window.Show();
}

protected override async void OnExit(ExitEventArgs e)
{// 等待_host对象的StopAsync方法完成,这个方法应该是停止一些后台服务的操作。await _host.StopAsync();// 释放_host对象所占用的资源。_host.Dispose();// 调用基类的OnExit方法,确保基类的退出逻辑也能被执行。base.OnExit(e);
}

示例

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{public new static App Current => (App)Application.Current;public IServiceProvider Services { get; }private readonly IHost _host;public App(){_host = CreateHostBuilder().Build();Services = _host.Services;}public static IHostBuilder CreateHostBuilder(string[] args = null){return Host.CreateDefaultBuilder(args).AddConfiguration().AddAutoMapper().AddDbContext().AddServices().AddViewModels().AddViews();}protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);_host?.Start();DbContextFactory contextFactory = _host.Services.GetRequiredService<DbContextFactory>();using (var context = contextFactory.CreateDbContext()){context.Database.Migrate();}Window window = _host.Services.GetRequiredService<MainWindow>();window.Show();}protected override async void OnExit(ExitEventArgs e){await _host.StopAsync();_host.Dispose();base.OnExit(e);}
}

UI+ViewModelM界面交互处理

在用户界面层(UI Layer)中,采用了CommunityToolkit.Mvvm库来实现MVVM(Model-View-ViewModel)设计模式。通过MVVM模式,实现了命令绑定和数据绑定,使得用户界面与业务逻辑之间的交互更加清晰和高效。因为此处不是本文重点所以不详细介绍啦。

参考

  1. 实体框架文档中心 | Microsoft Learn
  2. https://www.youtube.com/playlist?list=PLA8ZIAm2I03jSfo18F7Y65XusYzDusYu5
  3. Construction — AutoMapper documentation
  4. SingletonSean/SimpleTrader:全栈 WPF MVVM 交易应用程序。 — SingletonSean/SimpleTrader: A full stack WPF MVVM trading application.
  5. xtenzQ/WPF-MVVM-EFC-Example: 📲 MVVM (WPF) application built with EFCore, Abstract Factory pattern and dependency injection (Microsoft Unity)

平平无奇的代码小白,如有问题请多指正!

相关文章:

.NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoMapper

目录 .NET桌面应用架构Demo与实战|WPFMVVMEFCoreIOCDICode FirstAutoPapper技术栈简述项目地址&#xff1a;功能展示项目结构项目引用1. 新建模型2. Data层&#xff0c;依赖EF Core&#xff0c;实现数据库增删改查3. Bussiness层&#xff0c;实现具体的业务逻辑4. Service层&am…...

el-table根据指定字段合并行和列+根据屏幕高度实时设置el-table的高度

文章目录 html代码script代码arraySpanMethod.js代码 html代码 <template><div class"rightBar"><cl-table ref"tableData"border :span-method"arraySpanMethod" :data"tableData" :columns"columns":max-…...

图像处理 之 凸包和最小外围轮廓生成

“ 最小包围轮廓之美” 一起来欣赏图形之美~ 1.原始图片 男人牵着机器狗 2.轮廓提取 轮廓提取 3.最小包围轮廓 最小包围轮廓 4.凸包 凸包 5.凸包和最小包围轮廓的合照 凸包和最小包围轮廓的合照 上述图片中凸包、最小外围轮廓效果为作者实现算法生成。 图形几何之美系列&#…...

萤石设备视频接入平台EasyCVR私有化视频平台视频监控系统的需求及不同场景摄像机的选择

在现代社会&#xff0c;随着安全意识的提高和技术的进步&#xff0c;安防监控视频系统已成为保障人们生活和财产安全的重要工具。EasyCVR安防监控视频系统&#xff0c;以其先进的网络传输技术和强大的功能&#xff0c;为各种规模的项目提供了一个高效、可靠的监控解决方案。以下…...

网络安全之接入控制

身份鉴别 ​ 定义:验证主题真实身份与其所声称的身份是否符合的过程&#xff0c;主体可以是用户、进程、主机。同时也可实现防重放&#xff0c;防假冒。 ​ 分类:单向鉴别、双向鉴别、三向鉴别。 ​ 主题身份标识信息:密钥、用户名和口令、证书和私钥 Internet接入控制过程 …...

Sqlite: Java使用、sqlite-devel

这里写目录标题 一、简介二、使用1. Java项目中&#xff08;1&#xff09;引入驱动&#xff08;2&#xff09;工具类&#xff08;3&#xff09;调用举例 2. sqlite-devel in linuxsqlite-devel使用 三、更多应用1. 数据类型2. 如何存储日期和时间3. 备份 一、简介 非常轻量级&…...

京东面试题目分享

话不多说&#xff0c;直接上问题 一面&#xff08;视频面&#xff09; 1小时30分钟 1、类加载机制概念、加载步骤、双亲委托机制、全盘委托机制、类加载器种类及继承关系 2、如何实现让类加载器去加载网络上的资源文件&#xff1f;怎么自定义类加载器&#xff1f;自定义的加…...

STM32 使用 STM32CubeMX HAL库实现低功耗模式

STM32 使用 HAL 库的低功耗模式测试使用 ...... 矜辰所致前言 上次画了一个 STM32L010F4 最小系统的板子&#xff0c;也做了一些基本测试&#xff0c;但是最重要的低功耗一直拖到现在&#xff0c;以前在使用 STM32L151 的时候用标准库做过低功耗的项目&#xff0c;现在都使…...

技术美术百人计划 | 《2.1 色彩空间介绍》笔记

总览 一、色彩发送器 色彩认知&#xff1a; 光源是出生点&#xff0c;光源发射出光线&#xff0c;光线通过直射反射折射等路径最终进入人眼。 但人眼接收到光线后&#xff0c;人眼的细胞产生了一系列化学反应。 由此把产生的信号传入大脑&#xff0c;最终大脑对颜色产生了认…...

如何在 Ubuntu 上安装 Mosquitto MQTT 代理

如何在 Ubuntu 上安装 Mosquitto MQTT 代理 Mosquitto 是一个开源的消息代理&#xff0c;实现了消息队列遥测传输 (MQTT) 协议。在 Ubuntu 22.04 上安装 MQTT 代理&#xff0c;您可以利用 MQTT 轻量级的 TCP/IP 消息平台&#xff0c;该平台专为资源有限的物联网 (IoT) 设备设计…...

css使用弹性盒,让每个子元素平均等分父元素的4/1大小

css使用弹性盒&#xff0c;让每个子元素平均等分父元素的4/1大小 原本&#xff1a; ul {padding: 0;width: 100%;background-color: rgb(74, 80, 62);display: flex;justify-content: space-between;flex-wrap: wrap;li {/* 每个占4/1 */overflow: hidden;background-color: r…...

设计模式的学习思路

学习设计模式确实需要一定的时间和实践&#xff0c;尤其是对于刚入门的人来说&#xff0c;因为一开始可能会感到有些混淆&#xff0c;尤其是当多个设计模式看起来有相似之处时。本博客是博主学习设计模式的思路历程&#xff0c;大家可以一起学习进步。设计模式学习-CSDN博客 1…...

stereopy 查看 data.tl 的可用属性

为了查看 data.tl 的可用属性,您可以使用 Python 的内置函数,例如 dir() 或 vars(),具体操作如下: 1. 列出 data.tl 的所有属性 使用 dir() 来查看所有可用的属性和方法: # 列出所有属性 print(dir(data.tl))这将返回一个列表,包含所有可用的方法、属性和内部字段。 2.…...

【2024APMCM亚太杯A题】详细解题思路

A题 复杂场景下的水下图像增强研究 解题思路问题一图像统计分析技术一、检测 偏色 的技术二、检测 弱光 的技术三、检测 模糊 的技术 聚类算法 问题二问题三问题四完整论文与代码 解题思路 问题一 问题 1&#xff1a;请使用类似上文提到的图像统计分析技术&#xff0c;对附件 …...

用 React18 构建Tic-Tac-Toe(井字棋)游戏

下面是一个完整的 Tic-Tac-Toe&#xff08;井字棋&#xff09;游戏的实现&#xff0c;用 React 构建。包括核心逻辑和组件分离&#xff0c;支持两人对战。 1. 初始化 React 项目&#xff1a; npx create-react-app tic-tac-toe cd tic-tac-toe2.文件结构 src/ ├── App.js…...

数据结构及算法--排序篇

在 C 语言中&#xff0c;可以通过嵌套循环和比较运算符来实现常见的排序算法&#xff0c;比如冒泡排序、选择排序或插入排序 目录 基础算法&#xff1a; 1.冒泡排序&#xff08;Bubble Sort&#xff09; 2.选择排序&#xff08;Selection Sort&#xff09; 3.插入排序&…...

泷羽sec学习打卡-网络七层杀伤链1

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 关于蓝队基础的那些事儿-Base1 基本的企业网络架构是怎样的呢&#xff1f;高层管理IT管理影子IT中央技术…...

【QT】绘图

个人主页~ 绘图 一、绘图1、基础内容2、绘制形状&#xff08;1&#xff09;线段&#xff08;2&#xff09;矩形&#xff08;3&#xff09;圆形&#xff08;4&#xff09;文本&#xff08;5&#xff09;画笔&#xff08;6&#xff09;画刷 3、绘制图片&#xff08;1&#xff09;…...

vue3+elementui-plus el-dialog全局配置点击空白处不关闭弹窗

在与main.ts同级下的plugins文件夹&#xff08;如果没有&#xff0c;新建一个&#xff09;下建一个element.js文件&#xff08;名字随便取&#xff09; element.js文件内容如下&#xff1a; import ElementPlus from element-plus export default (app) > {console.log(app…...

Markdown语法说明

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...

推荐一款专业电脑护眼工具:CareUEyes Pro

CareUEyes Pro是一款非常好用的专业电脑护眼工具&#xff0c;软件小巧&#xff0c;界面简单&#xff0c;它可以自动过滤电脑屏幕的蓝光&#xff0c;让屏幕显示更加的不伤眼&#xff0c;更加舒适&#xff0c;有效保护你的眼睛&#xff0c;可以自定义调节屏幕的色调&#xff0c;从…...

对subprocess启动的子进程使用VSCode python debugger

文章目录 1 情况概要&#xff08;和文件结构&#xff09;2 具体设置和启动步骤2.1 具体配置Step 1 针对attach debugger到子进程Step 2 针对子进程的暂停(可选) Step 3 判断哪个进程id是需要的子进程 2.2 启动步骤和过程 3 其他问题解决3.13.2 ptrace: Operation not permitted…...

Django启用国际化支持(2)—实现界面内切换语言:activate()

文章目录 ⭐注意⭐1. 配置项目全局设置&#xff1a;启用国际化2. 编写视图函数3. 配置路由4. 界面演示5、扩展自动识别并切换到当前语言设置语言并保存到Session设置语言并保存到 Cookie ⭐注意⭐ 以下操作依赖于 Django 项目的国际化支持。如果你不清楚如何启用国际化功能&am…...

基于单片机的多功能跑步机控制系统

本设计基于单片机的一种多功能跑步机控制系统。该系统以STM32单片机为主控制器&#xff0c;由七个电路模块组成&#xff0c;分别是&#xff1a;单片机模块、电机控制模块、心率检测模块、音乐播放模块、液晶显示模块、语音控制模块、电源模块。其中&#xff0c;单片机模块是整个…...

VSCode 如何选中包含某个字母的所有行

文章目录 写在前面一、需求描述二、解决方法参考链接 写在前面 自己的测试环境&#xff1a;VSCode 一、需求描述 由于需要处理文件&#xff0c;需求是删除文件中包含某个字母的所有行。 二、解决方法 在 Visual Studio Code (VSCode) 中&#xff0c;如果你想选中所有包含某…...

CSRF保护--laravel进阶篇

laravel对csrf非常重视&#xff0c;专门针对csrf作出了很多的保护。如果您是刚刚接触laravel的路由不久&#xff0c;那么您可能对于web.php路由文件的post请求很疑惑&#xff0c;因为get请求很顺利&#xff0c;而post请求则可能会遭遇失败。其中一个失败的原因是由于laravel的c…...

计算机网络-理论部分(二):应用层

网络应用体系结构 Client-Server客户-服务器体系结构&#xff1a;如Web&#xff0c;FTP&#xff0c;Telnet等Peer-Peer&#xff1a;点对点P2P结构&#xff0c;如BitTorrent 应用层协议定义了&#xff1a; 交换的报文类型&#xff0c;请求or响应报文类型的语法字段的含义如何…...

k8s1.31版本最新版本集群使用容器镜像仓库Harbor

虚拟机 rocky9.4 linux master node01 node02 已部署k8s集群版本 1.31 方法 一 使用容器部署harbor (1) wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo yum -y install docker-ce systemctl enable docker…...

QT中使用json格式存取矩阵数据

在 Qt 中,可以通过 QJsonDocument 和 QJsonArray 方便地存取 JSON 格式的矩阵数据。以下是存储和读取矩阵数据的完整实现示例。 1. 矩阵存储为 JSON 将矩阵(QVector<QVector<double>> 或其他二维数组)存储为 JSON 文件。 实现代码 #include <QJsonArray&g…...

k8s 集群安装

安装rockylinux https://www.jianshu.com/p/a5fe20318b8e https://www.cnblogs.com/haoee/p/18290506 配置VirtualBox双网卡 https://www.cnblogs.com/ShineLeBlog/p/17580311.html https://zhuanlan.zhihu.com/p/341328334 https://blog.csdn.net/qq_36544785/article/deta…...

想自学做网站/爱站网长尾关键词挖掘

字符串内置方法的使用 设置字符串&#xff1a;st‘hello kitty’ 1、统计元素个数 Print&#xff08;st.count(‘l’)&#xff09; #结果为2 2、首字母大写 Print(st.capitalize()) #结果为Hello kitty 3、居中 Print(st.center(20,’#’)) #结果为…...

为什么百度地图嵌入网站不显示/深圳网站推广公司

php语言只所以在web开发领域占据半壁江山&#xff0c;是因为它有太多的生态&#xff0c;成熟的框架体系&#xff0c;广泛的开源cms系统。建设网站的时候&#xff0c;都想提升开发效率&#xff0c;效率就是成本&#xff0c;如果你用原生php语言开发一个项目&#xff0c;既要设计…...

网软志成个人商城网站/百度官方网站

WPF Behavior 行为 前言 行为是一类事物的共同特征&#xff0c;在WPF中通过行为可以封装一些通用的界面功能&#xff0c;从而实现代码重用来提高开发效率。因此他是一个非常好用的工具。 引入dll文件 找到System.Windows.Interactivity.dll文件。 然后将其引入到项目中。 …...

wordpress nova主题/关键词工具有哪些

用paramiko写堡垒机 paramiko paramiko模块&#xff0c;基于SSH用于连接远程服务器并执行相关操作。 基本用法 SSHClient 基于用户名密码连接&#xff1a; 基础用法: import paramiko# 创建SSH对象 ssh paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_mi…...

如何设计网络/邵阳seo优化

DNS服务配置及拓展一.DNS服务的信息说明:A ##正向记录PTR ##反向,ip到域名host -l example.com ##查看域中的所有主机dig -t soa example.com ##辅助dns软件包: bind DNS主配置目录:/var/named/chroot/DNS主配置文件:/etc/nam…...

国际贸易 独立网站建设/爱站网seo培训

Part1:写在最前MySQL5.7.15是截止至本文撰写当日&#xff0c;mysql官网的最新社区版&#xff0c;mysql5.7的多项功能优化可以用激动人心来形容&#xff0c;嫌安装麻烦&#xff1f;没关系&#xff0c;跟着本文&#xff0c;带你快速搞定MySQL5.7.15数据库安装部署。Part2:仅仅安装…...