Autofac reporting circular dependencies that don't exist -


i added autofac large, existing application manage di.

in process, replaced singletons single instance managed container gets injected dependent's constructor. in cases, however, circular dependencies had broken. easiest way found take advantage of onactivated event. intend modify these types eliminate circular dependencies, risk of changing them great.

to types involved in circular dependencies, added method called resolvecirculardependencies (this makes obvious method used temporarily , purpose of resolving these cycles). method gets called in onactivated event.

so code looks this:

public class servicea {     private serviceb otherservice;      public servicea()     {         ...     }      public void resolvecirculardependencies(serviceb other)     {         this.otherservice = other;     }      public void somemethod()     {         ...         this.otherservice.somemethod();         ...     } }  public class serviceb {     private servicea otherservice;      public serviceb()     {         ...     }      public void resolvecirculardependencies(servicea other)     {         this.otherservice = other;     }      public void somemethod()     {         ...         this.otherservice.somemethod();         ...     } } 

these types registered in autofac module, load method follows:

public override void load(containerbuilder builder) {     builder         .register(ctx => new servicea())         .onactivated(e => e.instance.resolvecirculardependences(e.context.resolve<serviceb>()));      builder         .register(ctx => new serviceb())         .onactivated(e => e.instance.resolvecirculardependences(e.context.resolve<servicea>())); } 

this appears work correctly in cases. however, randomly seeing autofac believes has found circular dependency , returns following stack trace exception:

at autofac.core.resolving.circulardependencydetector.checkforcirculardependency(icomponentregistration registration, stack`1 activationstack, int32 calldepth) @ autofac.core.resolving.resolveoperation.resolve(isharinglifetimescope activationscope, icomponentregistration registration, ienumerable`1 parameters) @ autofac.core.resolving.componentactivation.resolve(icomponentregistration registration, ienumerable`1 parameters) @ autofac.resolutionextensions.tryresolve(icomponentcontext context, service service, ienumerable`1 parameters, object& instance) @ autofac.resolutionextensions.resolve(icomponentcontext context, service service, ienumerable`1 parameters) @ autofac.resolutionextensions.resolve[tservice](icomponentcontext context, ienumerable`1 parameters) @ autofac.resolutionextensions.resolve[tservice](icomponentcontext context) @ domainobjectfactory.resolve[t]() @ domainobjectfactory.buildmyobject() 

we randomly see following error:

at system.throwhelper.throwinvalidoperationexception(exceptionresource resource) @ system.collections.generic.stack`1.enumerator.movenext() @ system.linq.enumerable.count[tsource](ienumerable`1 source, func`2 predicate) @ autofac.core.resolving.circulardependencydetector.iscirculardependency(icomponentregistration registration, stack`1 activationstack) @ autofac.core.resolving.circulardependencydetector.checkforcirculardependency(icomponentregistration registration, stack`1 activationstack, int32 calldepth) @ autofac.core.resolving.resolveoperation.resolve(isharinglifetimescope activationscope, icomponentregistration registration, ienumerable`1 parameters) @ autofac.core.resolving.componentactivation.resolve(icomponentregistration registration, ienumerable`1 parameters) @ autofac.resolutionextensions.tryresolve(icomponentcontext context, service service, ienumerable`1 parameters, object& instance) @ autofac.resolutionextensions.resolve(icomponentcontext context, service service, ienumerable`1 parameters) @ autofac.resolutionextensions.resolve[tservice](icomponentcontext context, ienumerable`1 parameters) @ autofac.resolutionextensions.resolve[tservice](icomponentcontext context) @ domainobjectfactory.resolve[t]() @ domainobjectfactory.buildmyobject() 

these occurring after registrations completed (which occurs on single thread @ application startup). calls buildmyobject method made simultaneously on separate threads. this, however, appears acceptable according autofac wiki.

i have reviewed complete dependency trees of servicea , serviceb , there no cycles in object trees.

has seen behavior? resolution?

we using autofac 2.3.2.632-net35 released download here.

the icomponentcontext domainobjectfactory calling appears temporary 1 created during single resolve operation, e.g. c parameter in like:

builder.register(c => new domainobjectfactory(c)) 

these aren't thread-safe; correct code be:

builder.register(c => new domainobjectfactory(c.resolve<icomponentcontext>()) 

it nasty gotcha appears , then, detectable because once c disposed resolve() call throw telltale objectdisposedexception. i'll make note on concurrency page linked to.


Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

aspxgridview - Devexpress grid - header filter does not work if column is initially hidden -

c# - How to execute a particular part of code asynchronously in a class -