2017-06-21 199 views
0

我在尝试建立与Autofac以下时循环依赖例外: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); 

对存储库的一个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)); 

     } 

所以eventhough我新起来的Autofac建设者方法库,Autofac仍然尝试解决IRepository在CacheRepository构造函数,它解析为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"); 

,但没有运气。仍然给循环依赖!

public Session(IRepository repository); 

所以我应该有以下组件的依赖关系树:

Session --> CacheRepository --> Repository --> SFEventStore 

而是将其解析为:

链与解决一个会话,它具有以下构造函数启动

Session --> CacheRepository --> CacheRepository 

这是堆栈跟踪:

Autofac.Core.DependencyResolutionException:检测到循环组件依赖项:AnswersBC.Command.Handlers.AddAnswerCmdHandler - > CQRSlite.Domain.Session - > CQRSlite.Cache.CacheRepository - > CQRSlite.Cache.CacheRepository。 Autofac.Core.Resolving.CircularDepenctor.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参数)在Autofac.Core.Activators的C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:行0。 C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs中的Reflection.ConstructorParameterBinding.Instantiate():Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance中的行0(IComponentContext上下文,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 \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs中:第0行在Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id,Func 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 parameters)in C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:Autofac.Core.Activat中的第0行C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs中的ors.Reflection.ConstructorParameterBinding.Instantiate():Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext上下文,IEnumerable C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:在Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id,Func 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 parameters)中的第0行:C:\ Program Files \ 1 parameters) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable 1 parameters) \ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:Autofac.Core.Activators.Reflection中的第0行。C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs中的ConstructorParameterBinding.Instantiate():Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance的第0行(IComponentContext上下文,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 \ work中的C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs中的第0行:Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id,Func 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 parameters) \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:在Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration注册,IEnumerable 1 parameters) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Licensing\LogErrorOnInvalidLicenseBehavior.cs:line 0 at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable 1参数,对象&实例)在C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs:Autofac.ResolutionExtensions.Resol中的第0行在C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Licensing \ LogErrorOnInvalidLicenseBehavior.cs中的veService(IComponentContext上下文,服务服务,IEnumerable`1参数)中的第0行:NServiceBus.AutofacObjectBuilder.Build(Type typeToBuild) \ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ ObjectBuilder \ Autofac \ AutofacObjectBuilder.cs:第39行在NServiceBus.LoadHandlersConnector.d__1.MoveNext()在C:\ BuildAgent \ work \ 3206e2123f54fce4 \ src \ NServiceBus.Core \ Pipeline \ Incoming \ LoadHandlersConnector.cs:line 37

+0

你可以在你的循环引用异常上发布你的堆栈跟踪吗? – raterus

+0

将代码更改为首先将存储库注册为命名服务(“实现者”)。这会添加堆栈跟踪...仍然是循环依赖。党! –

+0

我已经用一些东西来更新我的答案,我认为问题在于您对Repository的兴趣,而不是让Autofac去做。如果您需要这样做的理由很充分,请让我知道为什么 – raterus

回答

1

您所描述的内容听起来完全像装饰模式。你有两个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"); 
+0

对不起,仍然是同样的问题:-( –

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); 
     }); 

当我忽略此配置,没有检测到循环依赖。我所做的只是设置生命时间表。