# 日志服务使用示例 | Logger Service Usage Examples ## 示例 1:服务类中使用 | Example 1: Usage in Service Class ### 旧方式(手动传递字符串)| Old Way (Manual String) ```csharp public class PlcService { private readonly ILoggerService _logger; public PlcService(ILoggerService logger) { // 需要手动输入类名,容易出错 // Need to manually type class name, error-prone _logger = logger?.ForModule("PlcService") ?? throw new ArgumentNullException(nameof(logger)); } } // 日志输出 | Log output: // [PlcService] 正在初始化 PLC 连接... ``` ### 新方式(自动类型推断)| New Way (Auto Type Inference) ```csharp public class PlcService { private readonly ILoggerService _logger; public PlcService(ILoggerService logger) { // 自动获取完整类型名,重构安全 // Automatically get full type name, refactoring-safe _logger = logger?.ForModule() ?? throw new ArgumentNullException(nameof(logger)); } } // 日志输出 | Log output: // [XP.Hardware.Plc.Services.PlcService] 正在初始化 PLC 连接... ``` ## 示例 2:ViewModel 中使用 | Example 2: Usage in ViewModel ```csharp using Prism.Mvvm; using XP.Common.Logging.Interfaces; namespace XP.Hardware.RaySource.ViewModels { public class RaySourceOperateViewModel : BindableBase { private readonly ILoggerService _logger; public RaySourceOperateViewModel(ILoggerService logger) { // 自动使用:XP.Hardware.RaySource.ViewModels.RaySourceOperateViewModel // Automatically uses: XP.Hardware.RaySource.ViewModels.RaySourceOperateViewModel _logger = logger?.ForModule() ?? throw new ArgumentNullException(nameof(logger)); _logger.Info("射线源操作视图模型已初始化 | Ray source operate view model initialized"); } public void StartXRay() { _logger.Info("用户请求启动射线 | User requested to start X-ray"); // ... 业务逻辑 | business logic } } } ``` ## 示例 3:工厂类中使用 | Example 3: Usage in Factory Class ```csharp using XP.Common.Logging.Interfaces; using XP.Hardware.RaySource.Abstractions; namespace XP.Hardware.RaySource.Factories { public class RaySourceFactory : IRaySourceFactory { private readonly ILoggerService _logger; public RaySourceFactory(ILoggerService logger) { // 自动使用:XP.Hardware.RaySource.Factories.RaySourceFactory // Automatically uses: XP.Hardware.RaySource.Factories.RaySourceFactory _logger = logger?.ForModule() ?? throw new ArgumentNullException(nameof(logger)); } public IXRaySource CreateRaySource(string deviceType) { _logger.Info("创建射线源实例:类型={DeviceType} | Creating ray source instance: type={DeviceType}", deviceType); switch (deviceType) { case "Comet225": return new Comet225RaySource(_logger); default: _logger.Error(null, "不支持的设备类型:{DeviceType} | Unsupported device type: {DeviceType}", deviceType); throw new NotSupportedException($"不支持的设备类型:{deviceType}"); } } } } ``` ## 示例 4:静态方法中使用 | Example 4: Usage in Static Methods ```csharp public class ConfigLoader { public static PlcConfig LoadConfig(ILoggerService logger) { // 静态方法中也可以使用泛型 // Can also use generics in static methods var log = logger.ForModule(); log.Info("正在加载 PLC 配置 | Loading PLC configuration"); try { // ... 加载逻辑 | loading logic log.Info("PLC 配置加载成功 | PLC configuration loaded successfully"); return config; } catch (Exception ex) { log.Error(ex, "PLC 配置加载失败 | PLC configuration loading failed"); throw; } } } ``` ## 示例 5:嵌套类中使用 | Example 5: Usage in Nested Classes ```csharp public class RaySourceService { private readonly ILoggerService _logger; public RaySourceService(ILoggerService logger) { _logger = logger?.ForModule() ?? throw new ArgumentNullException(nameof(logger)); } // 嵌套类 | Nested class public class ConnectionManager { private readonly ILoggerService _logger; public ConnectionManager(ILoggerService logger) { // 自动使用:XP.Hardware.RaySource.Services.RaySourceService+ConnectionManager // Automatically uses: XP.Hardware.RaySource.Services.RaySourceService+ConnectionManager _logger = logger?.ForModule() ?? throw new ArgumentNullException(nameof(logger)); } } } ``` ## 示例 6:混合使用 | Example 6: Mixed Usage 有时你可能想要自定义模块名以保持简洁: ```csharp public class VeryLongNamespaceAndClassName { private readonly ILoggerService _logger; public VeryLongNamespaceAndClassName(ILoggerService logger) { // 选项 1:使用完整类型名(详细但冗长) // Option 1: Use full type name (detailed but verbose) // _logger = logger?.ForModule(); // 输出 | Output: [XP.Some.Very.Long.Namespace.VeryLongNamespaceAndClassName] // 选项 2:使用简短自定义名(简洁但需手动维护) // Option 2: Use short custom name (concise but needs manual maintenance) _logger = logger?.ForModule("VeryLong") ?? throw new ArgumentNullException(nameof(logger)); // 输出 | Output: [VeryLong] } } ``` ## 优势对比 | Advantages Comparison ### ForModule() 的优势 | Advantages of ForModule() ✅ **重构安全**:重命名类时自动更新 ✅ **Refactoring-safe**: Automatically updates when renaming class ✅ **无拼写错误**:编译器检查类型 ✅ **No typos**: Compiler checks type ✅ **完整信息**:包含命名空间,便于定位 ✅ **Complete info**: Includes namespace, easy to locate ✅ **智能提示**:IDE 自动补全 ✅ **IntelliSense**: IDE auto-completion ### ForModule(string) 的优势 | Advantages of ForModule(string) ✅ **简洁输出**:日志文件更易读 ✅ **Concise output**: Log files more readable ✅ **自定义名称**:可以使用业务术语 ✅ **Custom names**: Can use business terms ✅ **灵活性**:可以为不同场景使用不同名称 ✅ **Flexibility**: Can use different names for different scenarios ## 推荐使用场景 | Recommended Usage Scenarios | 场景 | 推荐方式 | 原因 | |------|---------|------| | 服务类 | `ForModule()` | 需要完整追踪 | | ViewModel | `ForModule()` | 需要完整追踪 | | 工厂类 | `ForModule()` | 需要完整追踪 | | 简单工具类 | `ForModule("ToolName")` | 保持简洁 | | 临时调试 | `ForModule("Debug")` | 快速定位 | | 第三方集成 | `ForModule("ThirdParty.XXX")` | 明确标识 | | Scenario | Recommended | Reason | |----------|------------|--------| | Service classes | `ForModule()` | Need full tracing | | ViewModels | `ForModule()` | Need full tracing | | Factory classes | `ForModule()` | Need full tracing | | Simple utility classes | `ForModule("ToolName")` | Keep concise | | Temporary debugging | `ForModule("Debug")` | Quick location | | Third-party integration | `ForModule("ThirdParty.XXX")` | Clear identification |