Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Alternate Visual Studio Solution Structures #21

Closed
nickwesselman opened this issue Nov 8, 2018 · 31 comments
Closed

RFC: Alternate Visual Studio Solution Structures #21

nickwesselman opened this issue Nov 8, 2018 · 31 comments
Labels

Comments

@nickwesselman
Copy link
Collaborator

@nickwesselman nickwesselman commented Nov 8, 2018

The Helix guidelines on solution structure and the Habitat example both utilize Visual Studio Projects to help define and enforce module boundaries and dependencies. While many in the community utilize this approach, much of the feedback around Helix has centered on the overhead of utilizing Visual Studio Projects in this way -- module creation, solution load time, build time, deployment complexity, dependency upgrades, etc. Though tooling and proper build configuration can help with this, there are reasonable arguments that this level of structure is not needed for all solutions.

Many developers utilize a "project-per-layer" approach, potentially using FxCop rules to help enforce module boundaries. Though this somewhat violates Common Closure, it likely can achieve the same maintainability goals for many/most Sitecore implementations. There is also potential for a hybrid approach, using a project-per-module just in the Foundation layer, since dependency management requires more care in the Foundation (which allows dependencies between modules in the same layer).

Should Helix documentation and examples include the project-per-layer approach?

@cardinal252

This comment has been minimized.

Copy link

@cardinal252 cardinal252 commented Nov 9, 2018

I think single project per tier is the worst possible idea and should be heavily advised against, it promotes rigidity. It also systematically destroys any ability to bundle / reuse / deploy most. By adding it here, I think you would be promoting a worse practice on an already not great practice (tiered architecture)

@asmagin

This comment has been minimized.

Copy link

@asmagin asmagin commented Nov 10, 2018

Let's start from the fact that there is no nice way to create versioned package that will deliver content, backend and frontend parts of a Helix module to Sitecore and VS solution.

You referring to a project, not to a specific version of a feature NuGet or an Npm module. Project per layer or granular one, you will end up building all at once. (Reuse-Release equivalent)

Having multiple solution files can introduce problems to sibling solutions, as you are not building them, but updating common dependencies.

Common Closure cannot be applied without a context, if you building one site - all its parts will be in common closure. It doesn't mean that you can build it replacing layer projects with namespaces and do not have tight coupling between classes.

@TwentyGotoTen

This comment has been minimized.

Copy link

@TwentyGotoTen TwentyGotoTen commented Nov 10, 2018

I'm in favour of additional demo sites with alternative solution structures. Primarily because there's so much Habitat cargo culting going on. Many people think the Habitat structure is the only way it can be done. In my opinion, having multiple differing examples to compare and constrast, can only deepen people's appreciation of the underlying principles.

Uncle Bob might put equations in his examples, but this stuff is defintely an art not an exact science. By being too hardline, you could run the risk of turning some people off completely. As far as I'm concerned, the more diverese examples that broadly follow the packaging principles, the better. Each example will have its strengths and weaknesses. The best thing you can do is simply point them out and then allow people to make an informed decision on the best approach for their circumstances.

@simonproctor

This comment has been minimized.

Copy link

@simonproctor simonproctor commented Nov 10, 2018

@TwentyGotoTen the trouble is that this structure is now all but de facto standard and is being pushed very hard commercially. So you can argue that its already become quite rigid as you're going against Sitecore if you don't follow it.

@dthunziker

This comment has been minimized.

Copy link

@dthunziker dthunziker commented Nov 11, 2018

+1 - I would like to see some real world examples of a three project solution (Feature, Foundation, Project), using Folders for modules within each layer, and tooling to prevent mismanagement of dependencies.

@lakesol

This comment has been minimized.

Copy link

@lakesol lakesol commented Nov 12, 2018

I have no ideological issues with the current project-per-module approach. However I do have tooling concerns. VS is dying under the strain when the number of projects gets high. However the approach does lend itself well to enforcing the dependency rules. In a project-per-layer approach I can see people "bending" the feature-feature referencing rules pretty quickly (and silently).

@cassidydotdk

This comment has been minimized.

Copy link

@cassidydotdk cassidydotdk commented Nov 13, 2018

@TwentyGotoTen the trouble is that this structure is now all but de facto standard and is being pushed very hard commercially. So you can argue that its already become quite rigid as you're going against Sitecore if you don't follow it.

This is indeed a problem. But it lies with how Helix is being interpreted and applied from within the Sitecore organisation - not so much a discussion for, how we define and describe it.

@cassidydotdk

This comment has been minimized.

Copy link

@cassidydotdk cassidydotdk commented Nov 13, 2018

I have no ideological issues with the current project-per-module approach. However I do have tooling concerns. VS is dying under the strain when the number of projects gets high. However the approach does lend itself well to enforcing the dependency rules. In a project-per-layer approach I can see people "bending" the feature-feature referencing rules pretty quickly (and silently).

I'm one of the advocates for fewer projects. I've seen what these 150+ solutions do to developer productivity, it's just completely bonkers to be this rigid about it.

I don't think it's any harder to slip a project-to-project reference into a traditional Habitat-style build than it is to slip a cross namespace reference into a feature-bundle-project approach. I've used the latter for a while now, and your review process will catch both instances just the same. If you have no review process well that's on you.

Also, there are FxCop rules that could be applied to help enforce these boundaries, for the lazy ;-)

@cassidydotdk

This comment has been minimized.

Copy link

@cassidydotdk cassidydotdk commented Nov 13, 2018

I think single project per tier is the worst possible idea and should be heavily advised against, it promotes rigidity. It also systematically destroys any ability to bundle / reuse / deploy most. By adding it here, I think you would be promoting a worse practice on an already not great practice (tiered architecture)

I don't think anyone specifically mentioned "just one project per tier". I think of this more like "Feature Bundles" - so having a handful of related components stacked together in one project - rather than split up into 8 (16 if you're TDS'ing).

To me, this is basically a proposal to try and break away from the idiotic rigidity of Habitat, with a gazillion projects and a pipe dream "Architecture over tools" statement to make all the pain go away.

@simonproctor

This comment has been minimized.

Copy link

@simonproctor simonproctor commented Nov 13, 2018

It does appear that part of this structure is to enforce per project publishing as that allows for micro feature deployments. But then enforcing physical boundaries rather than anything namespace based. I'd rather live with a full deployment of the solution and have a better design with cross cutting concerns handled and layered correctly.

I agree code review should catch boundary concerns and I myself bundle projects and code by logical grouping. That can be nuget, namespace or project boundaries.

How many projects you have should always be answered by - as many as we thought we needed. If the design is solid, it'll make sense for the work you're doing, it'll be responsive to refactoring and design changes and new devs will pick it up quickly.

@lakesol

This comment has been minimized.

Copy link

@lakesol lakesol commented Nov 13, 2018

I have no ideological issues with the current project-per-module approach. However I do have tooling concerns. VS is dying under the strain when the number of projects gets high. However the approach does lend itself well to enforcing the dependency rules. In a project-per-layer approach I can see people "bending" the feature-feature referencing rules pretty quickly (and silently).

I'm one of the advocates for fewer projects. I've seen what these 150+ solutions do to developer productivity, it's just completely bonkers to be this rigid about it.

I don't think it's any harder to slip a project-to-project reference into a traditional Habitat-style build than it is to slip a cross namespace reference into a feature-bundle-project approach. I've used the latter for a while now, and your review process will catch both instances just the same. If you have no review process well that's on you.

Also, there are FxCop rules that could be applied to help enforce these boundaries, for the lazy ;-)

@cassidydotdk I dont disagree with that. I was not saying we should stay with the 1 project-per-module approach. Just that my (main) objections to it are around the tooling issues which means that large solutions become onerous to work on. I agree something needs to change.

Maybe we need to consider a wider grouping when putting modules together in one assembly. Experience tells me that whilst the theory is that standard modules can be shared over multiple projects, the reality is that in the world of enterprise websites, much of the code is bespoke to create brand differentiation. So maybe we should be looking at a base grouping of modules for a solution, then split out modules which are specifically designed for multi solution reuse.

So, lets say we have a set of custom calls to action components and some product components which are in reality quite tied to the specific customer solution, these could be grouped into one project. However if we then create a grid component which can span customers, these should be more granular in grouping to facilitate multi solution reuse.

@simonproctor

This comment has been minimized.

Copy link

@simonproctor simonproctor commented Nov 13, 2018

Speaking for my own designs -> Core, Services, Presentation and Web are the layers I go for. That may be four projects or it may be 12. For some large sites we've reached 20-30 projects but thats because we wanted to have a physical boundary for some of our modules (Core.Modules.XYZ, Core.Cms.Modules.ABC) so we could maintain and re-use separately.

We still deploy as one unit most of the time and only have one place where we ship any content changes. So one location for unicorn.

What I do want to see regardless of what solution structure you use is people using the user defined folder inside /sitecore/templates. Its there for custom templates yet its never really come up as a best practise when it really is. Ok - maybe that's a pet peeve.

@nickwesselman

This comment has been minimized.

Copy link
Collaborator Author

@nickwesselman nickwesselman commented Nov 13, 2018

@simonproctor

It does appear that part of this structure is to enforce per project publishing as that allows for micro feature deployments.

This is actually explicitly stated as not a goal of Helix:

The modular architecture - as exposed through Helix - is not to be confused with a modular deployment model ... In Helix – as with development and Sitecore generally – it is highly recommended to follow a strict develop, test and deploy lifecycle for the whole application.

https://helix.sitecore.net/devops/deployment/strategy.html

However I have seen cases where it is successfully used this way, and it's probably worth a mention in the docs. It requires much more disciplined and advanced CI, deployment, and versioning practices though, especially if you start pulling off modules into reusable packages. This is all worth a discussion in #12.

@nickwesselman

This comment has been minimized.

Copy link
Collaborator Author

@nickwesselman nickwesselman commented Nov 13, 2018

@simonproctor

What I do want to see regardless of what solution structure you use is people using the user defined folder inside /sitecore/templates

Actually in 9.1, the Helix layer folders exist out of the box as children under /sitecore/templates, and the User Defined folder is really only there for backwards compatibility.

@simonproctor

This comment has been minimized.

Copy link

@simonproctor simonproctor commented Nov 13, 2018

@nickwesselman well I did qualify that as a pet peeve! I think it also illustrates how easy it is to conflate helix and habitat as a reference implementation for helix, so for that confusion I apologise :).

However, offering a few extra folders to encourage the helix structure isn't really necessary. What does it offer?

@nickwesselman

This comment has been minimized.

Copy link
Collaborator Author

@nickwesselman nickwesselman commented Nov 13, 2018

@simonproctor

However, offering a few extra folders to encourage the helix structure isn't really necessary. What does it offer?

It not only encourages Helix structure (which is a big benefit), it also ensures that all modules and solutions use the same ID's for these folders. 9.1 ships with the same folder ID's that SXA has been using for some time.

@lakesol

This comment has been minimized.

Copy link

@lakesol lakesol commented Nov 14, 2018

@simonproctor

However, offering a few extra folders to encourage the helix structure isn't really necessary. What does it offer?

It not only encourages Helix structure (which is a big benefit), it also ensures that all modules and solutions use the same ID's for these folders. 9.1 ships with the same folder ID's that SXA has been using for some time.

Having the same base IDs can only be a good thing when adopting modules from 3rd parties or over multiple projects, so I fully endorse that idea.

@cardinal252

This comment has been minimized.

Copy link

@cardinal252 cardinal252 commented Nov 14, 2018

@lakesol @nickwesselman I fully do not agree. I am unsure why as an application vendor Sitecore feels the need to push such a fussy and opinionated architecture upon developers, doubly so when it comes to supplying said fussy & opinionated architecture out of the box. Sitecore has always been proud of it's flexibility and developer focus and this kind of behaviour (especially black marks against solutions that do not adopt Sitecore's naming convention) is an issue that should really not exist.

Helix in my opinion is badly flawed as an approach to developing Sitecore solutions in several areas. I (as do many developers - the likes of @simonproctor and @cassidydotdk) have had many Sitecore solutions that, over the years have also proven their design and flexibility without the need to focus on the names which our teams chose. This is not even considering the fact that the helix names do not make sense - Foundation - ok, sure, Feature - some specific functionality, Project - wtf is this - surely it would be project wide?? What happened to industry wide conventions like 'Presentation'? And also not withstanding that something as simple as considering what order configurations would apply was not though out. I don't see this behaviour from other vendors including many Sitecore competitors.

Naming conventions do not a good architecture make.

If you insist as a vendor on this behaviour - sort Habitat out and put it in there, not in the product. This approach may have worked for it's original designers, but it's not an approach I would want to adopt in my Sitecore solutions.

@cassidydotdk

This comment has been minimized.

Copy link

@cassidydotdk cassidydotdk commented Nov 14, 2018

To followup on @cardinal252's comment; I don;t believe anywhere in Helix is stated that these folders must be named verbatim as such. And if it does, that I feel is most definitely a thing that must be amended. Even @Eldblom himself has begun taking about an "Infrastructure Layer". We'll see more nonsense when "Commerce" and other projects start taking part.

Having them in the core product makes no sense at this stage. If we really want to do something meaningful about what ships in core or not - I think it's a completely different conversation we need to be having.

https://twitter.com/cassidydotdk/status/1061961864912035841

@cassidydotdk

This comment has been minimized.

Copy link

@cassidydotdk cassidydotdk commented Nov 14, 2018

Besides; how is forcing names like "Foundation", "Feature" and "Gobbligook" any different from those nightmare solutions we still see everywhere; with a "Company.Project.Domain" and "Company.Project.Models" projects. Going further back, these were the "Company.Project.DAL" and "Company.Project.BLL" projects - where the BLL one was always near empty.

We should organise by function. This is something I know Helix states.

So /sitecore/templates/modules/... and then ../Carousel/Views, ../Carousel/Renderings

Distinguishing where said Carousel lives is pointless. During the project, I still advocate putting stuff like this out front - "project layer" if you will. It doesn't become a feature until someone triples the development effort and makes it reusable from the project layer - something pretty much no projects actually need.

@cassidydotdk

This comment has been minimized.

Copy link

@cassidydotdk cassidydotdk commented Nov 14, 2018

and I'll get back to work now. But discussing "Architecture" and then folder names, project groupings... I mean think about it ;-)

@cardinal252

This comment has been minimized.

Copy link

@cardinal252 cardinal252 commented Nov 14, 2018

@cassidydotdk Completely agree - my architecture design follows this principle too. The majority of presentation (for example) in a site is difficult at best to reuse effectively, and quicker to live with duplicated (since even the most basic of presentation - a CTA or something) will invariably diverge between sites. Forcing developers to make decisions constantly on something that might in the future if you make it so generic and abstract that it is unreadable causes little but confusion & analysis paralysis. Split when you prove there is a need (for me the need starts on a per site level), and when you feel you can deploy things in isolation.

@asmagin

This comment has been minimized.

Copy link

@asmagin asmagin commented Nov 14, 2018

@cardinal252 @cassidydotdk naming conventions and cache invalidation are two the most difficult problems in architecture and this conversation proves at least the first part :)
I agree that architecture should be driven by solution and general design principles, not by naming convention.
Decision about reuse and separation should be done by the architect/developer, and should not be forced by naming convention.
If you are building another SXA you may want to break it to small components and even version them separately. If it is one site, such approach can complicate development significantly.

Also, dotNet Core is coming (how fast is a question) and it will take apart CMS core to smaller service. Most likely you will be forced to organize projects per service you are extending.

@nickwesselman

This comment has been minimized.

Copy link
Collaborator Author

@nickwesselman nickwesselman commented Nov 14, 2018

I think things are getting a little off topic here. Some related issues:

#20 - More Focus on Core Principles of Helix (Modular Architecture / Standard Conventions)
#24 - Renaming the Project Layer
#12 - Deployment / CI Guidance (including modular deployment)
#23 - Multi-site and Project-layer HTML (site-specific Presentation)

Clearly everyone in this discussion knows how to create a maintainable modular architecture, and clearly there are alternative approaches, but anecdotal and survey evidence show the majority of the community supports the basic approach, and Sitecore will continue to encourage its use, including building in the conventions to 9.1 (being released imminently). You are welcome to your opinion but the baby is not going to be thrown out with the bathwater.

I appreciate the enthusiasm but please keep further comments here related to alternate Visual Studio structures for the existing Helix layers / naming conventions.

@cardinal252

This comment has been minimized.

Copy link

@cardinal252 cardinal252 commented Nov 15, 2018

Understood - with respect to alternate visual studio structures showing example helix implementations, I still maintain the view that if it exists here it will be considered an accepted or best practice and should not be shown. Regardless of personal opinion on the 'architecture' - if Sitecore are going to enforce an approach (for my mind) they should fix Habitat and make it an ACTUAL starter kit, rather than approach it in another way.

@TwentyGotoTen

This comment has been minimized.

Copy link

@TwentyGotoTen TwentyGotoTen commented Nov 15, 2018

A common complaint from those who don't like Helix is that it's too rigid and prescriptive, forcing them to work in ways that they would prefer not to.
With that in mind, it seems to me that having a variety of demo solution structures would be very useful. It would help to show that Helix doesn't want to control every part of your life and that there's plenty of room for pragmatic descision making.
Of course there's a challenging balance to be struck. The various solution structures would need to be different enough to demonstrate the flexibilty of Helix as an approach, while still retaining the key important aspects in common.

@cardinal252

This comment has been minimized.

Copy link

@cardinal252 cardinal252 commented Nov 15, 2018

As an alternative view point, not withstanding the (I believe) prescriptive and rigid nature of its naming conventions, helix is still an n-tier architecture at its heart (something Microsoft themselves denounced years ago). if you take the naming away, it is a thin veneer on an interpretation of Uncle bob principles - which is still at the heart of most of the proposed alternatives. In a similar vein. If you have never read uncle bob's books - I am sure helix is a revelation, and I would potentially agree - better than nothing. If you have (and have read the helix documentation and had helix trainers and lovers explain to you exactly what helix is and does, implemented solutions on helix principles and STILL don't believe its the right solution, then its not for you)... My point still stands - helix is still relatively prescriptive and rigid in its documented form + whether you cut it as an n-project n-tier architecture or a 150 project n-tier architecture, that is not showing architectural flexibility, it is showing your ability to add / remove VS projects from VS solutions - something I would hope is within all .net developers grasp.

Furthermore, It is also not (as a reference implementation) showing deployment modularity in either case (ie: delivering bundles of functionality) which still in my mind makes it fussy and unwieldy.

So - keeping on track to the original question - should we show a 3 tier 3 project visual studio solution - I still believe the answer is no. I think that the reference implementation should be improved upon and stuck with if that is a tack.

@vitaliitylyk

This comment has been minimized.

Copy link

@vitaliitylyk vitaliitylyk commented Nov 21, 2018

I think it definetely makes sense to add an example of the project-per-layer setup (and hybrid approach, with project-per-module Foundation). Helix is all about logical boundaries, while VS projects define physical boundary. And if you are not versioning/deploying your Helix modules separately, most often there is no need in creating this physical boundary.

There is a nice post on this topic: https://codurance.com/2015/03/23/multiple-projects-in-visual-studio/

@dsolovay

This comment has been minimized.

Copy link
Contributor

@dsolovay dsolovay commented Nov 30, 2018

I think showing multiple approches, and discussing the pros and cons of each, and when each would do best, would give the document useful depth, and make it less prescriptive.

  • Project boundaries, best for governance, heavy to manage.
  • Project per layer, lighter, but harder for governance.
  • NuGet for (some) modules, in the following scenarios ...
  • Multiple solution files, to provide different "views" of the implemetation.
@cassidydotdk

This comment has been minimized.

Copy link

@cassidydotdk cassidydotdk commented Dec 2, 2018

One thing that never really comes up in these talks. Team size. Because in my experience - more than any other factor - the size of team or even the number of teams working on the solution, determines how I approach granularity. And how I split up the architectural boundaries.

I feel it is lost on many, that you need to be in a pretty enterprisey type of project for a setup heavily weighted towards the bottom (Foundation) is even worth the effort. And the overhead you need to incur to manage projects of this scale, is way overkill for the typical Sitecore project which involves no more than a handful of developers.

@nickwesselman

This comment has been minimized.

Copy link
Collaborator Author

@nickwesselman nickwesselman commented Mar 26, 2019

This is obviously an issue with strong opinions on both sides. For the sake of completeness, alternate structures should be discussed in Helix docs and examples, with the necessary caveats/warnings.

nickwesselman added a commit that referenced this issue Oct 29, 2019
nickwesselman added a commit that referenced this issue Oct 29, 2019
nickwesselman added a commit that referenced this issue Oct 31, 2019
[#21] fixed typo in Alternate Solution Structures title!
nickwesselman added a commit that referenced this issue Oct 31, 2019
[#21] added additional TDS consolidation option from @nsgocev
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants
You can’t perform that action at this time.