CHAPTER 12
The framework classes that we used in the examples are:

And their common implementations:

All of the tenant identification strategies presented in Chapter 3 have some pros and cons; some require some additional configuration, others only really apply to simple scenarios. Some of the criteria include:
You can use the following decision flow:

When choosing a tenant location (and registration strategy), you need to take into account these questions:
You need to weigh all of these constraints before you make a decision. The following picture summarizes this:

The two APIs presented, NHibernate and Entity Framework, support all of the data access strategies. In the end, I think the decisive factor is the level of isolation that we want: separate databases offer the highest level, and data partitioning through discriminator columns offers the lowest. Criteria might include:

As for the APIs themselves, there will be probably some benefit in terms of ease of use with Entity Framework, but it all goes down to what the developer knows best, although it’s true that having separate schemas is slightly trickier with NHibernate. In any case, using an ORM seems a wiser decision than sticking with plain ADO.NET, because of all of the additional services that ORMs provide. Using the Generic Repository pattern to abstract away the data access API might be a good idea only if you do not need any of the API-specific features, and just stick with the least common denominator.
Even if you do not use custom performance counters, the built-in ones offer great tools when it comes to monitoring—and perhaps, billing—individual tenants. Some performance counters offer good insights on what’s going on, tenant-wise (you can select the sites to monitor independently):
You can view reports on some of these metrics, which can help you make decisions or serve as a billing basis:

It is even possible to add alerts to be triggered when certain values exceed their normal thresholds:

This example shows a rule for generating an alert for when the Managed Memory Used (estimated) metric of the ASP.NET Applications counter exceeds 1,000,000, for the _LM_W3SVC_1_ROOT site (abc.com) which is evaluated every 15 seconds.
If you need to support different layouts per tenant, make sure you follow modern guidelines for defining the markup of your pages; namely, enforce a strict separation between content (HTML) and layout (CSS) and use the proper HTML elements for organizing your contents. For example, do not use the Table element for layout or grouping contents, because it does not scale well and imposes limitations on what we can change.
Note: The CSS Zen Garden site offers fantastic examples on the power of CSS.