Dependency injection 如何使用log4net作为服务输出上下文类?

Dependency injection 如何使用log4net作为服务输出上下文类?,dependency-injection,log4net,structuremap,Dependency Injection,Log4net,Structuremap,我使用Log4Net作为一个服务,它使用StructureMap注入到其他服务中 如何确保日志文件包含调用服务类上下文类名和/或进行log4net调用的线程 当然,调用类或线程始终是日志服务,这并不能帮助我理解日志调用的真正来源 编辑: 注册码: ObjectFactory.Initialize(x => { x.For<ILog>().AlwaysUnique().Use(s => s.ParentType == nul

我使用Log4Net作为一个服务,它使用StructureMap注入到其他服务中

如何确保日志文件包含调用服务类上下文类名和/或进行log4net调用的线程

当然,调用类或线程始终是日志服务,这并不能帮助我理解日志调用的真正来源

编辑:

注册码:

  ObjectFactory.Initialize(x =>
    {           
        x.For<ILog>().AlwaysUnique().Use(s => s.ParentType == null ? 
            LogManager.GetLogger(s.BuildStack.Current.ConcreteType) : 
            LogManager.GetLogger(s.ParentType));

    });
在日志记录中,我仍然总是将LoggerService作为上下文,因此我永远看不到真正的logger。它似乎工作不正常。我觉得我错过了一些东西

编辑2: 我在此处添加了控制台应用程序的粘贴链接:


我希望父类被记录下来,但它在最简单的级别上无法工作。

您可能需要查看一下,以便使用AOP解决它。在StructureMap Google Group上,没有将其与StructureMap一起使用的方法


Ayende使用Log4Net和Windsor进行了基于AOP的日志记录。

您可能需要看看,以便使用AOP解决这个问题。在StructureMap Google Group上,没有将其与StructureMap一起使用的方法


Ayende使用Log4Net和Windsor进行了大量基于AOP的日志记录。

我在生成的许多代码中使用StructureMap,并且我有一个StructureMap注册表,我使用它将日志记录挂接到注入的类的上下文中

作为参考,我使用的是StructureMap的2.6.2版本,但在使用新的.For.Use格式的2.5+版本时应该可以

public class CommonsRegistry : Registry
{
  public CommonsRegistry()
  {
    For<ILogger>().AlwaysUnique().Use(s => s.ParentType == null ? new Log4NetLogger(s.BuildStack.Current.ConcreteType) : new Log4NetLogger(s.ParentType.UnderlyingSystemType.Name));
    XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location), "Log.config")));
  }
}

现在,消息被记录为context/class foo。

我在生成的许多代码中使用StructureMap,并且我有一个StructureMap注册表,我使用它将记录器挂接到它被注入的类的上下文中

作为参考,我使用的是StructureMap的2.6.2版本,但在使用新的.For.Use格式的2.5+版本时应该可以

public class CommonsRegistry : Registry
{
  public CommonsRegistry()
  {
    For<ILogger>().AlwaysUnique().Use(s => s.ParentType == null ? new Log4NetLogger(s.BuildStack.Current.ConcreteType) : new Log4NetLogger(s.ParentType.UnderlyingSystemType.Name));
    XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location), "Log.config")));
  }
}

现在,这些消息被记录为context/class foo。

感谢链接。有没有办法使用StructureMap,因为这就是我的应用程序目前用于DI的方法?是的,请看一下我链接到使用StructureMap的示例:它对SM使用了较旧的语法,但原理是相同的。基本上,您可以使用EnrichWith并包装要使用DynamicProxy记录的实例,并实现记录拦截器。示例中的拦截器将日志记录到控制台,但您可以将其切换到Log4Net。感谢链接。有没有办法使用StructureMap,因为这就是我的应用程序目前用于DI的方法?是的,请看一下我链接到使用StructureMap的示例:它对SM使用了较旧的语法,但原理是相同的。基本上,您可以使用EnrichWith并包装要使用DynamicProxy记录的实例,并实现记录拦截器。示例中的拦截器将日志记录到控制台,但您可以将其切换到Log4Net.Hi,这与第一个建议的丰富功能相比如何?我正在权衡两种选择的利弊。不过看起来不错!enrich文档中说EnrichWith-注册一个Func,该Func在创建新对象后运行,并允许您选择返回一个不同于原始对象的对象,在创建记录器时我的注册表函数所在的位置,在我的示例中设置父类foo的正确上下文。@jaffa-正如@Bryan所说,EnrichWith将用新对象替换对象。在使用DynamicProxy进行日志记录的情况下,您将围绕目标创建一个包装器类来执行日志记录。使用AOP的优点是,您不必向要记录的每个位置添加日志代码,它将在运行时被拦截并自动记录。请参阅Ayendes post了解更多解释。更新了CommonRegistry例程。您好,这与第一个建议的丰富功能相比如何?我正在权衡两种选择的利弊。不过看起来不错!enrich文档中说EnrichWith-注册一个Func,该Func在创建新对象后运行,并允许您选择返回一个不同于原始对象的对象,在创建记录器时我的注册表函数所在的位置,在我的示例中设置父类foo的正确上下文。@jaffa-正如@Bryan所说,EnrichWith将用新对象替换对象。在使用DynamicProxy进行日志记录的情况下,您将围绕目标创建一个包装器类来执行日志记录。使用AOP的优点是,您不必向要记录的每个位置添加日志代码,它将在运行时被拦截并自动记录。请参阅Ayendes post以了解更多解释。更新了CommonRegistry例程。似乎您已将记录器抽象到比我通常会做的更高的级别,但请尝试对ObjectFactory执行此操作。请改为初始化:将[LogManager.GetLoggers.ParentType]替换为[LogManager.GetLoggers.ParentType.Un]
derlyingSystemType.Name]@Bryan-我尝试改用s.root.ConcreteType.Name,并将app.config设置为使用%logger输出记录器的名称。它没有给我SubActionService logger的名称,不过请参见下面的我的Paste链接。UnderlineingSystemType始终是LoggerService,这没有帮助。请尝试在[x.For.AlwaysUnique.Use]lambda表达式中使用断点,在监视窗口中检查[s.ParentType]的值,并向下钻取到要查找的值。这就是我在使用源代码查看注入类的父类型时使用的方法。似乎您已将记录器抽象到比我通常要做的更高的级别,但请尝试对ObjectFactory执行此操作。请改为初始化:将[LogManager.GetLoggers.ParentType]替换为[LogManager.GetLoggers.ParentType.UnderlineingSystemType.Name]@Bryan-我尝试改用s.root.ConcreteType.Name,并将app.config设置为使用%logger输出记录器的名称。它没有给我SubActionService logger的名称,不过请参见下面的我的Paste链接。UnderlineingSystemType始终是LoggerService,这没有帮助。请尝试在[x.For.AlwaysUnique.Use]lambda表达式中使用断点,在监视窗口中检查[s.ParentType]的值,并向下钻取到要查找的值。这就是我在使用源代码查看注入类的父类型时使用的方法。
ObjectFactory.Initialize(x =>
{
  x.AddRegistry<CommonsRegistry>();
  ...
}
class foo
{
  private readonly ILogger _log;

  public foo(ILogger log)
  {
    _log = log;
  }
}