I have a generic repository (the generic type parameter being the aggregate root type being serialized to the database [mongo]).
The repository takes a parameter which in an IEnumerable of ISync services. Low-level database actions may need to be synchronized to other data, and implementors of ISync will do that.
Some psudeocode:
class Repository<T>
{
public Repository(IEnumerable<ISync<T>> synchronizers)
{
...
}
public void Save(T data)
{
database.Save(data);
foreach(synchronizer in _syncrhonizers)
{
synchronizer.Sync(data);
}
}
}
class SomeRandomSync : ISync<ObjectA>
{
public void Sync(ObjectAdata)
{
//do something with that object perhaps even use another repository
new Repository<ObjectB>().Save(objectB); //Obviously this is a constructor injection, I'm just keeping it simple
}
}
Most objects don't have an ISync<T> implementation, so the synchronizers do nothing.
However whenever dealing with such low level injected dependencies there can easily be a dependency cyle. What if there is an implementation of ISync<ObjectB> that, when syncing ObjectBdecides to Save ObjectA? Well, an infinite loop of saves and re-saves that LUCKILY, Castle Windsor would identify ahead of time and tell you "Hey, you've got a dependency cycle and you're doing something wrong."
Luckily only 99% of the time, though, because in my case i don't WANT it to cause a cyclical dependency, I just want that particular ISync<T> service to be ignored. I want to allow the developers using this code to be able to create those dependency cycles (sometimes they are quite necessary because SOME implementors of ISync need to be called, and some should just be ignored if they can't be - they will surely not cause a cycle in another situation.
I tried to do something like this but to no avail (StackOverflowException). Do I have any recourse?
public Repository(IWindsorContainer windsorContainer)
{
var handlers = windsorContainer.Kernel.GetHandlers(typeof(ISync<T>));
var syncers = new List<object>();
foreach (var handler in handlers)
{
try
{
object syncer= handler.TryResolve(CreationContext.CreateEmpty());
syncers.Add(syncer);
}
catch
{
}
}
_syncers = syncers;
}