在一个WPF项目中(使用prism),我们使用Unity作为DI框架。
最近,在我们合并了两个大的分支之后,我们无法启动我们的应用程序,我们有StackOverflowException。由于异常的性质,我们无法获得他的调用堆栈或当前值,我们只能看到问题是由于名称空间的原因来自Unity。
我们花了5个多小时来找出问题所在:
简化版:
我们有3-4个服务(A,B,C和D),每个服务都有一个实现,在某个时候,服务A需要服务B,服务B需要服务C,服务C需要服务D,服务D需要服务A)。基本上是一个循环引用。
我们想知道是否有可能添加一些日志,Unity正在尝试使用实现X来解决服务A,并要求解决服务B,...
这将对我们调试这个问题有很大帮助,可以直接看到这个循环引用中涉及哪些服务。
有什么办法可以做到这一点吗?
发布于 2018-10-24 22:15:48
参加聚会有点晚了,但对于完全相同的问题,我创建了这个,它工作得很好:
internal class LogExtension : UnityContainerExtension
{
public LogExtension( ILogger logger )
{
_logger = logger;
}
#region UnityContainerExtension
protected override void Initialize()
{
Context.Strategies.Add( new LoggingStrategy( _logger ), UnityBuildStage.PreCreation );
}
#endregion
#region private
private readonly ILogger _logger;
private class LoggingStrategy : BuilderStrategy
{
public LoggingStrategy( ILogger logger )
{
_logger = logger;
}
#region BuilderStrategy
public override void PreBuildUp( IBuilderContext context )
{
_logger.Log( $"Resolving {context.BuildKey.Type} for {context.OriginalBuildKey.Type}" );
}
#endregion
#region private
private readonly ILogger _logger;
#endregion
}
#endregion
}在引导程序中的某个位置(很可能是ConfigureContainer):
Container.AddExtension( new LogExtension( _logger ) );发布于 2021-02-03 11:43:44
如果您正在使用Unity v5+,并且懒于查看从v4到v5的更改,那么您可以复制我的版本:
using System.Reflection;
using Unity.Extension;
using Unity.Builder;
using Unity.Strategies;
namespace Company.ProjectName.Shared.Bootstrap.Unity
{
public class LogResolvesUnityContainerExtension : UnityContainerExtension
{
private static readonly ILogger Logger = LoggerManager.CreateLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected override void Initialize()
{
Context.Strategies.Add(new LoggingStrategy(Logger), UnityBuildStage.PreCreation);
}
private class LoggingStrategy : BuilderStrategy
{
private readonly ILogger _logger;
public LoggingStrategy(ILogger logger)
{
_logger = logger;
}
public override void PreBuildUp(ref BuilderContext context)
{
// Be aware that for Singleton Resolving this log message will only be logged once, when the Singleton is first resolved. After that, there is no buildup and it is just returned from a cache.
var registrationType = context.RegistrationType;
var registrationName = context.Name;
var resolvedType = context.Type;
var registrationNameWithParenthesesOrNothing = string.IsNullOrEmpty(registrationName) ? "" : $"({registrationName})";
_logger.LogDebug($"Resolving [{registrationType}{registrationNameWithParenthesesOrNothing}] => [{resolvedType}]");
}
}
}
}这仍然归功于Haukinger编写了v4的原始版本。
发布于 2016-04-08 20:05:56
您可以配置程序集绑定日志查看器Fusion Log来帮助诊断有问题的Unity解决方案。
它是随Visual Studio一起安装的,您只需在VS命令提示符中键入"fuslogvw“即可启动。
否则,这可能有助于配置记录器:How do I enable assembly bind failure logging (Fusion) in .NET?
https://stackoverflow.com/questions/36332287
复制相似问题