Hi I have a problem with the structure of my code, it somehow goes into Circular Dependency. Here is an explanation of how my code looks like:
I have a ProjectA contains BaseProcessor and BaseProcessor has a reference to a class called Structure in ProjectB. Inside BaseProcessor, there is an instance of Structure as a variable.
In projectB there are someother classes such as Pricing, Transaction etc. Every class in ProjectB has a base class called BaseStructure i.e. Structure, Pricing and Transaction classes all inherited from BaseStructure. Now in Pricing and Transaction classes, I want to call a method in BaseProcessor class from BaseStructure class which causing Circular Dependency.
What I have tried is:
Using Unity, but I didn't figure out how to make it work because I try to use function like:
unityContainer.ReferenceType(IBaseProcessor, BaseProcessor)
in BaseStructure then it will need a reference of BaseProcessor which also cause Circular Dependency.
And I've also tried creating an interface of IBaseProcessor and create a function(the function I want to call) declaration in this interface. And let both BaseProcessor and BaseStructure inherit this interface. But how can I call the function in Pricing and Transaction class without create an instance of BaseProcessor?
Can anyone please tell me how to resolve this problem other than using reflection?
Any help will be much appreciated. Thanks :)
You could use the lazy resolution:
Note that you haven't to register the Lazy because Unity will resolve it by BaseProcessor registration.
Your DI container can't help solving the circular reference, since it is the dependency structure of the application that prevents objects from being created. Even without a DI container, you can't construct your object graphs without some special 'tricks'.
Do note that in most cases cyclic dependency graphs are a sign of a design flaw in your application, so you might want to consider taking a very close look at your design and see if this can't be solved by extracting logic into separate classes.
But if this is not an option, there are basically two ways of resolving this cyclic dependency graph. Either you need to fallback to property injection, or need to postpone resolving the component with a factory,
Func<T>
, or like @onof proposed with aLazy<T>
.Within these two flavors, there are a lot of possible ways to do this, for instance by falling back to property injection into your application (excuse my C#):
This moves the
IBaseProcessor
dependency from the constructor to a property and allows you to set it after the graph is constructed. Here's an example of an object graph that is built manually:A better option is to hide the property inside your Composition Root. This makes your application design cleaner, since you can keep using constructor injection. Example:
Now instead of injecting the
BaseProcessor
into yourStructure
, you inject theCyclicDependencyBreakingProcessor
, which will be further initialized after the construction of the graph:This is basically the same as before, but now the application stays oblivious from the fact that there is a cyclic dependency that needed to be broken.
Instead of using property injection, you can also use
Lazy<T>
, but just as with the property injection, it is best to hide this implementation detail inside your Composition Root, and don't letLazy<T>
values leak into your application, since this just adds noise to your application, which makes your code more complex and harder to test. Besides, the application shouldn't care that the dependency injection is delayed. Just as withFunc<T>
(andIEnumerable<T>
), when injecting aLazy<T>
the dependency is defined with a particular implementation in mind and we're leaking implementation details. So it's better to do the following:With the following wiring:
Up until now I only showed how to build up the object graph manually. When doing this using a DI container, you usually want to let the DI container build up the complete graph for you, since this yields a more maintainable Composition Root. But this can make it a bit more tricky to break the cyclic dependencies. In most cases the trick is to register the component that you want to break with a caching lifestyle (basically anything else than transient). Per Web Request Lifestyle for instance. This allows you to get the same instance in a lazy fashion.
Using the last
CyclicDependencyBreakingProcessor
example, we can create the following Unity registration: