将 NLog 与 MEF 结合使用的最佳方式是什么?

2023-11-21

我想知道将 NLog 与托管可扩展性框架 (MEF) 结合使用的最佳方法是什么?

我有一个支持使用 MEF 架构的插件的应用程序(导入和导出等) 我想向我的应用程序添加日志记录功能。 作为一个日志组件,我想使用 NLog。

你会推荐什么? 1. 为 NLog 创建一个包装器,即配置 NLog 并导出其他插件导入的 void Log(string level, string message) 等函数的附加插件 2. 每个插件都应该配置和使用它自己的 NLog 实例。 (实际上它们都会写入同一个文件)。


这是一种有趣的方法,但是,它似乎存在这样的缺点:所有注入的记录器(或注入的一个单例)将是相同的实例(或将具有相同的名称,该名称是该记录器的名称) NLogLoggingService 类。这意味着您无法非常轻松地控制日志记录的粒度(即,在一个类中将日志记录设置为“Info”级别,在另一个类中将日志记录设置为“Warn”)。此外,如果您选择使用调用站点格式化令牌,则您需要将始终获取调用 NLog 记录器的调用站点,而不是应用程序代码中的调用站点。

这是链接的记录器的缩写版本:

  [Export(Services.Logging.LoggingService, typeof(ILoggingService))] 
  class NLogLoggingService : ILoggingService 
  { 
    Logger log; public NLogLoggingService() 
    { 
      log = LogManager.GetCurrentClassLogger(); 
    } 

    public void Debug(object message) 
    {
      log.Debug(message); 
    }
    public void DebugWithFormat(string format, params object[] args) 
    { 
      if (args.Length == 0) 
      { 
        log.Debug(format); 
      } 
      else
      { 
        Debug(string.Format(format, args)); 
      }
    } 
    public bool IsDebugEnabled 
    { 
      get 
      { 
        return log.IsDebugEnabled; 
      } 
    } 
  }

在构造函数中LogManager.GetCurrentClassLogger()用于获取 NLog 记录器。 GetCurrentClassLogger 将返回一个基于“当前”类型“命名”的 NLog 记录器,在本例中为 NLogLoggingService。因此,要在 app.config 文件中配置 NLog,您将基于记录器名为“SoapBox.Core.NLogLoggingService”的配置。通常,在直接使用 NLog(或 log4net)的代码中,每个类都有自己唯一命名的记录器,如下所示:

namespace MyNamespace
{
  public class MyClass1
  {
    private static readonly Logger logger LogManager.GetCurrentClassLogger();

    public void DoSomeWork()
    {
      logger.Info("Logging from inside MyClass1.DoSomeWork");
    }
  }

  public class MyClass2
  {
    private static readonly Logger logger LogManager.GetCurrentClassLogger();

    public void DoSomeWork()
    {
      logger.Info("Logging from inside MyClass2.DoSomeWork");
    }
  }
}

现在,MyClass1 和 MyClass2 的日志记录可以单独控制。您可以为每个类别配置不同的级别,将它们发送到不同的目标,或者完全关闭其中一个或两个。或者,由于 log4net 和 NLog 中记录器层次结构的概念,您可以通过为命名空间(本例中为 MyNamespace)或任何“祖先”命名空间配置“记录器”来同时控制两个类中的日志记录。如果没有为完全限定的类型名配置记录器,那么日志记录框架实际上会通过将名称视为点分隔字符串并删除最后一个块并检查是否配置了该记录器来向上移动层次结构。因此,在本例中,我们请求 MyNamespace.MyClass1 和 MyNamespace.MyClass2 的记录器。我可以将 app.config 文件配置为在“info”处记录 MyNamespace 并写入文件目标(log4net-speak 中的附加程序)。如果我这样做,那么我通过完全限定名称请求的两个记录器都将继承 MyNamespace 配置。

使用建议的通过 MEF 注入 NLog 的方法,您将只有一个记录器实例,因此您无法将每个类配置为以不同方式记录。另外,正如我之前提到的,如果您选择记录调用站点信息,您将始终获得该类的“SoapBox.Core.NLogLoggingService”和该方法的“Debug”(或 DebugWithFormat、Info、InfoWithFormat 等)。

这似乎是从 log4net 和 NLog 成功注入记录器的问题。您可以看到question几个月前我就问过这个问题。

最终我能够弄清楚一些依赖注入框架如何成功注入特定于正在创建的类的 log4net 和 NLog 记录器(即,如果 DI 框架正在实例化 MyClass,而 MyClass 又依赖于 ILogger 接口,那么 MyClass 将获得一个记录器,本质上相当于 MyClass 通过 LogManager.GetCurrentClassLogger api 请求记录器本身所发生的情况)。通常,DI/IoC 框架中的“解析器”会被赋予当前上下文(其中包含当前正在创建的对象的类型等信息)。有了该类型,让特定于日志记录框架的解析器接收该类型并将其传递给日志记录框架以创建适合该类型的记录器就变得很简单。

为了充分利用 NLog(和 log4net)的功能,您确实希望能够告诉 MEF 您的类依赖于“ILogger”,而且注入到您的类中的“ILogger”实例应该取决于您的班级类型。

我不知道使用 MEF 实现这一目标有多容易。或者,您可以将 NLog 的静态 LogManager 包装在 ILogManager 中并注入它。这将偏离正常的“注入 ILogger”范例。

总结一下:如果您以这种方式通过 MEF 注入 NLog,您确实可以使用 NLog 进行日志记录,但您将只有一个命名的记录器 (SoapBox.Core.NLogLoggingService)。这意味着您将无法以任何粒度进行控制 - 无论是级别/开/关还是输出(NLog Target/log4net Appender)

对于如何通过 MEF 注入 NLog 并保持“原始”NLog 为您提供的粒度/灵活性,我没有一个好的答案。

我可以说我们已经决定使用.NET 的 Common.Logging抽象日志框架,但我们决定不注入日志记录。相反,我们将仅使用静态 LogManager(由 Common.Logging 提供)来分发记录器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 NLog 与 MEF 结合使用的最佳方式是什么? 的相关文章

  • 与仅调用依赖函数/类相比,在 FastAPI 中使用 Depends 有哪些优点?

    FastAPI 提供了way https fastapi tiangolo com tutorial dependencies 通过其自己的依赖关系解析机制来管理依赖关系 例如数据库连接 它类似于一个pytest夹具系统 简而言之 您在函数
  • Laravel 5 包中依赖注入的最佳方法

    我正在为 Laravel 5 开发一个包 现在我需要受益于依赖注入来拥有一个更具可扩展性和可靠性的应用程序 我不知道最好采用哪种方法以及为什么 这是我的一段代码 我需要注射Lang类依赖 class MyController extends
  • 如何在 Caliburn.Micro 中使用 Conductor 的依赖注入

    我有时用Caliburn Micro http caliburnmicro com创建应用程序 使用最简单的 BootStrapper 我可以像这样使用 IoC 容器 SimpleContainer private SimpleContai
  • 从另一个命令 Handle() 方法中调用命令

    嗨 我正在使用简易注射器 https simpleinjector orgDI 库并一直在关注一些关于围绕命令模式设计的架构模型的非常有趣的材料 同时 在我的架构的命令方面 https cuttingedge it blogs steven
  • 春天。使用java配置解决循环依赖而不使用@Autowired

    我有循环依赖和java配置 虽然使用 xml 配置解决它非常简单 但如果没有 Autowired 我无法使用 java 配置解决它 豆子 public class A private B b public B getB return b p
  • 注入需要构造函数参数的服务

    我有一项服务需要启动一些值 Injectable export class MyService private myVals any constructor init any this myVals init 而消费者 Component
  • 为什么我无法调试动态加载的程序集?

    我正在开发一个 Web API 项目 该项目使用内部模拟框架 允许拦截和修改来自控制器的响应 它使用 MEF 加载包含某些先决条件匹配时执行的代码的程序集 我知道这是正常工作的 因为我可以在响应中看到模拟已被执行 但由于某种原因我无法调试动
  • Nlog 异步和日志序列

    在我的 nlog 配置中 我设置了
  • 为什么要使用依赖注入?

    我试图理解依赖注入 http en wikipedia org wiki Dependency injection DI 我再一次失败了 这看起来很愚蠢 我的代码从来不会乱七八糟 我几乎不编写虚拟函数和接口 尽管我千载难逢 并且我的所有配置
  • 我们什么时候需要在 Angular2 的服务中使用 @Injectable ?

    All 我对 Angular2 还很陌生 当我到达依赖注入部分时 Injectable 符号让我有点困惑 只是想确保我对 Injectable 的理解是正确的 Injectable 表示它后面的类可以作为服务注入 Injectable 表示
  • 如何动态实例化服务?

    我有一个Utils服务很重 我想在特定的用户操作中使用其中定义的一些函数 由于这项服务很重 我想延迟实例化它 在用户操作时 我该如何实现这一目标 Service module service Utils function dep1 dep2
  • 使用 asp.net mvc 4 的简单注入器,从另一个程序集加载控制器

    我正在开发一个 asp net mvc 4 站点 使用 Simple Injector 作为 Ioc 工具 这将是一个可插拔的架构 某些控制器和视图位于另一个程序集中 另一个 mvc4 应用程序 Plugin Web dll 从主应用程序中
  • 私有只读接口 - 它是多余的吗?

    我在我的项目中使用 IoC 和 DI 但是我想知道以下是否是一个好的做法 private readonly IMyService myservice 作为服务使用者的类内的字段 该字段在构造函数中设置 我确信我在某处见过这个并且我已经注意到
  • 何时使用接口,何时使用高阶函数?

    给定一个具有以下层的 ASP NET MVC 应用程序 UI 视图 CSS Javascript 等 控制器 服务 包含业务逻辑和数据访问 没有单独的数据访问层的原因是我正在使用 SQL 类型提供程序 以下代码可能不起作用 因为它只是原始草
  • autofac 中的条件组件注册

    是否可以根据其他组件的状态有条件地注册组件 就像是 ContainerBuilder RegisterConditionally
  • 使用策略和工厂模式进行依赖注入

    我正在开展一个业余项目 以更好地理解控制反转和依赖注入以及不同的设计模式 我想知道是否有将 DI 与工厂和策略模式结合使用的最佳实践 当策略 从工厂构建 需要每个可能的构造函数和实现不同的参数时 我面临的挑战就出现了 因此 我发现自己在服务
  • .net 4.7 中的依赖注入?

    我对 DI 有哪些集成选项有点困惑 我发现它对于 net core 对于我的特定项目 来说非常简单 但我不需要构建跨平台应用程序 也看不到使用 core 的优势 但是 net 框架应用程序似乎仍然使用 Global asax 设置且没有 S
  • 如何使用 ILoggerFactory 记录 Polly 的重试

    或者 如何从静态方法记录 From https github com App vNext Polly https github com App vNext Polly你有这样的例子 其中记录器神奇地可用 Policy Timeout 30
  • 提供通用服务接口最具体实现的依赖注入机制

    我觉得我和标题一起玩了流行语宾果游戏 这是我所要求的一个简洁示例 假设我有一些实体的继承层次结构 class BaseEntity class ChildAEntity BaseEntity class GrandChildAEntity
  • 只能通过bootstrap将服务注入到服务中吗?

    我正在尝试连接一个使用 Http 服务的基本 Angular2 应用程序 我见过的大多数教程都是通过Component消耗Http服务 这似乎是错误的 除非瘦控制器的基本理念已经改变 但这是一个不同的问题 我想创建一个使用 Angular

随机推荐

  • 如何获取外键引用的表

    我有一个小问题 但尚未找到答案 如何在 C 中使用 Microsoft SqlServer Smo 外键列所引用的表 foreach Column column in currentTable Columns if column IsFor
  • 如何压缩两个非连续的提交?

    我对 git 中的整个变基功能有点陌生 假设我做出了以下承诺 A gt B gt C gt D 后来我意识到D包含一个修复程序 该修复程序依赖于添加的一些新代码A 并且这些提交属于一起 我该如何压扁A D一起离开B C alone 你可以运
  • 如何从 LLVM 中的 CallInst 获取间接调用的函数名称

    Function fun call gt getCalledFunction getCalledFunction 如果是间接调用则返回 null 如何获取函数的名称或指针的名称 我发现Stack Overflow中与此问题相关的所有问题都谈
  • 在gradle中使用目标sdk版本23时,ZBAR条码扫描库不工作

    我在我的项目中使用 zbar 扫描仪库 更新到 sdk 23 后 棉花糖扫描仪无法工作 以下是 gradle 文件 扫描仪正在工作 如果我将 targetSdkVersion 设置为 23 以外的任何值 以下是gradle文件 apply
  • 按下按键后防止光标隐藏在浏览器中

    我知道在大多数浏览器 最新一代 中 当您输入 A 或空格等任何键时 鼠标光标会隐藏 这是为了让用户看到他输入的内容 一旦您将鼠标移动一个像素 光标就会恢复可见 现在问题来了 这种情况在浏览器中随处可见 即使我关注的是 div 等非输入元素
  • JavaFX 中需要使用 gradle 来定位

    我越来越 java lang NullPointerException 位置是必需的 当我使用 gradle 和 javafx 插件组装后运行我的程序时 如果我从 IntelliJ Idea 运行它 一切都很好 Java源文件和 fxml位
  • Haskell hoogle 通过 cabal 安装,但未找到 hoogle 命令

    hoogle hoogle 4 2 36 安装过程看起来很成功 除了在命令行输入 hoogle 时 它会抱怨 hoogle 找不到命令 在两台机器上尝试过这个 都运行 MAC OS X Yosemite 它们以完全相同的方式失败 有什么建议
  • 非常大的集合的 SQLAlchemy 集合成员资格

    我的 SQL 查询可以非常简单地写为 result session query Table filter Table my key in key set The my key整数列已建立索引 主键 但是key set确实可能非常大 有数千万
  • Linux (Ubuntu 11.10) 中的 Matlab 在绘图中不显示 Unicode(希伯来语)

    我尝试在 Ubuntu 上的 Matlab 图形图中使用希伯来字符 但没有成功 我试过 text 0 6 0 5 fontname times new roman rotation 180 fontsize 50 color r and t
  • 验证器中的 HTML 开始标记有误?

    我正在尝试验证此 HTML 文档http validator w3 org validate by input但我收到以下错误 第 3 行 第 47 列 杂散开始标记 html 第 4 行 第 47 列 杂散开始标记 html 第 5 行
  • 简短的 IF - ELSE 语句

    我试图使我的代码更具可读性 因此我决定使用一些简短的 IF 语句 这是我的代码 它不起作用 不是声明 jXPanel6 isVisible jXPanel6 setVisible true jXPanel6 setVisible false
  • ElasticSearch:搜索嵌套数组中的字段

    我对 ES 相当陌生 正在将它用于我的一个新项目 首先 我有一个客户的简单映射 其中包含名字和姓氏以及支付信息对象列表 如果我在 SQL 中执行此操作 它将类似于客户表和具有一对多关系的付款信息表 这是我正在尝试做的一个简单示例 https
  • 如何序列化对象以通过网络发送

    我正在尝试仅使用 STL 序列化对象以通过套接字通过网络发送 我没有找到一种方法来保持对象的结构在其他主机中反序列化 我尝试转换为string to char 我花了很长时间在互联网上搜索教程 但到目前为止我什么也没找到 有没有办法只用ST
  • LDA 忽略 n_components?

    当我尝试使用 Scikit Learn 的 LDA 时 它只给我一个组件 尽管我要求更多 gt gt gt from sklearn lda import LDA gt gt gt x np random randn 5 5 gt gt g
  • Python C 扩展 - 为什么使用关键字参数的方法强制转换为 PyCFunction

    我正在学习 Python C 扩展 并且很困惑为什么使用关键字参数的方法必须转换为 PyCFunctions 我对 PyCFunction 的理解是它需要两个指向 PyObjects 的指针并返回一个指向 PyObject 的指针 例如 P
  • 记忆处理程序[重复]

    这个问题在这里已经有答案了 创建一个像下面这样可以为您处理记忆过程的类是 好习惯 吗 记忆化的好处是如此之大 在某些情况下 比如这个 它从我的计算机上的 501003 次函数调用减少到 1507 次函数调用 并将 CPU 时间从 1 409
  • iOS 正则表达式 阿拉伯语

    我来自这个帖子 正则表达式 仅限阿拉伯字符和数字 如何将阿拉伯语单词与正则表达式匹配 没有回答我的问题 我试过了 p Arabic 并收到 解析错误 原因 无效的转义序列 pos 3 p 阿拉伯语 我也尝试过 u0621 u064A s 解
  • 无法读取配置文件,因为它超出了最大文件大小

    无法读取配置文件 因为它超出了最大文件大小 我收到上述错误是因为我的 rewritemap config 文件大小超过 250KB 带有 IIS 7 5 的 Windows 2008 R2 SP1 服务器 如果您有权访问注册表并且确实需要大
  • ionic/cordova 中的 Firebase 离线功能

    有人在 Android iOS 中使用 Firebase 实现了具有完整离线功能的本机应用程序吗 可以通过使用本机 Firebase SDK 的插件在 Cordova Ionic 中完成此操作吗 我们正在构建一个在下载和首次启动时具有连接的
  • 将 NLog 与 MEF 结合使用的最佳方式是什么?

    我想知道将 NLog 与托管可扩展性框架 MEF 结合使用的最佳方法是什么 我有一个支持使用 MEF 架构的插件的应用程序 导入和导出等 我想向我的应用程序添加日志记录功能 作为一个日志组件 我想使用 NLog 你会推荐什么 1 为 NLo