2017-06-21 304 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); 
     }); 

當我忽略此配置,沒有檢測到循環依賴。我所做的只是設置生命時間表。