9

Sitecore Helix- Modules that need to reference another module in the same layer...

 3 years ago
source link: https://blog.coates.dk/2017/04/26/sitecore-helix-modules-that-need-to-reference-another-module-in-the-same-layer-part-2/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

One module which is dependent on 2 or more modules

This is the second part in a 3-part series on dependency, if you have not read part 1 please read it first.

When a single module is dependent on 2 or more other modules in the feature layer there are few ways to solve this issue:

The Metadata Challenge

one-on-many.png?w=522&h=233

A typical example of a module, which can be dependent on 2 or more modules, is Metadata. In addition to providing keywords, taxonomy, etc. metadata is generally responsible for generating the title element in the head section and typical requirements could be as follows:

  1. If it is a news article, use the news title.
  2. If it is a blog post, use the blog post.
  3. If it is a product page, get the product title from the database.
  4. Otherwise return the item display name.

Metadata is a good example where implicit/soft dependency typically creep in, i.e. the metadata module needs the title for a given item and it uses the Sitecore field from the news module, blog module, product module, etc.

Solution 1 – Introduce an abstraction and implemente the abstraction in the project layer.

in-the-project-layer1.png?w=517&h=294

The only information that the metadata module needs that it can not determine itself is the title for a given item. Therefore, it is necessary to introduce an interface that satisfies that requirement, for an item give me the title. It is in fact very simple, see below.

namespace Feature.MetaData
{
internal interface ITitleRepository
{
string Get(Item item);
}
}

The context in the project layer is well suited to implement the ITitleRepository interface, as the project layer is responsible for aggregating/mediating the functionality provided by the feature and foundation layers.

Therefore, the next step is to implement ITitleRepository in the project layer, by getting the relevant information from the features (i.e. news, blogs, products) and provide the default behavior of returning the Display name if all else fails (see the example implementation below).

namespace Feature.MetaData
{
namespace Project.Context
{
class TitleRepository : ITitleRepository
{
public string Get(Item item)
{
if (item == null)
return string.Empty;
// we assume that each repsository returns null, if the item is ot of the correct type...
string value;
//is the item a news?
var news = _newsRepository.Get(item);
if (!string.IsNullOrEmpty(news?.Title))
return news.Title;
//is it a blog post?
var blog = _blogRepository.Get(item);
if (!string.IsNullOrEmpty(blog?.Title))
return blog.Title;
//is a blog post?
var product = _productRepository.Get(item);
if (!string.IsNullOrEmpty(product?.Name))
return product.Name;
//default return display name...
return item.DisplayName;
}
readonly ProductRepository _productRepository = new ProductRepository();
readonly NewsRepository _newsRepository = new NewsRepository();
readonly BlogRepository _blogRepository = new BlogRepository();
}
}}

The last step is to use dependency inject to inject the implementation from the project layer, for the interface ITitleRepository.

Solution 2 – Introduce an Abstractions in the foundation layer

In some situations, it might be appropriate to introduce an abstraction in the foundation layer, but only if more than one feature depend on the abstraction. If only the Metadata is using the abstraction it is not sufficient to introduce an abstraction in the foundation layer.

In addition, you should consider why was the abstraction not identified and or present already, it could be a mistake but be sure.

move-to-foundation.png?w=469&h=297

See Part 1, where I have a step by step guide on how to implement this.

Solution 3 – Move the module to the project layer

move-to-project-layer.png?w=453&h=331

Whilst this is an easy solution I do not recommend it.

The purpose of the project layer is to aggregate functionality provided by the feature layer and not provide functionality. For example:

  • Page Types module – determine which features are shown on given page type.
  • Context module is responsible for determining the context for each request
    • for example using dependency injection to decide which implementation should be used for any abstractions.

In addition the project is the least stable layer, and the majority of the Metadata functionality in my experience is very stable and similar across all projects, the only variation is how the title is generated and this is not enough to warrant it being moved to the project layer.

I hope this was helpful, and please continue to part 3.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK