Files

168 lines
6.6 KiB
C#

using System;
using System.IO;
using XP.Common.Localization;
using XP.Common.Logging.Interfaces;
using XP.Common.PdfViewer.Exceptions;
using XP.Common.PdfViewer.Interfaces;
using XP.Common.PdfViewer.ViewModels;
using XP.Common.PdfViewer.Views;
namespace XP.Common.PdfViewer.Implementations
{
/// <summary>
/// PDF 查看服务实现 | PDF viewer service implementation
/// 基于 Telerik RadPdfViewer 实现 | Based on Telerik RadPdfViewer
/// </summary>
public class PdfViewerService : IPdfViewerService
{
private readonly ILoggerService _logger;
private readonly IPdfPrintService _printService;
private bool _disposed;
public PdfViewerService(ILoggerService logger, IPdfPrintService printService)
{
_logger = logger?.ForModule<PdfViewerService>()
?? throw new ArgumentNullException(nameof(logger));
_printService = printService
?? throw new ArgumentNullException(nameof(printService));
}
/// <summary>
/// 通过文件路径打开 PDF 阅读器窗口 | Open PDF viewer window by file path
/// </summary>
/// <param name="filePath">PDF 文件路径 | PDF file path</param>
/// <exception cref="FileNotFoundException">文件不存在 | File not found</exception>
/// <exception cref="PdfLoadException">PDF 格式无效 | Invalid PDF format</exception>
public void OpenViewer(string filePath)
{
ObjectDisposedException.ThrowIf(_disposed, this);
// 1. 验证文件路径存在 | Validate file path exists
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath),
"文件路径不能为空 | File path cannot be null or empty");
}
if (!File.Exists(filePath))
{
_logger.Error(new FileNotFoundException(filePath),
"文件不存在 | File not found: {FilePath}", filePath);
throw new FileNotFoundException(
$"文件不存在 | File not found: {filePath}", filePath);
}
try
{
// 2. 创建 PdfViewerWindowViewModel | Create PdfViewerWindowViewModel
var viewModel = new PdfViewerWindowViewModel(filePath, _printService, _logger);
// 3. 创建 PdfViewerWindow 并设置 DataContext | Create PdfViewerWindow and set DataContext
var window = new PdfViewerWindow
{
DataContext = viewModel
};
// 4. 记录 Info 日志 | Log info
_logger.Info("打开 PDF 阅读器窗口 | Opening PDF viewer window: {FileName}",
Path.GetFileName(filePath));
// 5. 显示窗口(非模态)| Show window (non-modal)
window.Show();
}
catch (Exception ex) when (ex is not FileNotFoundException
and not ArgumentNullException
and not PdfLoadException)
{
_logger.Error(ex, "PDF 文件加载失败 | PDF file load failed: {FilePath}", filePath);
throw new PdfLoadException(
"PDF 文件加载失败 | PDF file load failed", filePath, ex);
}
}
/// <summary>
/// 通过文件流打开 PDF 阅读器窗口 | Open PDF viewer window by stream
/// </summary>
/// <param name="stream">PDF 文件流 | PDF file stream</param>
/// <param name="title">窗口标题(可选)| Window title (optional)</param>
/// <exception cref="ArgumentNullException">流为 null | Stream is null</exception>
/// <exception cref="PdfLoadException">PDF 格式无效 | Invalid PDF format</exception>
public void OpenViewer(Stream stream, string? title = null)
{
ObjectDisposedException.ThrowIf(_disposed, this);
// 1. 验证 stream 非 null | Validate stream is not null
ArgumentNullException.ThrowIfNull(stream, nameof(stream));
try
{
// 2. 创建 ViewModel | Create ViewModel
var viewModel = new PdfViewerWindowViewModel(stream, title, _printService, _logger);
// 3. 创建 PdfViewerWindow 并设置 DataContext | Create PdfViewerWindow and set DataContext
var window = new PdfViewerWindow
{
DataContext = viewModel
};
// 4. 记录 Info 日志 | Log info
var displayTitle = title ?? LocalizationHelper.Get("PdfViewer_Title");
_logger.Info("打开 PDF 阅读器窗口(流模式)| Opening PDF viewer window (stream mode): {Title}",
displayTitle);
// 5. 显示窗口(非模态)| Show window (non-modal)
window.Show();
}
catch (Exception ex) when (ex is not ArgumentNullException
and not PdfLoadException)
{
_logger.Error(ex, "PDF 文件加载失败(流模式)| PDF file load failed (stream mode)");
throw new PdfLoadException(
"PDF 文件加载失败 | PDF file load failed", null, ex);
}
}
#region IDisposable | IDisposable Pattern
/// <summary>
/// 释放资源 | Dispose resources
/// </summary>
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 释放资源的核心方法 | Core dispose method
/// </summary>
/// <param name="disposing">是否由 Dispose() 调用 | Whether called by Dispose()</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// 释放托管资源 | Dispose managed resources
_logger.Info("PdfViewerService 已释放 | PdfViewerService disposed");
}
_disposed = true;
}
/// <summary>
/// 终结器安全网 | Finalizer safety net
/// 确保未显式释放时仍能清理非托管资源 | Ensures unmanaged resources are cleaned up if not explicitly disposed
/// </summary>
~PdfViewerService()
{
Dispose(disposing: false);
}
#endregion
}
}