.NET开发之.net framework对比.net core

"经典 3 层架构" VS ".net core现代化版本"

先用你熟悉的方式对应一下

  • 以前的 UI层 = 现在的 CustomerManager.WinForms
  • 以前的 Business = 现在拆成了 CustomerManager.Application + CustomerManager.Domain
  • 以前的 DAL = 现在主要是 CustomerManager.Infrastructure

你可以先这样记:

  • WinForms:界面层,负责按钮点击、表单输入、列表显示
  • Application:业务编排层,负责"这个功能怎么走"
  • Domain:核心业务模型层,负责"客户是什么、客户有哪些规则"
  • Infrastructure:数据访问和技术实现层,负责"数据到底存哪、怎么取"

所以它不是推翻你以前的 3 层,而是把以前那个偏大的 Business 又拆细了一点。

和经典 3 层最接近的映射

  • UI层src/CustomerManager.WinForms
  • Business层
    • 偏"业务流程"的部分:src/CustomerManager.Application
    • 偏"业务对象/规则"的部分:src/CustomerManager.Domain
  • DAL层src/CustomerManager.Infrastructure

如果按你过去的习惯看:

  • Application 很像以前的 BLL
  • Infrastructure 很像以前的 DAL
  • Domain 相当于把"实体类、接口、规则"单独抽出来了

为什么要把 Business 再拆成两个 以前很多项目里,Business 会越写越大,里面混着这些东西:

  • 实体类
  • 业务规则
  • 功能流程
  • 调 DAL
  • 工具类

现在一般会拆成两块:

  • Domain

    • 放"最核心、最稳定"的东西
    • 比如 Customer 实体、ICustomerRepository 接口
    • 不关心 WinForms、数据库、日志这些技术细节
  • Application

    • 放"用例流程"
    • 比如"新增客户""修改客户""删除客户"
    • 它调用 Domain 里的接口去做事

这样好处是:

  • 业务模型更稳定
  • UI 和数据库变化时,不容易把核心逻辑搞乱
  • 后面换存储方式也方便

你现在这个项目里,每层到底干什么

  • src/CustomerManager.WinForms

    • 就是窗体层
    • 例如 CustomerListFormCustomerEditForm
    • 只做界面交互,不直接写业务逻辑,不直接访问数据库
  • src/CustomerManager.Application

    • 就是"业务服务层"
    • 例如 CustomerAppService
    • Form 点按钮后,主要调用这里的方法
  • src/CustomerManager.Domain

    • 就是"业务模型层"
    • 例如 CustomerICustomerRepository
    • 定义系统里"客户"是什么,以及仓储接口长什么样
  • src/CustomerManager.Infrastructure

    • 就是"数据实现层"
    • 例如 InMemoryCustomerRepository
    • 现在先用内存模拟数据,后面可以替换成 EF Core + SQLite

如果按"新增客户"流程看,就很清楚了 用户在界面点"新增客户"后,流程大概是:

  • CustomerEditForm 收集输入
  • 调用 ICustomerAppService.CreateAsync(...)
  • CustomerAppService 创建 Customer 实体,并调用 ICustomerRepository
  • InMemoryCustomerRepository 把数据存起来
  • Service 返回结果
  • Form 再刷新列表

也就是:

复制代码
Form -> Service -> Repository

这其实和你以前的:

复制代码
UI -> BLL -> DAL

是同一条路,只是命名更现代,职责更细。

那 DI 是什么,为什么现在到处都在用 以前 WinForms 很常见的写法是:

复制代码
var service = new CustomerService();
var dal = new CustomerDal();

现在更常见的是"不自己 new,而是交给容器创建",这就是 DI。

比如现在可能是这样:

  • Form 需要 ICustomerAppService
  • 容器自动把 CustomerAppService 注入进去
  • CustomerAppService 需要 ICustomerRepository
  • 容器再把 InMemoryCustomerRepository 注入进去

这样做的好处:

  • 各层不直接绑死实现类
  • 后面把内存仓储换成数据库仓储,不用改 Form
  • 更方便测试

你可以把 DI 理解成:

  • 以前:自己手动 new
  • 现在:启动时统一登记,运行时自动给你装配

那 Program.cs 为什么变复杂了 以前 WinForms 的 Program.cs 很简单:

复制代码
Application.Run(new Form1());

现在它变成了应用启动入口,除了开窗体,还负责:

  • 注册 DI
  • 加载配置
  • 初始化日志
  • 创建主窗体

所以 src/CustomerManager.WinForms/Program.cs 现在像一个"总装配点"。

你可以把它理解成:

  • 以前只是"启动窗体"
  • 现在是"先把整个系统零件装好,再启动窗体"

AppSettings.cs 是干什么的 你刚打开的 src/CustomerManager.WinForms/Configuration/AppSettings.cs,本质上是"配置项对应的 C# 类"。

比如配置文件里可能有:

复制代码
{
  "AppSettings": {
    "AppName": "Customer Manager"
  }
}

AppSettings.cs 就是把这段配置映射成对象,代码里就可以类型安全地用,而不是到处写字符串读取配置。

你可以把它理解成:

  • 以前可能写在 app.config / web.config
  • 现在常用 appsettings.json
  • 再配一个 AppSettings 类接它

也就是"配置实体类"。

日志又是怎么回事 以前很多 WinForms 项目会自己写:

  • 文本日志
  • Log4Net
  • 或者干脆不记日志

现在 .NET 统一用了 ILogger<T> 这一套抽象。 好处是:

  • 代码里统一写日志接口
  • 底层想输出到控制台、Debug、文件,都可以后面换

所以它和 DI 一样,也是"先抽象,再注入"。

MVP 你不用现在就紧张 你提的"复杂窗体以后演进到 MVP"是对的,但这里不是说所有窗体都必须马上上 MVP。

你可以先这样理解:

  • 简单窗体:Form + Service
  • 复杂窗体:Form + Presenter + Service

也就是说:

  • 简单页面先按你熟悉的方式写
  • 只是别把业务逻辑直接塞进 Form
  • 当列表页越来越复杂,再把它提炼成 MVP

这是一种"渐进升级",不是一开始就把 WinForms 写成很重的模式。

如果用你熟悉的话来重新描述这个项目 你完全可以先这样理解当前骨架:

  • WinForms = UI 层
  • Application = BLL
  • Infrastructure = DAL
  • Domain = 实体层 + 接口层 + 业务规则层
  • Program.cs = 系统启动装配入口
  • AppSettings.cs = 配置实体类
  • DI = 自动帮你 new 对象并串起来

这么看就不会陌生了。

最重要的一句话 这套结构不是"和你以前完全不一样",而是:

  • 保留你熟悉的 UI -> Business -> DAL 思路
  • 再把 Business 拆得更清楚
  • 再把"对象创建、配置、日志"标准化了

如果你愿意,我下一条可以继续直接按"你熟悉的 3 层思维"帮你画一张这个项目的对照图,比如:

  • 哪个项目相当于以前的 BLL
  • 哪个类相当于以前的 DAL
  • 一个新增客户按钮点击后,代码会怎么流转

我可以专门用"老 WinForms 开发者视角"给你讲一版。

相关推荐
cfm_29143 小时前
JVM垃圾收集算法与收集器深度解析
jvm·测试工具·算法·性能优化
自律懒人5 小时前
AI Agent 工作流编排实战:从单 Agent 到多 Agent,手搭一套能跑通的协作系统
jvm
石一峰6996 小时前
SQLite 与 db_manager 集成关键概念详解
jvm·数据库·sqlite
布朗克1681 天前
34 JVM深入理解
java·jvm
eggrall1 天前
Linux线程:并发编程的双刃剑
jvm
程序员晨曦1 天前
深入浅出JVM内存结构
jvm·面试·职场和发展
cfm_29141 天前
JVM对象创建与内存分配机制深度解析
jvm
wuminyu1 天前
Java锁膨胀机制之偏向锁到轻量级锁源码剖析
java·linux·c语言·jvm·c++
cfm_29141 天前
JVM内存模型深度剖析与性能优化
jvm·性能优化