我无法弄清楚为什么我会遇到周期性依赖性错误。我也得到许多不同的激活路径和类,看似随意。
这是一个已经工作了一年多的系统中的新问题。它一直在积极开发,所以它不断变化并试图回滚变化以确定问题突然出现的地方在这个时刻做起来有点过于繁琐。
似乎这与多线程和竞争条件有关。当我添加更多线程运行时,错误会更频繁地出现。
当Ninject发出的一个激活路径/依赖关系引起了我的注意时,我一直在努力解决这个问题。 我列出的其中一个依赖项本身没有依赖项。
Ninject.ActivationException: Error activating IMetaValueProvider using binding from IMetaValueProvider to ExecutionOutputMetaValueProvider
A cyclical dependency was detected between the constructors of two services.
Activation path:
6) Injection of dependency IMetaValueProvider into parameter valueProviders of constructor of type MetaValueResolverFactory
5) Injection of dependency IMetaValueResolverFactory into parameter valueResolverFactory of constructor of type MessageExecutionContextFactory
4) Injection of dependency IMessageExecutionContextFactory into parameter executionContextFactory of constructor of type MessageProcessor
3) Injection of dependency IMessageProcessor into parameter messageProcessor of constructor of type MessageProcessingManager
2) Injection of dependency IMessageProcessingManager into parameter messageProcessingManager of constructor of type QueuePollerFactory
1) Request for QueuePollerFactory
在上面的示例中,ExecutionOutputMetaValueProvider
绝对没有依赖关系。
以下是ExecutionOutputMetaValueProvider
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DealerVision.Messaging
{
public class ExecutionOutputMetaValueProvider : IMetaValueProvider
{
public string MetaKeyPrefix
{
get
{
return "Output";
}
}
public object GetMetaValue(IMessageExecutionContext context, string key)
{
if(context.ExecutableMessage.Result == null)
{
throw new Exception($"{nameof(ExecutionOutputMetaValueProvider)} cannot get key \"{key}\" because the {nameof(ExecutableMessageBase)} does not have a result.");
}
if (context.ExecutableMessage.Result.ExecutionOutput.ContainsKey(key))
{
return context.ExecutableMessage.Result.ExecutionOutput[key];
}
return null;
}
public IEnumerable<string> GetPersistantKeys(IMessageExecutionContext executionContext)
{
if (executionContext.ExecutableMessage.Result == null)
return Enumerable.Empty<string>();
List<string> keys = new List<string>();
foreach (var kvp in executionContext.ExecutableMessage.Result.ExecutionOutput)
{
keys.Add($"{this.MetaKeyPrefix}.{kvp.Key}");
}
return keys;
}
}
}
两个问题:
我显然错过了一些东西。任何帮助将不胜感激。
答案 0 :(得分:1)
需要创建实例&#34;自下而上&#34;或者&#34;依赖首先&#34;。这意味着ExecutionOutputMetaValueProvider
在MessageExecutionContextFactory
之前创建,并且再次在... QueuePollerFactory
之前创建。
现在,ninject确实在ExecutionOutputMetaValueProvider
处停止,因为这会导致在链中进一步创建类型。在这一点上,并没有明确说明那是什么。
因为你说ExecutionOutputMetaValueProvider
没有任何依赖关系:
Rebind
和条件绑定)。OnActivation
的使用情况 - 这可能导致激活与类型的实例相结合