Gra*_*ler 24 logging dependency-injection autofac
我试图在遗留代码库中调试一些问题.我认为是由于抛出异常引起的,因为无法从Autofac容器中解析某些内容.但是我觉得异常被埋没在某个地方,我没有看到根本原因.我确信从控制器请求的东西要么找不到,要么可以找到的东西有一个无法满足的依赖.没有任何保护条款等,所以我认为我得到一个空参考问题.为了尝试调试这个,我希望看到容器中找不到的所有请求.
无论如何都要记录Autofac无法解决的所有请求?或者只是将所有请求记录到容器中?
Tra*_*lig 36
您可以通过注册一个特殊模块来为容器添加请求记录,该模块将捕获Preparing所有注册的事件:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是最简单的方法,可能会让你得到你想要的.在Preparing事件记录信息之后,您将看到弹出的异常,您将知道正在抛出的组件.
如果你想更大胆的尝试,你可以在容器设置一些事件处理程序ChildLifetimeScopeBeginning,ResolveOperationBeginning,ResolveOperationEnding,和CurrentScopeEnding事件.
ChildLifetimeScopeBeginning您需要设置某些内容以自动附加到任何子生命周期ResolveOperationBeginning事件时.ResolveOperationBeginning您记录要解决的内容期间.ResolveOperationEnding您记录任何异常情况时.CurrentScopeEnding您需要取消订阅该范围内的任何事件时,垃圾收集器可以清除其所有实例的生命周期范围.Whitebox分析器项目有一个模块可以实现一些更高级的日志记录,但它没有针对最新的Autofac进行设置,因此您必须将其用作起点,而不是剪切/粘贴样本.
同样,最简单的解决方案是我上面发布的模块.
Seb*_*n K 27
只是为了建立一个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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
样本输出:
--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
Run Code Online (Sandbox Code Playgroud)
这个问题的其他答案适用于 Autofac 5.x 版本。任何为Autofac 版本 6.x寻找答案的人都应该查看对 Diagnostics & Logging 的内置支持。Autofac 不再需要自定义逻辑来实现此问题中请求的日志记录类型。
其中的相关部分是:
DefaultDiagnosticTracer来协调您的诊断。这是 Autofac 的一流部分。您设置它,然后让您的容器订阅它。这是一个简单的示例,仅用于Console.WriteLine记录诊断内容。您应该将其替换为您希望用于应用程序的任何日志记录机制。
var tracer = new DefaultDiagnosticTracer();
tracer.OperationCompleted += (sender, args) =>
{
Console.WriteLine(args.TraceContent);
};
container.SubscribeToDiagnostics(tracer);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6183 次 |
| 最近记录: |