4

I've been thinking a lot about the organization of Foundation.Abstractions modules (organizing base-types for IoC that Feature - and potentially Foundation - modules use), and I am a bit torn on whether Foundation.Abstractions should really be a single module, a grouping of separate, more granular modules, or else if it should just be core abstractions with other abstractions living in their own, separate Foundation modules.

Putting IIndexableFoo in the same module as IBazWeatherServiceManager (made up interfaces for illustration purposes, only) doesn't feel right to me, since I should be able to remove one the "Indexing" or the "Weather" feature without affecting anything else. I feel like what I should be doing is instead adding sub-modules to Foundation.Abstractions (i.e. using Foundation.Abstractions as a module group and adding a new module to that group). In this case, I might have something like Foundation.Abstractions.Indexing and Foundation.Abstractions.Weather.

In contrast, I know that the Foundation.Abstractions module shouldn't really be aware of what purpose it will server or by which features it will be used. As such, even though it is perfectly acceptable in Helix to group multiple modules together as a single module, I feel like breaking Foundation.Abstractions up the way I described in the example might actually violate the concept that Helix was aiming for. To elaborate, what I mean is that if I were to split up my Foundation.Abstractions module by purpose, I would inherently be making said Foundation layer module aware of the purpose.

The other option that I have is to create separate Foundation layer modules for the different abstractions, and reserve Foundation.Abstractions for core abstractions. In the case of the example I described above, this would likely entail having modules like the following: Foundation.Indexing.Abstractions, Foundation.Weather.Abstractions, and Foundation.Abstractions (or Foundation.Core.Abstractions if Foundation.Core exists and is a module group).

Can anyone help me straighten out the guidelines on when to group abstractions and which would be the better practice when following Helix?


UPDATE: In the example, above, "Weather" was actually a poor choice. The "Indexing" example illustrates the correct point, as it is for a feature that is/modifies part of the platform. I don't want to change the post yet, in case people are currently writing answers, but instead of "Weather" you can think of something like "IEventHandler" or something else that is/modifies part of the platform.

  • It is quite obvious that there is no reason to mix abstractions of different purpose/origin. Let's say, you will want to re-use the Indexing foundation project in another sitecore solution. In case indexing is mixed with whatever IEventHandler (etc) abstractions, you are potentially bringing redundant stuff along, which is super unnecessary and confusing. tldr: dont group unrelated abstractions – Andrey Bobrov Mar 6 '17 at 18:56
4

Let's look at what Feature/Foundation layers are defined as (I'll ignore Project for now as the question focuses on Feature/Foundation):

Feature

The concrete features of the solution, grouped by the business domain of the solution, not the technology.

Features should never depend on other features.

Read more

Foundation

This is the foundation of your solution. Governed by the Stable Dependencies Principle. Note this quote from the docs:

Typically, modules in the Foundation layer are either business-logic specific extensions on the technology frameworks used in the implementation, or shared functionality between feature modules that is abstracted out into separate frameworks.

Typically, modules in the Foundation layer are conceptually abstract and do not contain presentation in the form of renderings or views - as these are to be considered concrete.

Read more

Now - how do we apply this to your question.

So a Foundation layer project, really should take some business logic or technology and provide the abstraction for one or more features to be able to use. A foundation project should not be a generic place to put "things" and it should still not cover multiple business or tecnology units in a single project.

When you talk about a Foundations.Abstraction project, this has the potential to become a dumping ground for everything - similar to how you never want a class called Utilities etc... - it is too generic and has no definition. Maintainability becomes problematic.

Really your whole Foundation layer is your abstraction so that the Features are not tightly coupled to the technology/frameworks that are underlying.

YAGNI

Another very important principle to keep in mind is: YAGNI - if you know that the functionality you are writing needs to be used by multiple features - for example an Indexing project that abstracts the Sitecore Search API - then, yes that is a Foundation project.

But if you don't know or are not sure - then add it to your feature. There is no need to add more code to the "Stable" foundation layer than is absolutely needed. If that bit is needed by another feature later on, refactor it then, when it is needed.

tl;dr

The short version of that is: * Don't add a generic project to the Foundation layer to hold all abstractions, your foundation layer is your abstraction * Add to the Foundation layer when your business features require it, not before. * The Foundation layer still is grouped into logical business or technology units.

Foundation.Abstractions - don't do it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.