4.9 KiB
4.9 KiB
软件开发文档 - 03. DMS.Infrastructure 详细设计
DMS.Infrastructure 层是所有外部技术和服务的具体实现地。它实现了 DMS.Core 定义的接口,为 DMS.Application 层提供数据和功能支持。
1. 目录结构
DMS.Infrastructure/
├── Data/
│ └── SqlSugarDbContext.cs
├── Entities/
│ ├── DbDevice.cs
│ ├── DbMqttServer.cs
│ ├── DbVariable.cs
│ └── ... (所有数据库表对应的实体)
├── Repositories/
│ ├── BaseRepository.cs
│ ├── DeviceRepository.cs
│ └── ... (所有仓储接口的实现)
├── Services/
│ ├── Communication/
│ │ ├── S7CommunicationService.cs
│ │ └── MqttPublishService.cs
│ ├── Processing/
│ │ ├── ChangeDetectionProcessor.cs
│ │ ├── HistoryStorageProcessor.cs
│ │ └── MqttPublishProcessor.cs
│ └── DatabaseInitializerService.cs
└── DMS.Infrastructure.csproj
2. 文件详解
2.1. 数据库实体 (Entities/)
DbDevice.cs
// 文件: DMS.Infrastructure/Entities/DbDevice.cs
using SqlSugar;
namespace DMS.Infrastructure.Entities;
[SugarTable("Devices")]
public class DbDevice
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
public int Protocol { get; set; }
public string IpAddress { get; set; }
public int Port { get; set; }
public bool IsActive { get; set; }
}
... (其他实体 DbVariableTable, DbVariable, DbMqttServer, DbVariableHistory, DbVariableMqttMap 结构类似) ...
2.2. 仓储实现 (Repositories/)
BaseRepository.cs
// 文件: DMS.Infrastructure/Repositories/BaseRepository.cs
// 注意:这里需要一个从领域模型到数据库实体的映射,实际项目中通常使用AutoMapper的ProjectTo或手动映射。
// 为简化示例,此处仅做基础实现。
DeviceRepository.cs
// 文件: DMS.Infrastructure/Repositories/DeviceRepository.cs
using AutoMapper;
using DMS.Core.Interfaces;
using DMS.Core.Models;
using DMS.Infrastructure.Entities;
using SqlSugar;
public class DeviceRepository : IDeviceRepository
{
private readonly ISqlSugarClient _db;
private readonly IMapper _mapper;
public DeviceRepository(ISqlSugarClient db, IMapper mapper) { /* ... */ }
public async Task<List<Device>> GetActiveDevicesWithDetailsAsync()
{
var dbResult = await _db.Queryable<DbDevice>()
.Where(d => d.IsActive)
.ToListAsync();
// 此处需要手动或通过AutoMapper加载关联的变量表和变量
return _mapper.Map<List<Device>>(dbResult);
}
// ... 其他方法的实现
}
2.3. 外部服务 (Services/)
S7CommunicationService.cs
// 文件: DMS.Infrastructure/Services/Communication/S7CommunicationService.cs
using S7.Net;
using System.Collections.Concurrent;
public class S7CommunicationService : IS7CommunicationService
{
private readonly ConcurrentDictionary<int, Plc> _clients = new();
public async Task<object> ReadVariableAsync(Device device, Variable variable)
{
if (!_clients.TryGetValue(device.Id, out var plc))
{
plc = new Plc(CpuType.S71500, device.IpAddress, 0, 1);
await plc.OpenAsync();
_clients[device.Id] = plc;
}
return await plc.ReadAsync(variable.Address);
}
// ... 其他连接、断开等管理方法
}
MqttPublishService.cs
// 文件: DMS.Infrastructure/Services/Communication/MqttPublishService.cs
using MQTTnet;
using MQTTnet.Client;
public class MqttPublishService : IMqttPublishService
{
private readonly IMqttClient _mqttClient;
public MqttPublishService() {
var factory = new MqttFactory();
_mqttClient = factory.CreateMqttClient();
}
public async Task PublishAsync(MqttServer server, string topic, string payload)
{
if (!_mqttClient.IsConnected)
{
var options = new MqttClientOptionsBuilder()
.WithTcpServer(server.BrokerAddress, server.Port)
.WithCredentials(server.Username, server.Password)
.Build();
await _mqttClient.ConnectAsync(options, CancellationToken.None);
}
var message = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)
.Build();
await _mqttClient.PublishAsync(message, CancellationToken.None);
}
}
2.4. 数据处理器 (Services/Processing/)
(此处包含 ChangeDetectionProcessor, HistoryStorageProcessor, MqttPublishProcessor 的完整实现,如之前文档所示,但会更加细化,并注入 ILogger)