编辑
2025-09-30
C#
00

本文将介绍如何使用 C# 和 OpenXml SDK,从 Excel 文件中提取图片和嵌入对象。我们将以一个包含代码示例的完整项目为例,详细介绍实现过程。

准备工作

你需要安装以下 NuGet 包:

  • DocumentFormat.OpenXml

你可以通过 NuGet 安装这些依赖包。在 Visual Studio 的“工具” -> “NuGet 包管理器” -> “包管理器控制台”中运行以下命令:

Bash
Install-Package DocumentFormat.OpenXml

代码结构

本文将从以下几个方面展开:

  1. 打开 Excel 文件
  2. 提取 OLE 嵌入对象
  3. 提取图片
  4. 辅助方法和工具函数

打开 Excel 文件

我们首先需要打开 Excel 文件并遍历其工作表部分,为后续的提取操作做准备。

待读出的excel文件

image.png

编辑
2025-09-30
C#
00

领域驱动设计(DDD, Domain-Driven Design)是一种软件设计方法,旨在通过以领域为中心的方式建模,以应对复杂性并提高软件的灵活性和可维护性。DDD鼓励开发人员与领域专家密切合作,构建出能够反映业务需求的模型。它不仅仅是一个技术方法,更是一种开发哲学。

DDD的核心概念

在DDD中,有一些关键概念是核心组成部分:

  1. 领域(Domain): 系统的业务逻辑部分,定义了业务规则和行为。
  2. 实体(Entity): 有唯一标识的对象。
  3. 值对象(Value Object): 不可变且没有唯一标识的对象。
  4. 领域服务(Domain Service): 操作复杂但不归属于任何实体或值对象的业务逻辑。
  5. 聚合(Aggregate): 由实体和值对象组成的集合,并以根实体(Aggregate Root)为入口。
  6. 仓储(Repository): 用于持久化实体的存储机制。
  7. 工厂(Factory): 用于创建复杂对象和聚合根的对象。

一个简单的示例

为了说明DDD的特点,我们将通过一个简单的库存管理系统的控制台应用程序来展示DDD的应用。此示例包含了领域、实体、值对象、领域服务、聚合、仓储和工厂等概念。

项目结构

一个简单的库存管理

C#
- InventoryManagement - Domain - Entities - Product.cs - ValueObjects - ProductId.cs - Services - InventoryService.cs - Factories - ProductFactory.cs - Repositories - IProductRepository.cs - Infrastructure - Repositories - InMemoryProductRepository.cs - Program.cs
编辑
2025-09-30
C#
00

在项目管理的世界里,甘特图是不可或缺的工具。它不仅能帮助你直观地展示项目进度,还能有效地管理任务和资源。然而,找到一个既强大又易用的甘特图控件并不容易。今天,我们为你推荐一款颠覆性的工具——.NET C# Winforms Gantt Chart 控件,它将彻底改变你的项目管理方式!

先看个样式

image.png

官网

C#
https://github.com/jakesee/ganttchart

为什么选择.NET C# Winforms Gantt Chart 控件?

1. 无需额外依赖,轻松上手

这款控件完全基于.NET Framework,无需任何额外的预先条件。只需下载最新的源代码并在Microsoft Visual Studio 2017中构建库,你就可以立即开始使用。

2. 强大的功能,满足多样需求

.NET C# Winforms Gantt Chart 控件支持多种时间单位(周、天、小时),并且可以自定义其他时间分辨率。它还提供了单任务、分组任务、前置/后置任务、拆分任务和标记资源等功能。此外,每个任务都有完成百分比属性,帮助你更好地跟踪进度。

3. 灵活的用户界面定制

通过各种鼠标事件,你可以直接在甘特图上自定义用户界面体验。默认的鼠标命令可以通过继承来覆盖,满足你的个性化需求。

4. 打印支持,完美呈现

打印功能尊重页面边距、方向和每页的多个页面设置,确保你的甘特图在纸质版上也能完美呈现。

5. 关键路径和浮动时间计算

控件能够自动确定关键路径和浮动时间,帮助你更好地进行项目规划和风险管理。

编辑
2025-09-30
C#
00

在现代软件开发中,依赖注入(Dependency Injection, DI)是实现松耦合、模块化和可测试代码的一个重要实践。C# 提供了优秀的 DI 容器,如ASP.NET Core中自带的Microsoft.Extensions.DependencyInjection,但是有时候我们希望自定义一些功能,比如通过特性(Attributes)实现自动注入。本文将详细介绍如何从零开始实现一个通过特性自动注入的功能。

引言

特性(Attributes)是C#提供的一种用于在运行时通过反射向代码中添加声明性信息的方式。通过结合反射和特性,我们可以实现一种自动依赖注入的功能,这样可以简化DI的配置。

Nuget安装

C#
Microsoft.Extensions.DependencyInjection

创建特性

首先,我们需要创建一个特性,用于标记需要注入的类。

编辑
2025-09-30
C#
00

在C#编程中,高效地排序和比较对象是至关重要的。无论是处理复杂的数据结构,还是简单地对一个项目列表进行排序,IComparer接口都提供了一种灵活而强大的方式来定义自定义的比较逻辑。在这篇文章中,我们将深入探讨IComparer,并展示如何在C#应用程序中有效地实现和使用它。

什么是IComparer?

IComparer是一个定义了比较两个对象的方法的接口。当你需要基于自定义标准对对象进行排序,或者默认的排序行为不够时,它特别有用。

IComparer接口

IComparer接口是System.Collections命名空间的一部分,由一个单一的方法组成。

Compare(object x, object y)

这个方法比较两个对象x和y。它返回:

  • 如果x小于y,则返回负整数。
  • 如果x等于y,则返回零。
  • 如果x大于y,则返回正整数。

实现IComparer

要实现IComparer,你需要创建一个实现Compare方法的类。让我们考虑一个实际的例子,我们有一个书籍的列表,我们想按标题排序,如果标题相同,则按作者排序。

步骤一:定义书籍类

首先,创建一个包含Title和Author属性的Book类。

C#
public class Book { public string Title { get; set; } public string Author { get; set; } public Book(string title, string author) { Title = title; Author = author; } }