首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何调试Unity resolution?

如何调试Unity resolution?
EN

Stack Overflow用户
提问于 2016-03-31 19:36:03
回答 3查看 2.9K关注 0票数 17

在一个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,...

这将对我们调试这个问题有很大帮助,可以直接看到这个循环引用中涉及哪些服务。

有什么办法可以做到这一点吗?

EN

回答 3

Stack Overflow用户

发布于 2018-10-24 22:15:48

参加聚会有点晚了,但对于完全相同的问题,我创建了这个,它工作得很好:

代码语言:javascript
复制
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):

代码语言:javascript
复制
Container.AddExtension( new LogExtension( _logger ) );
票数 8
EN

Stack Overflow用户

发布于 2021-02-03 11:43:44

如果您正在使用Unity v5+,并且懒于查看从v4到v5的更改,那么您可以复制我的版本:

代码语言:javascript
复制
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的原始版本。

票数 1
EN

Stack Overflow用户

发布于 2016-04-08 20:05:56

您可以配置程序集绑定日志查看器Fusion Log来帮助诊断有问题的Unity解决方案。

它是随Visual Studio一起安装的,您只需在VS命令提示符中键入"fuslogvw“即可启动。

否则,这可能有助于配置记录器:How do I enable assembly bind failure logging (Fusion) in .NET?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36332287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档