7.7 KiB
7.7 KiB
日志服务使用示例 | Logger Service Usage Examples
示例 1:服务类中使用 | Example 1: Usage in Service Class
旧方式(手动传递字符串)| Old Way (Manual String)
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)
public class PlcService
{
private readonly ILoggerService _logger;
public PlcService(ILoggerService logger)
{
// 自动获取完整类型名,重构安全
// Automatically get full type name, refactoring-safe
_logger = logger?.ForModule<PlcService>() ?? throw new ArgumentNullException(nameof(logger));
}
}
// 日志输出 | Log output:
// [XP.Hardware.Plc.Services.PlcService] 正在初始化 PLC 连接...
示例 2:ViewModel 中使用 | Example 2: Usage in ViewModel
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<RaySourceOperateViewModel>() ?? 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
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<RaySourceFactory>() ?? 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
public class ConfigLoader
{
public static PlcConfig LoadConfig(ILoggerService logger)
{
// 静态方法中也可以使用泛型
// Can also use generics in static methods
var log = logger.ForModule<ConfigLoader>();
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
public class RaySourceService
{
private readonly ILoggerService _logger;
public RaySourceService(ILoggerService logger)
{
_logger = logger?.ForModule<RaySourceService>() ?? 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<ConnectionManager>() ?? throw new ArgumentNullException(nameof(logger));
}
}
}
示例 6:混合使用 | Example 6: Mixed Usage
有时你可能想要自定义模块名以保持简洁:
public class VeryLongNamespaceAndClassName
{
private readonly ILoggerService _logger;
public VeryLongNamespaceAndClassName(ILoggerService logger)
{
// 选项 1:使用完整类型名(详细但冗长)
// Option 1: Use full type name (detailed but verbose)
// _logger = logger?.ForModule<VeryLongNamespaceAndClassName>();
// 输出 | 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<T>() |
需要完整追踪 |
| ViewModel | ForModule<T>() |
需要完整追踪 |
| 工厂类 | ForModule<T>() |
需要完整追踪 |
| 简单工具类 | ForModule("ToolName") |
保持简洁 |
| 临时调试 | ForModule("Debug") |
快速定位 |
| 第三方集成 | ForModule("ThirdParty.XXX") |
明确标识 |
| Scenario | Recommended | Reason |
|---|---|---|
| Service classes | ForModule<T>() |
Need full tracing |
| ViewModels | ForModule<T>() |
Need full tracing |
| Factory classes | ForModule<T>() |
Need full tracing |
| Simple utility classes | ForModule("ToolName") |
Keep concise |
| Temporary debugging | ForModule("Debug") |
Quick location |
| Third-party integration | ForModule("ThirdParty.XXX") |
Clear identification |