Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good solution structure to allow easy customisation of a product on a per client basis?

I am looking for some advice on how to allow easy customisation and extension of a core product on a per client basis. I know it is probably too big a question. However we really need to get some ideas as if we get the setup of this wrong it could cause us problems for years. I don't have a lot of experience in customising and extending existing products.

We have a core product that we usually bespoke on a per client basis. We have recently rewritten the the product in C# 4 with an MVC3 frontend. We have refactored and now have 3 projects that compose the solution:

  • Core domain project (namespace - projectname.domain.*) - consisting of domain models (for use by EF), domain service interfaces etc (repository interfaces)
  • Domain infrastructure project (namespace -projectname.infrastructure.*) - that implements the domain service-EF Context, Repository implementation, File upload/download interface implementations etc.
  • MVC3 (namespace - projectname.web.*)-project that consists of controllers, viewmodels, CSS, content,scripts etc. It also has IOC (Ninject) handling DI for the project.

This solution works fine as a standalone product. Our problem is extending and customising the product on a per client basis. Our clients usually want the core product version given to them very quickly (usually within a couple of days of signing a contract) with branded CSS and styling. However 70% of the clients then want customisations to change the way it functions. Some customisations are small such as additional properties on domain model, viewmodel and view etc. Others are more significant and require entirely new domain models and controllers etc.

Some customisations appear to be useful to all clients, so periodically we would like to change them from being customisations and add them to the core.

We are presently storing the source code in TFS. To start a project we usually manually copy the source into a new Team Project. Change the namespace to reflect the clients name and start customising the basic parts and then deploy to Azure. This obviously results in an entirely duplicated code base and I’m sure isn’t the right way to go about it. I think we probably should be having something that provides the core features and extends/overrides where required. However I am really not sure how to go about this.

So I am looking for any advice on the best project configuration that would allow:

  • Rapid deployment of the code – so easy to start off a new client to allow for branding/minor changes
  • Prevent the need for copying and pasting of code
  • Use of as much DI as possible to keep it loosely coupled
  • Allow for bespoking of the code on a per client basis
  • The ability to extend the core product in a single place and have all clients gain that functionality if we get the latest version of the core and re-deploy

Any help/advice is greatly appreciated. Happy to add more information that anyone thinks will help.

like image 449
GraemeMiller Avatar asked May 03 '12 09:05

GraemeMiller


People also ask

What is the primary basis for customizing a product?

Customerization is the customization of products or services through personal interaction between a company and its customers. A company is customerized when it is able to establish a dialogue with individual customers and respond by customizing its products, services, and messages on a one-to-one basis.

Which system provides most flexibility for customization?

Understanding Flexible Manufacturing System (FMS) Flexible manufacturing can be a key component of a make-to-order strategy that allows buyers to order customized products.

What is product customization strategy?

Product customization is the process of delivering tailor-made products to customers based on their needs and expectations. This strategy is one of the most effective ways to promote customer experience and satisfaction.

What are the key success factors for mass customization to be truly effective?

Manufacturing and supply chainElicitation, process flexibility and logistics are three important elements in assessing a firms' readiness to implement a mass customization strategy with success. These elements are related to manufacturing, distribution and order management.


1 Answers

I may not answer to this completly, but here some advices:

  1. Don't copy your code, ever, whatever the reason is.
  2. Don't rename the namespace to identify a given client version. Use the branches and continuous integration for that.
  3. Choose a branching model like the following: a root branch called "Main", then create one branch from Main per major version of your product, then one branch per client. When you develop something, target from the start in which branch you'll develop depending on what you're doing (a client specific feature will go in the client branch, a global version in the version branch or client branch if you want to prototype it at first, etc.)
  4. Try the best to rely on Work Item to track features you develop to know in which branch it's implemented to ease merge across branches.

Targeting the right branch for you dev is the most crucial thing, you don't have to necessary define some hard rules of "what to do in which occasion", but try to be consistant.

I've worked on a big 10 years project with more than 75 versions and what we usually did was:

  • Next major version: create a new branch from Main, dev Inside
  • Next minor version: dev in the current major branch, use Labels to mark each minor versions Inside your branch.
  • Some complex functionnal features was developped in the branch of the client that asked for it, then reversed integrated in the version branch when we succeeded in "unbranded" it.
  • Bug fixes in client branch, then reported in other branches when needed. (you have to use the Work Item for that or you'll get easily lost).

It's my take on that, other may have different point of view, I relied a lot on the Work Item for traceability of the code, which helped a lot for the delivery and reporting of code.

EDIT

Ok, I add some thought/feedback about branches:

In Software Configuration Management (SCM) you have two features to help you for versionning: branches and labels. Each one is not better nor worst than the other, it depends on what you need:

  1. A Label is used to mark a point in time, using a label, for you to later be able to go back to that point if needed.
  2. A Branch is used to "duplicate" your code to be able to work on two versions at the same time.

So using branches only depends on what you want to be able to do. If you have to work one many different versions (say one per client) at the same time: there's no other way to deal with it than using branches.

To limit the number of branches you have to decide what will be a new branch or what will be marked by a label for: Client Specific Versions, Major Version, Minor Version, Service Pack, etc.

Using branches for Client versions looks to be a no brainer. Using one branch for each Major version may be the toughest choice for you to make. If you choose to use only one branch for all major versions, then you won't have the flexibility to work on different major versions at the same time, but your number of branches will be the lowest possible.

Finally, Jemery Thompson has a good point when he says that not all your code should be client dependent, there are some libraries (typically the lowest level ones) that shouldn't be customized per client. What we do usually is using a separated branch tree (which is not per client) for Framework, cross-cutting, low level services libraries. Then reference these projects in the per client version projects.

My advice for you is using Nuget for these libraries and create nuget package for them, as it's the best way to define versionned dependencies. Defining a Nuget package is really easy, as well as setting up a local Nuget server.

like image 91
Nock Avatar answered Oct 01 '22 19:10

Nock