尝试使用Autofac构建以下内容时出现循环依赖项异常:
builder.RegisterType<Session>().As<ISession>();
builder.RegisterType<SFEventStore>().As<IEventStore>();
builder.RegisterType<MemoryCache>().As<ICache>();
builder.Register(c =>
{
return new CacheRepository(new Repository(c.Resolve<IEventStore>()), c.Resolve<IEventStore>(), c.Resolve<ICache>());
})
.As<IRepository>();
问题是IRepository,它解析为CacheRepository,而CacheRepository依赖于IRepository:
public CacheRepository(IRepository repository, IEventStore eventStore, ICache cache);
Repository在其构造函数中使用IEventStore:
public class Repository : IRepository
{
private readonly IEventStore _eventStore;
public Repository(IEventStore eventStore)
{
_eventStore = eventStore ?? throw new ArgumentNullException(nameof(eventStore));
}
}
CacheRepository遵循装饰器模式并向存储库添加功能:
public class CacheRepository : IRepository
{
private readonly IRepository _repository;
private readonly IEventStore _eventStore;
private readonly ICache _cache;
public CacheRepository(IRepository repository, IEventStore eventStore, ICache cache)
{
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
_eventStore = eventStore ?? throw new ArgumentNullException(nameof(eventStore));
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
}
因此,尽管我在Autofac构建器方法中新建了一个Repository,但Autofac仍然会尝试解析CacheRepository构造函数中的IRepository,该构造函数解析为CacheRepository。因此循环依赖。
尝试使用Autofac装饰器解决此问题,如下所示:
builder.RegisterType<Session>().As<ISession>();
builder.RegisterType<SFEventStore>().As<IEventStore>();
builder.RegisterType<MemoryCache>().As<ICache>();
builder.Register(c =>
{
return new Repository(c.Resolve<IEventStore>());
})
.Named<IRepository>("implementor");
builder.RegisterDecorator<IRepository>(
(c, inner) => new CacheRepository(inner, c.Resolve<IEventStore>(), c.Resolve<ICache>()),
fromKey: "implementor");
但没有运气。仍然给出循环依赖!
该链从解析会话开始,该会话具有以下ctor:
public Session(IRepository repository);
所以我应该得到以下组件依赖树:
Session --> CacheRepository --> Repository --> SFEventStore
但它转而解决:
Session --> CacheRepository --> CacheRepository
这是堆栈跟踪:
Autofac.Core.DependencyResolutionException:检测到循环组件依赖关系:AnswersBC.Command.Handlers.AddAnswerCmdHandler - &gt; CQRSlite.Domain.Session - &gt; CQRSlite.Cache.CacheRepository - &gt; CQRSlite.Cache.CacheRepository。在Autofac.Core.Resolving.CircularDependencyDetector.CheckForCircularDependency(IComponentRegistration注册,堆栈1 activationStack, Int32 callDepth) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1个参数)在C:\ BuildAgent \工作\ 3206e2123f54fce4 \ SRC \ NServiceBus.Core \许可\ LogErrorOnInvalidLicenseBehavior.cs:在Autofac线0。 Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()位于C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:第0行,位于Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context) ,IEnumerable的1 parameters) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1个参数)在C:\ BuildAgent \工作\ 3206e2123f54fce4 \ SRC \ NServiceBus.Core \许可\ LogErrorOnInvalidLicenseBehavior.cs:行0在Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(GUID ID,Func键{ {1}} 1个参数)在C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:第0行,位于C:\ BuildA中的Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()绅士\工作\ 3206e2123f54fce4 \ SRC \ NServiceBus.Core \许可\ LogErrorOnInvalidLicenseBehavior.cs:行0在Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext上下文,IEnumerable的1 creator) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.InstanceLookup.Execute() in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1个参数)在C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:在C:\ BuildAgent \ work \中的Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id,Func 1 parameters) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1个参数)的第0行3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:第0行,位于C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior中的Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()。 CS:线0在Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext上下文,IEnumerable的1 creator) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.InstanceLookup.Execute() in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1个参数)在C:\ BuildAgent \工作\ 3206e2123f54fce4 \ SRC \ NServiceBus.Core \许可\ LogErrorOnInvalidLicenseBehavior.cs :第0行在Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(GUID标识,函数功能1 parameters) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1个参数)在C:\ BuildAgent \工作\ 3206e2123f54fce4 \ SRC \ NServiceBus.Core \许可\ LogErrorOnInvalidLicenseBehavior.cs:在Autofac线0。 Core.Resolving.ResolveOperation.Execute(IComponentRegistration注册,IEnumerable 1 creator) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.InstanceLookup.Execute() in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1个参数,Object&amp;在C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs中:在C:\ BuildAgent \中的Autofac.ResolutionExtensions.ResolveService(IComponentContext上下文,服务服务,IEnumerable`1参数)中的第0行work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:位于C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ ObjectBuilder \ Autofac \ AutofacObjectBuilder中的NServiceBus.AutofacObjectBuilder.Build(Type typeToBuild)的第0行。 cs:位于C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Pipeline \ Incoming \ LoadHandlersConnector.cs:第37行的NServiceBus.LoadHandlersConnector.d__1.MoveNext()第39行
答案 0 :(得分:1)
您描述的内容与Decorator模式完全相同。你有两个IRepository实现,一个包装另一个。 Autofac使用.RegisterDecorator()
本地支持此功能请参阅此处的文档, http://docs.autofac.org/en/latest/advanced/adapters-decorators.html
我相信你的新问题就是问题,见下面的例子
不要使用它:
builder.Register(c =>
{
return new Repository(c.Resolve<IEventStore>());
})
.Named<IRepository>("implementor");
而是使用它:
builder.RegisterType<Repository>().Named<IRepository>("implementor");
builder.RegisterDecorator<IRepository>(
(c, inner) => new CacheRepository(inner, c.Resolve<IEventStore>(), c.Resolve<ICache>()),
fromKey: "implementor");
答案 1 :(得分:0)
似乎必须对NServiceBus中组件的配置做一些事情:
nsbEndpointConfig.RegisterComponents(registration: configureComponents =>
{
configureComponents.ConfigureComponent<Session>(DependencyLifecycle.InstancePerUnitOfWork);
configureComponents.ConfigureComponent<SFEventStore>(DependencyLifecycle.InstancePerUnitOfWork);
configureComponents.ConfigureComponent<MemoryCache>(DependencyLifecycle.InstancePerUnitOfWork);
configureComponents.ConfigureComponent<Repository>(DependencyLifecycle.InstancePerUnitOfWork);
configureComponents.ConfigureComponent<CacheRepository>(DependencyLifecycle.InstancePerUnitOfWork);
});
当我省略此配置时,未检测到循环依赖性。我所做的就是设置生命望远镜。