You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6 WCF中含Lazy静态方法的NLog日志类继承复用方案

解决方案

问题根源在于静态方法属于定义它的基类,当派生类继承基类后,调用的BuildLogFactory仍然是基类的静态方法,Assembly.GetExecutingAssembly()自然返回基类所在程序集的路径,无法获取派生类的程序集信息。

推荐采用泛型基类的方式实现代码复用,同时确保每个派生类能加载自身程序集路径下的对应配置文件:

1. 定义泛型基类

这个基类利用泛型参数的类型信息,自动获取派生类的程序集路径和类名,生成对应的配置文件路径:

using System.Reflection;
using System.IO;
using NLog;

public abstract class LoggerServiceBase<T>
    where T : class
{
    public static LogFactory Instance => _instance.Value;
    private static readonly Lazy<LogFactory> _instance = new Lazy<LogFactory>(BuildLogFactory);

    private static LogFactory BuildLogFactory()
    {
        // 获取派生类的类型信息
        var derivedType = typeof(T);
        // 拿到派生类所在程序集的目录
        string basePath = Path.GetDirectoryName(derivedType.Assembly.Location);
        // 自动生成配置文件名:派生类类名 + .nlog
        string configFileName = $"{derivedType.Name}.nlog";
        string configFilePath = Path.Combine(basePath, configFileName);

        var logFactory = new LogFactory();
        logFactory.Configuration = new XmlLoggingConfiguration(configFilePath, logFactory);
        return logFactory;
    }
}

2. 实现派生类

每个类库的日志服务类只需要继承上述泛型基类,并将自身类型作为泛型参数传入即可,无需额外编写重复代码:

public class SomeDerivedClassLoggerService : LoggerServiceBase<SomeDerivedClassLoggerService>
{
}

public class SomeClassLoggerService : LoggerServiceBase<SomeClassLoggerService>
{
}

3. 使用方式

和你原来的调用方式完全一致,无需改动:

static NLog.ILogger _Logger = SomeDerivedClassLoggerService.Instance.GetCurrentClassLogger();

原理说明

泛型基类的静态成员会为每个不同的泛型参数(即每个派生类)创建独立的实例,通过typeof(T)可以准确获取到派生类的类型,进而拿到其所在程序集的路径,同时自动生成与类名匹配的配置文件名,完美解决重复代码和配置文件加载的问题。

内容的提问来源于stack exchange,提问作者FDB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:55:15