Skip to main content

Considerations for Multi-Client Applications

Often when dealing with applications/systems that serve multiple clients, we encounter a situation where

  • Clients share some core functionality and algorithms
  • Clients have custom logic that extends the core functionality
  • Clients have customized data structures that extend core data structures
The key to making this work in a maintainable way (that is, without infusing the code with crazy branching statements or writing the whole application in dynamic SQL) is maintaining a distinct separation between core and client.

Here I present components from a simple, hypothetical application that demonstrates such a separation. The application is meant to evaluate whether or not a client should acquire a player for fantasy football. It contains some core functionality for doing the evaluation (it doesn't pick up a player who has never scored a point) and a core data structure that represents a player. There are two clients who extend this core functionality: me and a stupid opponent in my league. The stupid opponent is a Bears fan who only picks up Bears players. I am a player who uses some trivial evaluation strategy and also extends the core data structure with some data that represents my own opinion.

The code shows an example of how to define and extend core functionality. It does not show how to wire everything together (dependency injection) or how to persist custom data. I may explore these topics in future posts. Also note that I called the code repository 'MultiTenancy', but this is more likely something you'll find in multi-instance scenario. I'm using the term 'multi-client' to represent both possibilities.

Comments

Popular posts from this blog

Stubbing Static Methods with PostSharp

TypeMock uses the Profiler API to allow mocking, stubbing, etc. of classes used by code under test. It has the ability to handle sealed classes, static classes, non-virtual methods, and other troublesome-yet-oft-encountered scenarios in the world of unit testing. Other frameworks rely on proxies to intercept method calls, limiting them to be able to only fake virtual, abstract, and interface members. They also rely on dependecy injection to place the proxies as the concrete implementation of calls to the abstracted interface members. Anyone working with a legacy codebase is bound to run into static method calls (especially in the data access layer), dependencies on concrete types with non-virtual methods, and sealed class dependencies (HttpContext anyone?). The only way to unit test this without refactoring is with TypeMock. I've never used TypeMock, and I'm sure it's a great product, but it's not free. I decided to spike some code to see if I could solve the prob...

Migrating Hg Repos with hg-fast-export and Windows Subsystem for Linux

Introduction I prefer Mercurial (hg) to git . I don’t really have any reason for this preference - they both do the same thing, and the user experience for 90% of the use cases is the same. It probably comes from the conditions of the DVCS landscape when I started using these systems. Some of this may have been perception only, but it looked like this: GitHub didn’t have free private repos BitBucket did have free private repos BitBucket was very hg-friendly Joel Spolsky had an amazing tutorial that served as both a how-to for hg as well as a general intro to DVCS hg was much more Windows-friendly than git Since hg was written in python, I felt like extending it would be easier than doing so for git if I ever needed to (admittedly, this is a pretty ridiculous reason) hg felt like a more unified, “coherent” system than the very linux-y feeling git and its extensions (also pretty ridiculous) Where they differed, I liked the verbs hg used better than git’s counterparts ...

Who I'm Is

I am a junior .NET developer currently working in Chicago, IL. I am starting this blog in order to enhance my knowledge of programming subject matter. Hopefully, someone else will be helped along the way. This first post will probably be edited soon...