构建企业级.NET应用:CSLA .NET框架实战指南

构建企业级.NET应用:CSLA .NET框架实战指南

【免费下载链接】csla A home for your business logic in any .NET application. 【免费下载链接】csla 项目地址: https://gitcode.com/gh_mirrors/cs/csla

为什么需要CSLA .NET?

在现代软件开发中,我们拥有丰富的UI框架(Blazor、MAUI、ASP.NET MVC)和数据访问技术(Entity Framework、Dapper),但业务逻辑往往成为被忽视的中间层。CSLA .NET(Component-based Scalable Logical Architecture)填补了这一空白,为业务逻辑提供标准化家园,确保代码跨平台一致性、可维护性和安全性。

读完本文你将掌握:

  • 理解CSLA .NET的核心架构与五层设计模式
  • 构建可验证、可追踪的业务实体(Business Object)
  • 实现完整的CRUD操作与数据门户(Data Portal)交互
  • 应用业务规则引擎进行验证与授权
  • 在实际项目中集成CSLA组件的最佳实践

CSLA .NET核心架构

CSLA .NET基于五层架构设计,抽象了不同关注点的分离:

mermaid

核心组件说明

组件作用基类示例
业务实体封装业务逻辑和数据BusinessBase<T>, ReadOnlyBase<T>
业务列表管理实体集合BusinessListBase<T,C>, ReadOnlyListBase<T,C>
数据门户处理数据访问与远程调用DataPortal<T>
规则引擎验证与授权逻辑ValidationRule, AuthorizationRule
状态管理跟踪对象状态变化IsDirty, IsValid, IsNew

快速上手:构建第一个业务对象

以下通过创建PersonEdit实体演示CSLA核心功能,完整实现CRUD操作与业务规则验证。

步骤1:环境准备

  1. 创建解决方案结构(以.NET 8为例):

    dotnet new sln -n CslaDemo
    dotnet new classlib -n BusinessLayer && dotnet sln add BusinessLayer
    dotnet new classlib -n DataAccessLayer && dotnet sln add DataAccessLayer
    dotnet new console -n ClientApp && dotnet sln add ClientApp
    
  2. 添加CSLA依赖

    # 业务层添加CSLA核心包
    cd BusinessLayer && dotnet add package Csla --version 8.0.0
    # 客户端项目引用业务层
    cd ../ClientApp && dotnet add reference ../BusinessLayer
    

步骤2:实现数据传输对象(DTO)

DataAccessLayer项目中定义DTO,隔离业务层与数据存储:

// DataAccessLayer/PersonDto.cs
namespace DataAccessLayer;

public class PersonDto
{
    public int Id { get; set; }
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
}

步骤3:创建业务实体

业务实体继承BusinessBase<T>,封装属性、规则和数据操作:

// BusinessLayer/PersonEdit.cs
using Csla;
using DataAccessLayer;
using System.ComponentModel.DataAnnotations;

namespace BusinessLayer;

[Serializable]
public class PersonEdit : BusinessBase<PersonEdit>
{
    #region 属性定义
    // 声明属性元数据(支持数据绑定和状态跟踪)
    public static readonly PropertyInfo<int> IdProperty = 
        RegisterProperty<int>(c => c.Id);
    public int Id
    {
        get => GetProperty(IdProperty);
        private set => LoadProperty(IdProperty, value);
    }

    public static readonly PropertyInfo<string> FirstNameProperty = 
        RegisterProperty<string>(c => c.FirstName);
    [Required(ErrorMessage = "名字不能为空")]  // 数据注解规则
    public string FirstName
    {
        get => GetProperty(FirstNameProperty);
        set => SetProperty(FirstNameProperty, value);
    }

    public static readonly PropertyInfo<string> LastNameProperty = 
        RegisterProperty<string>(c => c.LastName);
    [Required(ErrorMessage = "姓氏不能为空")]
    public string LastName
    {
        get => GetProperty(LastNameProperty);
        set => SetProperty(LastNameProperty, value);
    }
    #endregion

    #region 数据门户方法(CRUD操作)
    // 创建新对象
    protected override void DataPortal_Create()
    {
        var dal = new PersonDal();
        var dto = dal.Create();
        using (BypassPropertyChecks)  // 临时绕过属性检查
        {
            Id = dto.Id;
            FirstName = dto.FirstName;
            LastName = dto.LastName;
        }
        BusinessRules.CheckRules();  // 触发初始规则检查
    }

    // 获取对象(按ID)
    private void DataPortal_Fetch(int id)
    {
        var dal = new PersonDal();
        var dto = dal.GetPerson(id);
        using (BypassPropertyChecks)
        {
            Id = dto.Id;
            FirstName = dto.FirstName;
            LastName = dto.LastName;
        }
    }

    // 插入新对象
    protected override void DataPortal_Insert()
    {
        var dal = new PersonDal();
        using (BypassPropertyChecks)
        {
            var dto = new PersonDto
            {
                FirstName = FirstName,
                LastName = LastName
            };
            Id = dal.InsertPerson(dto);  // 获取数据库生成的ID
        }
    }

    // 更新对象
    protected override void DataPortal_Update()
    {
        var dal = new PersonDal();
        using (BypassPropertyChecks)
        {
            var dto = new PersonDto
            {
                Id = Id,
                FirstName = FirstName,
                LastName = LastName
            };
            dal.UpdatePerson(dto);
        }
    }

    // 删除对象
    private void DataPortal_Delete(int id)
    {
        var dal = new PersonDal();
        dal.DeletePerson(id);
    }
    #endregion
}

步骤4:实现数据访问层(DAL)

数据访问层隔离业务逻辑与数据源,此处使用内存集合模拟数据库:

// DataAccessLayer/PersonDal.cs
using System.Collections.Generic;
using System.Linq;

namespace DataAccessLayer;

public class PersonDal
{
    private static readonly List<PersonDto> _dataStore = new();

    public PersonDto Create() => new() { Id = -1 };

    public PersonDto GetPerson(int id)
    {
        var entity = _dataStore.FirstOrDefault(e => e.Id == id);
        if (entity == null) throw new KeyNotFoundException("记录不存在");
        return entity;
    }

    public int InsertPerson(PersonDto data)
    {
        data.Id = _dataStore.Any() ? _dataStore.Max(e => e.Id) + 1 : 1;
        _dataStore.Add(data);
        return data.Id;
    }

    public void UpdatePerson(PersonDto data)
    {
        var entity = GetPerson(data.Id);
        entity.FirstName = data.FirstName;
        entity.LastName = data.LastName;
    }

    public void DeletePerson(int id) => _dataStore.Remove(GetPerson(id));
}

步骤5:客户端交互示例

控制台应用演示如何使用数据门户操作业务对象:

// ClientApp/Program.cs
using BusinessLayer;
using Csla;

// 创建新对象
var person = await DataPortal.CreateAsync<PersonEdit>();
Console.Write("输入名字: ");
person.FirstName = Console.ReadLine();
Console.Write("输入姓氏: ");
person.LastName = Console.ReadLine();

// 保存对象(自动判断Insert/Update)
if (person.IsSavable)  // 检查业务规则是否通过
{
    person = await person.SaveAsync();
    Console.WriteLine($"保存成功!ID: {person.Id}");
}
else
{
    Console.WriteLine("保存失败:");
    foreach (var rule in person.BrokenRulesCollection)
        Console.WriteLine($"- {rule.Description}");
}

// 查询并更新
var updatedPerson = await DataPortal.FetchAsync<PersonEdit>(person.Id);
updatedPerson.FirstName = "Updated";
await updatedPerson.SaveAsync();

// 删除对象
await DataPortal.DeleteAsync<PersonEdit>(person.Id);

业务规则引擎深度应用

CSLA规则引擎支持验证规则授权规则计算规则,以下是高级用法示例:

自定义验证规则

// 确保姓氏不为"测试"
public static void AddLastNameRule()
{
    BusinessRules.AddRule(new LastNameRule(LastNameProperty));
}

public class LastNameRule : ValidationRule
{
    public LastNameRule(IPropertyInfo prop) : base(prop) { }

    protected override void Execute(IRuleContext context)
    {
        var lastName = (string)context.InputPropertyValues[PrimaryProperty];
        if (lastName == "测试")
            context.Results.Add(new RuleResult(
                PrimaryProperty, "姓氏不能为'测试'"));
    }
}

异步授权规则

// 仅允许管理员修改
protected override void AddAuthorizationRules()
{
    AuthorizationRules.AllowWrite(LastNameProperty, "Admin");
    // 异步规则示例
    AuthorizationRules.AddRule(
        new AsyncAuthorizationRule(FirstNameProperty), 
        AuthorizationActions.WriteProperty);
}

高级特性与最佳实践

1. 状态管理与跟踪

CSLA自动管理对象状态,关键属性包括:

  • IsNew: 对象是否为新创建(未保存到数据库)
  • IsDirty: 对象是否被修改
  • IsValid: 业务规则是否全部通过
  • IsDeleted: 对象标记为删除
if (person.IsDirty && !person.IsNew)
    Console.WriteLine("对象已修改但未保存");

2. 数据门户高级配置

通过配置文件指定数据门户模式(本地/远程):

<!-- appsettings.json -->
{
  "Csla": {
    "DataPortal": {
      "DefaultProxy": "Csla.DataPortalClient.HttpProxy, Csla",
      "ServerUrl": "https://api.example.com/dataportal"
    }
  }
}

3. 跨平台支持

CSLA业务对象可在以下平台无缝运行:

mermaid

项目实战与性能优化

分层架构改进

实际项目中建议引入依赖注入解耦DAL:

// 使用DI注入DAL
protected override async Task DataPortal_FetchAsync(int id)
{
    var dal = ApplicationContext.GetRequiredService<IPersonDal>();
    var dto = await dal.GetPersonAsync(id);
    // 加载数据...
}

性能优化策略

  1. 对象缓存:使用[Cacheable]特性缓存只读对象
  2. 批量操作:使用CommandBase实现批量处理
  3. 延迟加载:通过Child_DataPortal_Fetch延迟加载子对象
  4. 数据压缩:配置二进制序列化压缩传输数据

总结与进阶学习

CSLA .NET为业务逻辑提供了标准化、可扩展的实现框架,核心优势包括:

  • 关注点分离:清晰划分业务逻辑与数据访问
  • 跨平台一致性:一套业务逻辑运行于所有.NET平台
  • 内置安全性:完善的授权与状态管理
  • 减少样板代码:自动化状态跟踪与数据绑定

进阶资源

  • 官方文档:深入理解数据门户与规则引擎
  • 示例项目Samples/ProjectTracker完整企业级应用
  • 性能调优:使用DataPortalInstrumentation监控性能

通过CSLA .NET,开发者可以将精力集中在业务逻辑本身,而非基础设施代码,构建真正面向业务的.NET应用。

【免费下载链接】csla A home for your business logic in any .NET application. 【免费下载链接】csla 项目地址: https://gitcode.com/gh_mirrors/cs/csla

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值