Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Logging 如何将所有解析请求记录到Autofac容器?_Logging_Dependency Injection_Autofac - Fatal编程技术网

Logging 如何将所有解析请求记录到Autofac容器?

Logging 如何将所有解析请求记录到Autofac容器?,logging,dependency-injection,autofac,Logging,Dependency Injection,Autofac,我试图调试遗留代码库中的一些问题。我认为这是由抛出异常引起的,因为Autofac容器无法解决某些问题。然而,我认为这个例外正在某处被埋葬,我没有看到根本原因。我确信某个控制器正在请求某个无法找到的内容,或者某个可以找到的内容具有无法满足的依赖关系。没有任何保护条款等,所以我想我得到了一个空引用问题。要尝试并调试此操作,我希望查看容器中未找到的所有请求 是否仍要记录Autofac无法解决的所有请求?或者只是将所有请求记录到容器中 您可以通过注册一个特殊模块将请求的日志记录添加到容器中,该模块将捕获

我试图调试遗留代码库中的一些问题。我认为这是由抛出异常引起的,因为Autofac容器无法解决某些问题。然而,我认为这个例外正在某处被埋葬,我没有看到根本原因。我确信某个控制器正在请求某个无法找到的内容,或者某个可以找到的内容具有无法满足的依赖关系。没有任何保护条款等,所以我想我得到了一个空引用问题。要尝试并调试此操作,我希望查看容器中未找到的所有请求


是否仍要记录Autofac无法解决的所有请求?或者只是将所有请求记录到容器中

您可以通过注册一个特殊模块将请求的日志记录添加到容器中,该模块将捕获所有注册的
准备
事件:

public class LogRequestsModule : Module
{
  protected override void AttachToComponentRegistration(
    IComponentRegistry componentRegistry,
    IComponentRegistration registration)
  {
    // Use the event args to log detailed info
    registration.Preparing += (sender, args) =>
      Console.WriteLine(
        "Resolving concrete type {0}",
        args.Component.Activator.LimitType);
  }
}
这是最简单的方法,可能会得到你想要的。在
准备
事件记录信息之后,您将看到异常弹出,您将知道哪个组件正在抛出

如果您想变得更有趣,可以在容器
ChildLifeTimeScopeBeging
ResolveOperationBeging
ResolveOperationEnding
CurrentScopeEnding
事件上设置一些事件处理程序

  • ChildLifeTimeScopeBeging
    期间,您需要设置一些自动附加到任何子生命周期
    ResolveOperationBeging
    事件的内容
  • ResolveOperationStart
    期间,您将记录要解决的问题
  • ResolveOperationEnding
    期间,您将记录出现的任何异常
  • CurrentScopeEnding
    期间,您需要取消订阅该作用域上的任何事件,以便垃圾回收器可以清理生存期作用域及其所有实例
这实现了一些更高级的日志记录,但它不是为最新的Autofac设置的,因此您必须将其用作起点,而不是剪切/粘贴示例


同样,最简单的解决方案是我在上面发布的模块。

仅仅是基于Travis的一个优秀答案,以防它对将来的人有所帮助

如果您的类结构很深,那么如果您在合成层次结构中显示对象,则可能更容易发现有问题的路径。这可以通过以下方式实现:

using System;
using System.Text;
using Autofac;
using Autofac.Core;

namespace Tests
{
    public class LogRequestModule : Module
    {
        public int depth = 0;

        protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry,
                                                              IComponentRegistration registration)
        {
            registration.Preparing += RegistrationOnPreparing;
            registration.Activating += RegistrationOnActivating;
            base.AttachToComponentRegistration(componentRegistry, registration);
        }

        private string GetPrefix()
        {
            return new string('-',  depth * 2);
        }

        private void RegistrationOnPreparing(object sender, PreparingEventArgs preparingEventArgs)
        {
            Console.WriteLine("{0}Resolving  {1}", GetPrefix(), preparingEventArgs.Component.Activator.LimitType);
            depth++;
        }

        private void RegistrationOnActivating(object sender, ActivatingEventArgs<object> activatingEventArgs)
        {
            depth--;    
            Console.WriteLine("{0}Activating {1}", GetPrefix(), activatingEventArgs.Component.Activator.LimitType);
        }
    }
}

此问题的其他答案适用于5.x版之前的Autofac。任何想为Autofac 6.x版寻找答案的人都应该去看看。Autofac不再需要自定义逻辑来实现此问题中所要求的记录类型

其中的相关部分包括:

  • 您不再需要将其集成到注册级别逻辑中。虽然你可以,如果你愿意,有一个例子在链接的网址
  • 使用
    DefaultDiagnosticTracer
    协调诊断。这是Autofac的一流部件。您设置它,然后让您的容器订阅它
下面是一个简单的示例,它仅使用
Console.WriteLine
记录诊断内容。你应该用你希望应用程序使用的任何日志记录机制来替换它

var tracer=newdefaultdiagnostictracer();
tracer.OperationCompleted+=(发送方,参数)=>
{
控制台写入线(参数TraceContent);
};
容器。不可知论者(追踪者);

我知道,所以我不赞成谢谢你。不过,我非常感谢您为支持Autofac问题所做的努力。答案总是非常详细只是为了减少注入的依赖性,就像我一样,这就是注册这个模块的方式:builder.RegisterModule();Travis谢谢你的回答,你能不能给我一个片段,告诉我如何记录解析类型的作用域名称?鉴于不是所有的生存期作用域都有名称,你可能无法得到你想要的。但是在您的
ResolveOperationBeging
处理程序中,您可以记录
this.Tag
(如果存在,这将是生存期范围的名称)。不过,您会得到一些令人困惑的结果,因为一个作用域中的对象可能会解析来自不同/父作用域的依赖项。我没有这方面的代码片段。吹毛求疵,但肯定“深度”应该是实例属性,而不是静态属性。同时使用两个的可能性显然很小,但仍然…@piers7,正确,验证了使用实例属性就可以了,更改了itMan,我无法让任何一个工作:(它编译和运行时没有错误,模块添加到容器中,但从未命中注册事件…@Jester您是否已将LogRequestModule添加到ContainerBuilder?
ContainerBuilder.RegisterModule();
RegisterModule(新LogRequestModule())
不起作用-未记录任何内容,记录代码中的断点从未命中。请注册您编写代码的方式。
--Resolving  SomeProject.Web.Integration.RestApiAdapter.RestApiAdapter
----Resolving  SomeProject.Web.Integration.RestApiAdapter.Client.ClientFactory
------Resolving  SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
------Activating SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
------Resolving  SomeProject.Web.Integration.RestApiAdapter.Client.Authentication.ApiClientAuthenticationService
--------Resolving  SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
--------Activating SomeProject.Web.Integration.RestApiAdapter.RestApiAdapterConfiguration
------Activating SomeProject.Web.Integration.RestApiAdapter.Client.Authentication.ApiClientAuthenticationService