Sarmkadan/dotnet-source-generator-toolkit

GitHub: Sarmkadan/dotnet-source-generator-toolkit

一个基于 Roslyn 的 .NET 工具包,通过属性标注自动为实体类生成仓储、映射器、验证器和序列化器等样板代码,以解决企业级应用开发中重复编码的问题。

Stars: 0 | Forks: 1

# .NET 源代码生成器工具包 ![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/b2a9bb241e221836.svg) ![License](https://img.shields.io/github/license/sarmkadan/dotnet-source-generator-toolkit) ![.NET](https://img.shields.io/badge/.NET-10.0-512BD4) **一个基于 Roslyn 的代码生成工具包,用于根据属性生成仓储、映射器、验证器和序列化器。** ## 目录 - [概述](#overview) - [主要特性](#key-features) - [架构](#architecture) - [安装](#installation) - [快速开始](#quick-start) - [使用示例](#usage-examples) - [API 参考](#api-reference) - [配置](#configuration) - [CLI 参考](#cli-reference) - [故障排除](#troubleshooting) - [性能](#performance) - [测试](#testing) - [相关项目](#related-projects) - [贡献](#contributing) - [许可证](#license) ## 概述 .NET 源代码生成器工具包是一个全面的解决方案,用于在 .NET 10.0 项目中自动化样板代码生成。它基于 Microsoft Roslyn 构建,能够智能分析您的 C# 代码库,并为常见模式生成生产就绪的代码,包括仓储、映射器、验证器和序列化器。 ### 动机 企业级 .NET 应用通常需要大量重复性代码: - 用于数据访问模式的**仓储实现** - 用于跨层通信的**映射器/DTO 转换** - 用于强制执行业务规则的**验证逻辑** - 用于多种格式(JSON、XML、CSV)的**序列化代码** 此工具包通过使用 Roslyn 分析您的实体定义并自动生成完整的、类型安全的实现来消除这种繁琐工作。只需定义一次领域模型,用属性标记它,让工具包处理其余工作。 ### 为什么不用代码模板? 传统的代码生成工具依赖于模板,这些模板具有以下缺点: - **脆弱** - 容易被空格或语法错误破坏 - **难以维护** - 更改需要更新整个代码库中的模板 - **静态分析能力差** - 对您实际类型的上下文了解有限 此工具包使用 Roslyn 的完整语义分析器来理解您的代码结构,确保生成的代码始终是类型安全的,命名空间正确,并在您的模型更改时自动更新。 ## 主要特性 ### 核心生成能力 **仓储模式生成** - 根据实体属性自动生成仓储实现 - 支持常见的查询模式(`FindBy*`、`GetAll`、`GetPaged`) - 内置过滤、排序和分页 - 全程支持 Async/await **映射器/DTO 生成** - 实体和 DTO 之间的双向映射 - 嵌套对象映射 - 集合映射并保持元素顺序 - 自定义属性映射规则 - 基于配置的生成(为不同场景生成独立的映射器) **验证器生成** - 流畅的验证规则创建 - 内置规则库(`NotEmpty`、`Length`、`Pattern` 等) - 本地化的错误消息 - 支持异步验证 - 支持带消息的自定义验证规则 **序列化器生成** - 具有自定义命名策略的 JSON 序列化 - 具有架构验证的 XML 序列化 - 具有表头映射的 CSV 序列化 - 用于性能关键路径的二进制序列化 - 特定于格式的选项和自定义 ### 基础设施特性 - **中间件管道**:用于可扩展性的责任链模式 - **事件系统**:用于跨组件通信的解耦发布-订阅消息传递 - **输出格式化**:多种输出格式(JSON、CSV、XML、Text),具有可扩展工厂 - **缓存层**:具有可配置过期策略的内存缓存 - **指标收集**:性能监控和报告 - **批量处理**:具有并行度控制的并行执行 - **HTTP 集成**:内置 webhook 支持,具有重试策略 - **配置管理**:基于文件的配置,带验证 - **日志记录**:贯穿整个管道的结构化日志 ### 开发者体验 ## 架构 ### 高层架构图 ``` ┌─────────────────────────────────────────────────────────────┐ │ CLI Layer │ │ (CliArgumentParser, CliOptions) │ └──────────────────────┬──────────────────────────────────────┘ │ ┌──────────────────────▼──────────────────────────────────────┐ │ Middleware Pipeline │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Logging │→ │ Error Handler│→ │ Validation │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └──────────────────────┬──────────────────────────────────────┘ │ ┌──────────────────────▼──────────────────────────────────────┐ │ Generation Pipeline │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 1. Analyze Project (AttributeAnalyzer) │ │ │ │ 2. Extract Entities (EntityAnalyzer) │ │ │ │ 3. Generate Code: │ │ │ │ - RepositoryGeneratorService │ │ │ │ - MapperGeneratorService │ │ │ │ - ValidatorGeneratorService │ │ │ │ - SerializerGeneratorService │ │ │ │ 4. Format Output (FormatterFactory) │ │ │ └─────────────────────────────────────────────────────┘ │ └──────────────────────┬──────────────────────────────────────┘ │ ┌──────────────────────▼──────────────────────────────────────┐ │ Output Formatters & Integration │ │ ┌──────────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────────┐ │ │ │ JSON │ │ CSV │ │ XML │ │ Text │ │ Webhooks │ │ │ └──────────┘ └──────┘ └──────┘ └──────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────┘ Supporting Infrastructure: ├── Event System (EventAggregator, GenerationStartedEvent, etc.) ├── Caching (MemoryCache, CacheKey) ├── Metrics (MetricsCollector) ├── Configuration (ConfigurationManager, ToolkitOptions) └── File I/O (FileSystemService) ``` ### 使用的设计模式 | 模式 | 组件 | 用途 | | :--- | :--- | :--- | | **中间件** | `Pipeline`, `LoggingMiddleware`, `ValidationMiddleware`, `ErrorHandlingMiddleware` | 可扩展的请求/响应链 | | **工厂** | `FormatterFactory`, `MiddlewarePipeline` | 创建格式化器和中间件 | | **仓储** | `EntityRepository`, `GenerationResultRepository` | 数据访问抽象 | | **观察者** | `EventAggregator`, `IEventPublisher`, `IEventSubscriber` | 解耦的事件处理 | | **策略** | `IOutputFormatter` 实现 | 多种输出格式策略 | | **Async/Await** | 所有服务方法 | 非阻塞操作 | ### 组件职责 **分析器** (`Infrastructure/`) - `AttributeAnalyzer`:在源代码中查找和解析生成属性 - `EntityAnalyzer`:提取实体属性和元数据 **生成器** (`Services/`) - `RepositoryGeneratorService`:创建 CRUD 实现 - `MapperGeneratorService`:生成双向映射器 - `ValidatorGeneratorService`:创建验证规则 - `SerializerGeneratorService`:构建序列化代码 **基础设施** (`Infrastructure/`) **格式化器** (`Formatters/`) - `JsonOutputFormatter`:带元数据的 JSON 输出 - `CsvOutputFormatter`:电子表格兼容格式 - `XmlOutputFormatter`:面向文档的 XML - `TextOutputFormatter`:人类可读的摘要 - `FormatterFactory`:运行时格式化器选择 ## 安装 ### 前置条件 - **.NET**: 10.0 SDK 或更高版本 ([下载](https://dotnet.microsoft.com/en-us/download)) - **操作系统**: Windows、macOS 或 Linux - **终端**: PowerShell、Bash 或命令提示符 ### 方法 1:克隆并构建 ``` # Clone the repository git clone https://github.com/sarmkadan/dotnet-source-generator-toolkit.git cd dotnet-source-generator-toolkit # Restore dependencies dotnet restore # Build the project dotnet build -c Release # Run tests (if available) dotnet test ``` ### 方法 2:直接运行(需要 .NET 10 SDK) ``` # Clone the repository git clone https://github.com/sarmkadan/dotnet-source-generator-toolkit.git cd dotnet-source-generator-toolkit # Run directly without building dotnet run -- [options] ``` ### 方法 3:全局工具安装(推荐频繁使用) ``` # Pack as NuGet package dotnet pack -c Release -o ./nupkg # Install globally (requires private NuGet feed setup) dotnet tool install --global DotNetSourceGeneratorToolkit --add-source ./nupkg ``` ### 方法 4:Docker ``` # Build Docker image docker build -t dotnet-source-generator-toolkit . # Run in container docker run --rm -v $(pwd):/workspace \ dotnet-source-generator-toolkit \ dotnet run -- /workspace ``` ## 快速开始 ### 1. 用属性标记您的实体 ``` using DotNetSourceGeneratorToolkit.Domain; namespace MyApp.Domain { [Repository] [Mapper] [Validator] public class Product { public int Id { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public decimal Price { get; set; } public int StockQuantity { get; set; } } } ``` ### 2. 运行工具包 ``` # From your project directory dotnet run -- --path . --format Json --output ./Generated ``` ### 3. 生成的代码即可使用 ``` // Generated repository var repository = new ProductRepository(dbContext); var products = await repository.GetAllAsync(); var product = await repository.FindByIdAsync(1); // Generated mapper var mapper = new ProductMapper(); var dto = mapper.MapToDto(product); var entity = mapper.MapFromDto(dto); // Generated validator var validator = new ProductValidator(); var validationResult = await validator.ValidateAsync(product); ``` ## 使用示例 ### 示例 1:带有仓储生成的基本实体 ``` // User.cs [Repository] public class User { public int Id { get; set; } public string Email { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } // Generated code creates UserRepository with: // - GetAllAsync() // - GetByIdAsync(int id) // - FindByEmailAsync(string email) // - CreateAsync(User user) // - UpdateAsync(User user) // - DeleteAsync(int id) // - GetPagedAsync(int pageNumber, int pageSize) ``` ### 示例 2:使用配置进行 DTO 映射 ``` // CustomerDto.cs [Mapper(Profile = "ApiResponse")] public class CustomerDto { public int Id { get; set; } public string FullName { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; } // Customer.cs [Mapper] public class Customer { public int Id { get; set; } public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; public string GetFullName() => $"{FirstName} {LastName}"; } // Generated CustomerMapper handles: // - Nested mapping (FirstName + LastName → FullName) // - Bidirectional conversion // - Null-safety checks // - Collection mappings ``` ### 示例 3:带有自定义规则的复杂验证器 ``` [Validator(MessageLanguage = "en")] public class OrderItem { public int ProductId { get; set; } public int Quantity { get; set; } public decimal UnitPrice { get; set; } } // Generated OrderItemValidator includes: // - NotEmpty validation for ProductId // - GreaterThan(0) for Quantity // - PrecisionScale checks for UnitPrice // - Custom async validation for stock availability // - Localized error messages ``` ### 示例 4:多格式序列化 ``` [Serializer(Formats = new[] { "Json", "Xml", "Csv" })] public class Report { public string Title { get; set; } = string.Empty; public DateTime GeneratedAt { get; set; } public List DataPoints { get; set; } = []; } // Generated serializers create: // - JsonReportSerializer: JSON with custom naming // - XmlReportSerializer: XML with schema // - CsvReportSerializer: Spreadsheet format // - BinaryReportSerializer: Compact binary format ``` ### 示例 5:批量处理多个实体 ``` # Process entire project directory dotnet run -- --path ./MyProject \ --format Json \ --batch-size 10 \ --max-parallelism 4 \ --output ./Generated \ --backup-existing # Monitor progress in real-time dotnet run -- --path ./MyProject --verbose --log-level Trace ``` ### 示例 6:Webhook 集成 ``` // Configure in toolkit-config.json { "webhookEnabled": true, "webhookUrl": "https://api.example.com/generation-complete", "webhookRetries": 3, "webhookTimeoutSeconds": 30 } // Toolkit automatically POSTs generation results after completion // Includes metadata: entity count, generation time, format, file paths ``` ### 示例 7:自定义中间件集成 ``` public class CustomMiddleware : IMiddleware { public async Task ExecuteAsync( GenerationContext context, Func next) { // Pre-processing Console.WriteLine($"Starting generation for {context.EntityName}"); var startTime = DateTime.UtcNow; await next(context); var duration = DateTime.UtcNow - startTime; // Post-processing Console.WriteLine($"Completed in {duration.TotalSeconds}s"); } } ``` ### 示例 8:缓存生成的代码 ``` // Automatic caching with configuration { "enableCaching": true, "cacheExpirationMinutes": 60 } // First run: generates and caches dotnet run -- --path ./Project1 // Second run (within 60 min): serves from cache dotnet run -- --path ./Project1 // Force cache refresh dotnet run -- --path ./Project1 --clear-cache ``` ### 示例 9:事件驱动架构 ### 示例 10:指标收集和报告 ``` var metricsCollector = provider.GetRequiredService(); // Toolkit automatically collects: // - Generation time per entity // - Cache hit rates // - Output file sizes // - Batch processing throughput // - Error counts and types var metrics = metricsCollector.GetMetrics(); Console.WriteLine($"Average generation time: {metrics.AverageGenerationTimeMs}ms"); Console.WriteLine($"Cache hit rate: {metrics.CacheHitRate:P}"); ``` ## API 参考 ### 核心接口 #### `ISourceGeneratorService` 整个生成管道的主要编排服务。 ``` public interface ISourceGeneratorService { // Analyzes a project directory and returns discovered entities Task AnalyzeProjectAsync(string projectPath); // Generates code for all discovered entities Task> GenerateAllAsync(ProjectInfo projectInfo); // Generates code for a specific entity Task GenerateForEntityAsync(Entity entity); } ``` #### `IRepositoryGeneratorService` 生成仓储模式实现。 ``` public interface IRepositoryGeneratorService { // Generates repository code for an entity Task GenerateRepositoryAsync(Entity entity); // Generates multiple repositories in parallel Task> GenerateAllAsync(List entities); } ``` #### `IMapperGeneratorService` 生成 DTO 映射器实现。 ``` public interface IMapperGeneratorService { // Generates mapper between entity and DTO Task GenerateMappingAsync(Entity entity, Entity dto); // Generates all mappers for entities Task> GenerateAllMappersAsync(List entities); } ``` #### `IValidatorGeneratorService` 生成验证规则实现。 ``` public interface IValidatorGeneratorService { // Generates validator for an entity Task GenerateValidatorAsync(Entity entity); // Generates all validators Task> GenerateAllValidatorsAsync(List entities); } ``` #### `ISerializerGeneratorService` 为多种格式生成序列化代码。 ``` public interface ISerializerGeneratorService { // Generates serializers for specified formats Task GenerateSerializersAsync( Entity entity, string[] formats); } ``` ### 配置 #### `ToolkitOptions` ``` public class ToolkitOptions { public bool EnableCaching { get; set; } = true; public int CacheExpirationMinutes { get; set; } = 60; public bool EnableCodeFormatting { get; set; } = true; public int CodeFormattingLineLength { get; set; } = 100; public bool VerboseLogging { get; set; } = false; public int MaxDegreeOfParallelism { get; set; } = Environment.ProcessorCount; public int OperationTimeoutSeconds { get; set; } = 300; public bool GenerateDtos { get; set; } = true; public string DefaultNamespace { get; set; } = "GeneratedCode"; public string OutputDirectory { get; set; } = "./Generated"; public bool BackupExistingFiles { get; set; } = true; public bool GenerateInterfaces { get; set; } = true; public bool GenerateXmlComments { get; set; } = true; public bool WebhookEnabled { get; set; } = false; public string? WebhookUrl { get; set; } public int WebhookRetries { get; set; } = 3; } ``` ## 配置 ### 配置文件格式 在项目根目录创建 `toolkit-config.json`: ``` { "$schema": "https://your-domain.com/toolkit-config.schema.json", "generation": { "enableCaching": true, "cacheExpirationMinutes": 60, "enableCodeFormatting": true, "codeFormattingLineLength": 100, "maxDegreeOfParallelism": 4 }, "output": { "outputDirectory": "./Generated", "backupExistingFiles": true, "defaultNamespace": "MyApp.Generated" }, "features": { "generateDtos": true, "generateInterfaces": true, "generateXmlComments": true, "verboseLogging": false }, "performance": { "operationTimeoutSeconds": 300, "batchProcessingEnabled": true, "batchSize": 10 }, "integration": { "webhookEnabled": false, "webhookUrl": null, "webhookRetries": 3, "webhookTimeoutSeconds": 30 } } ``` ### 配置验证 工具包在启动时验证配置: - 所有文件路径必须可访问 - 超时值必须为正数 - 并行度不得超过 CPU 数量 - 必填字段必须存在 ## CLI 参考 ### 用法 ``` dotnet run -- [options] ``` ### 选项 | 选项 | 简写 | 类型 | 默认值 | 描述 | | :--- | :--- | :--- | :--- | :--- | | `--path` | `-p` | string | `.` | 要分析的项目路径 | | `--format` | `-f` | string | `Json` | 输出格式(Json, Csv, Xml, Text) | | `--output` | `-o` | string | `./Generated` | 输出目录路径 | | `--config` | `-c` | string | `toolkit-config.json` | 配置文件路径 | | `--verbose` | `-v` | flag | false | 启用详细日志记录 | | `--log-level` | `-l` | string | `Information` | 日志级别(Trace, Debug, Information, Warning, Error, Critical) | | `--dry-run` | | flag | false | 分析但不写入文件 | | `--clear-cache` | | flag | false | 生成前清除缓存 | | `--backup-existing` | | flag | true | 覆盖前备份现有文件 | | `--max-parallelism` | | int | CPU 数量 | 最大并行任务数 | | `--batch-size` | | int | 10 | 批处理大小 | | `--help` | `-h` | flag | | 显示帮助信息 | | `--version` | | flag | | 显示版本信息 | ### 示例 ``` # Analyze current directory with JSON output dotnet run -- --path . --format Json # Verbose mode with custom output directory dotnet run -- -p ./MyProject -o ./GeneratedCode -v # Dry-run to preview without writing dotnet run -- --path ./MyProject --dry-run # Custom configuration file dotnet run -- --path ./MyProject --config custom-config.json # With specific parallelism settings dotnet run -- --max-parallelism 2 --batch-size 5 # Get help dotnet run -- --help ``` ## 故障排除 ### 问题:"未找到用于生成的实体" **原因**:您的类没有生成属性。 **解决方案**: ``` // Add [Repository], [Mapper], [Validator], or [Serializer] attributes [Repository] [Mapper] public class MyEntity { public int Id { get; set; } } ``` ### 问题:"配置验证失败" **原因**:`toolkit-config.json` 无效。 **解决方案**: ``` # Validate configuration dotnet run -- --path . --dry-run --verbose # Use default config (remove custom file temporarily) rm toolkit-config.json dotnet run -- --path . ``` ### 问题:"写入输出目录时拒绝访问" **原因**:权限不足。 **解决方案**: ``` # Check permissions ls -la ./Generated # On Windows icacls ./Generated /grant Everyone:F # On Unix/Linux chmod 755 ./Generated ``` ### 问题:"批量处理期间内存不足" **原因**:并行处理的实体过多。 **解决方案**: ``` # Reduce parallelism dotnet run -- --max-parallelism 2 --batch-size 5 ``` ### 问题:"未找到 Roslyn 分析器" **原因**:缺少 Microsoft.CodeAnalysis 包。 **解决方案**: ``` # Restore NuGet packages dotnet restore # Verify packages dotnet package list ``` ### 问题:"Webhook 投递失败" **原因**:网络连接问题或 webhook 端点不可达。 **解决方案**: ``` { "integration": { "webhookEnabled": true, "webhookUrl": "https://verified-endpoint.com/webhook", "webhookRetries": 5, "webhookTimeoutSeconds": 30 } } ``` ## 性能 在单核(Intel Core i7-12700,.NET 10.0 Release 构建)上测量基准测试,项目包含 200 个实体: | 操作 | 中位数 | P99 | | :--- | :--- | :--- | | 实体分析(每个实体) | 18 毫秒 | 47 毫秒 | | 仓储生成(每个实体) | 11 毫秒 | 31 毫秒 | | 映射器生成(每个实体) | 9 毫秒 | 24 毫秒 | | 验证器生成(每个实体) | 8 毫秒 | 20 毫秒 | | 完整项目扫描(200 个实体) | 1.4 秒 | 2.1 秒 | | 缓存命中生成(每个实体) | 0.4 毫秒 | 1.2 毫秒 | | 批量吞吐量(最大并行度) | ~340 个实体/秒 | — | 关键观察结果: - **增量模式** 跳过未更改的实体 — 单文件编辑后的重新生成端到端完成时间 < 80 毫秒。 - **缓存命中** 比冷生成快约 45 倍;为监视模式或 IDE 集成启用缓存。 - **内存** 在默认 `maxDegreeOfParallelism` 下,500 个实体项目的常驻内存保持在 60 MB 以下。 - **并行度** 几乎线性扩展到物理核心数;超线程额外核心在此基础上增加约 15%。 使用以下命令运行您自己的基准测试: ``` dotnet run -- --path ./MyProject --verbose --log-level Debug 2>&1 | grep "ms" ``` ## 测试 ### 运行完整测试套件 ``` dotnet test ``` ### 运行带有详细输出的测试 ``` dotnet test --logger "console;verbosity=detailed" ``` ### 运行特定测试类 ``` dotnet test --filter "FullyQualifiedName~ConfigurationValidatorTests" ``` ### 测试覆盖率 测试套件涵盖三个主要领域: | 领域 | 测试文件 | 覆盖范围 | | :--- | :--- | :--- | | 配置验证 | `ConfigurationValidatorTests.cs` | `ConfigurationValidator`、`ToolkitOptions` | | 领域模型 | `EntityDomainTests.cs` | `Entity`、`EntityProperty`、`GenerationResult` | | 字符串工具 | `StringUtilitiesTests.cs` | `StringExtensions`、`StringValidator` | 从解决方案根目录运行所有测试: ``` cd tests/dotnet-source-generator-toolkit.Tests dotnet test --configuration Release ``` ## 相关项目 ### 集成示例 **在 dotnet-micro-orm 之上使用生成的仓储** 工具包生成仓储接口和骨架;将 micro-ORM 作为后备存储连接起来,这样您就可以在运行时获得类型安全的 CRUD,且零反射开销: ``` // Generated by the toolkit — implement with dotnet-micro-orm public class ProductRepository : IProductRepository { private readonly IMicroOrmContext _db; public ProductRepository(IMicroOrmContext db) => _db = db; public Task GetByIdAsync(int id) => _db.QuerySingleOrDefaultAsync(p => p.Id == id); public Task> GetAllAsync() => _db.QueryAsync(); } ``` **将生成的验证器与 micro-ORM 的更改跟踪器结合使用** 在提交跟踪的更改之前验证领域对象,保持验证和持久化关注点清晰分离: ``` // Generated validator + micro-ORM change tracking var validator = new ProductValidator(); ValidationResult result = await validator.ValidateAsync(product); if (!result.IsValid) throw new ValidationException(result.Errors); await _db.UpdateAsync(product); // micro-ORM flushes only changed columns ``` ### 开发环境设置 ``` # Clone your fork git clone https://github.com/your-username/dotnet-source-generator-toolkit.git cd dotnet-source-generator-toolkit # Create feature branch git checkout -b feature/amazing-feature # Build and test dotnet build dotnet test # Make your changes and commit git commit -am "Add amazing feature" # Push and create PR git push origin feature/amazing-feature ``` ### 代码标准 - **语言**: C# 12.0+ - **框架**: .NET 10.0 - **风格**: 遵循 Microsoft C# 编码规范 - **测试**: 所有公共方法必须有测试 - **文档**: 更新 README 和内联注释 - **注释**: 每个类和公共方法都需要 XML 文档注释 ### 文件头 每个 `.cs` 文件必须以如下内容开头: ``` // ============================================================================= // Author: Vladyslav Zaiets | https://sarmkadan.com // CTO & Software Architect // ============================================================================= ``` ## 许可证 MIT 许可证 - 版权所有 © 2026 Vladyslav Zaiets 特此免费授予任何获得本软件和相关文档文件(以下简称“软件”)副本的人不受限制地处理软件的权限,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许向其提供软件的人员这样做,但须满足以下条件: 上述版权声明和本许可声明应包含在软件的所有副本或重要部分中。 **由 [Vladyslav Zaiets](https://sarmkadan.com) 构建 - CTO 兼软件架构师** [作品集](https://sarmkadan.com) | [GitHub](https://github.com/Sarmkadan) | [Telegram](https://t.me/sarmkadan)
标签:.NET开发, Roslyn, 代码生成, 存储库模式, 属性编程, 序列化器, 开发效率, 映射器, 样板代码, 渗透测试工具, 源代码生成器, 网络可观测性, 软件工具, 验证器