Modules that depend on each other
This is the last part in a 3-part series on dependency, if you have not read the previous posts please read Part 1 and Part 2.
Implicit (Soft/Weak) Dependencies
So how is it possible to have 2 modules that depend on each other? Surely that would not compile, due to the circular reference, right? But it is possible to have implicit dependencies that is where the C# projects do have to reference each-other – but they depend/communicate using non-compiled methods (usually using a string identifier or guid id).
Implicit dependencies are not only limited to modules that only depend on each other, but all types of module dependencies.
Here is a list of possible sources for soft dependencies:
- Url’s
- Query strings – i.e. q for search term.
- Path i.e. /…/Electronics/…/ – i.e. the product type (metadata/taxonomy/categories/etc.) is in the path.
- Host
- Sitecore
- Template ids
- Field names/id’s
- Item paths
- Sitecore queries
- Lucen / Solr indexesSitecore string references
- Pipeline parameters
- Context
- Form data
- Session
- Cache’s
- Request items
- Configuration
- Sitecore.config
- web.config
- External systems (i.e. SQL database, ERP, CRM, etc.)
- Local storage
The most common examples of soft dependencies are query strings or using the field/path/template string identifiers from another module.
For example: Metadata is a typical example where soft dependencies creep in. The metadata module needs the title for a given item. So it uses the sitecore field id’s from the news module, blog module, product module, etc. to get the title from an item.
Solution
Within a blog post it is difficult to give a clear step by step approach and or an example with how to deal with this circular references, but here is a number of solutions.
- Consider that the modules boundaries/responsibilities are incorrect (see solution 1 in part 1).
- Introduce an Abstraction in the foundation layer and keep the concrete implementation in the feature layer (see solution 2 in part 1).
- Slight modification – take the common functionality and move it to a new module in the feature layer and introduce an Abstraction in the foundation layer, for the remaining 2 modules to use.
- Each module defines an interface and then a introduce a class in the project layer (see solution 1 in part 2)
I normally recommend abstraction as the best tool to deal with dependencies. But when 2 modules are only dependent on each other, it is normally because the modules boundaries/responsibilities are incorrect as they are violating the Common-closure principle.
I hope this series on dependencies has been helpful 🙂
Great blog posts. We have had lots of similar discussions and debates internally on how to handle these dependency problems.