Introducing SharedFlat

栏目: IT技术 · 发布时间: 5年前

内容简介:A multitenant web application is one that responds differently depending on how it is addressed (the tenant). This kind of architecture has become very popular, because a single code base and deployment can serve many different tenants.There are a few libr

Introduction

A multitenant web application is one that responds differently depending on how it is addressed (the tenant). This kind of architecture has become very popular, because a single code base and deployment can serve many different tenants.

There are a few libraries out there that help ASP.NET Core developers implement such architectures, but, since I wrote a book on ASP.NET Multitenant Applications a few years ago, I decided to write something from scratch for ASP.NET Core – and here is SharedFlat !

For the sake of the examples, let’s assume two tenants that correspond to two different domain names, abc.com ( abc ) and xyz.net ( xyz ).

Concepts

SharedFlatis available at GitHub and NuGet and you are free to have a look, fork and suggest improvements. It is still in early stages, mind you!

It was designed around the following key tenets:

What is a tenant?

A tenant is a unique entity, identified by a name, and the application must respond appropriately to in, in terms of:

  • User interface: each tenant may have one or more different UI aspects

  • Data: each tenant should have access to different data

  • Behavior: the application should behave (maybe slightly) differently, for each tenant

The current tenant is always returned by the implementation of the ITenantService interface:

public interface ITenantService
{
string GetCurrentTenant();
}

Simple, don’t you think? The returned tenant information is the tenant’s name (or code, if you prefer).

How do we identify a tenant?

Now, the first thing to know is, how do we identify the current tenant? Well, there are different strategies for this, but they all implement this interface:

public interface ITenantIdentificationService
{
string GetCurrentTenant(HttpContext context);
}

The strategies itself can be various:

  • Using the request’s HTTP Host header : useful for scenarios where we have multiple domains pointing to the same IP address and we want to distinguish the tenant by the requested host

  • Using a query string field: more for debugging purposes

  • Using the source IP of the request: for when we want to force IPs to be of a specific tenant

  • Static: for testing purposes only

  • Dynamic: when we decide in code, at runtime, what the tenant is

  • Some header’s value

Introducing SharedFlat

The ITenantService that we saw first will have to somehow delegate to one of these implementations for getting the current tenant. We need to register one implementation by using one of the following extension methods:

services.AddTenantIdentification()
.DynamicTenant(ctx => "abc.com")    //dynamic
.TenantForQueryString()             //query string
.TenantForSourceIP()                //source IP
.TenantForHost()                    //host header
.TenantForHeader()                  //some header
.StaticTenant("abc.com");           //static

Of course, only one of these methods ( DynamicTenant , TenantForQueryString , TenantForSourceIP , TenantForHost, TenantForHeader , StaticTenant ) should be called.

Some of these different strategies need configuration. For example, to map a host name to a tenant name, we use code like this:

services.AddTenantIdentification()
.TenantForSourceIP(options =>
{
options.Mapping.Default = "abc";
options.Mapping
.Add("192.168.1.0", "xyz")
.Add("10.0.0.0", "abc");
});

Some tenant identification services also expose an interface ITenantsEnumerationService , which allows listing all the known tenants (their name, or code). This service can be retrieved from the DI, but only if the registered identification service supports it:

public IActionResult Index([FromServices] ITenantsEnumerationService svc)
{
var tenants = svc.GetAllTenants();
return View(tenants);
}

Configuration per tenant

It is also very important to get different configuration depending on the current tenant. Almost all of the tenant identification strategies (except StaticTenantIdentificationService and DynamicTenantIdentificationService ) support a mapping between “something” and a tenant code. This “something” may be the source IP ( SourceIPTenantIdentificationService ), the request’s Host header ( HostTenantIdentificationService ), etc. There is a standard configuration section that you can add to your appsettings.json file:

{
"Tenants": {
"Default": "",
"Tenants": {
"xyz.net": "xyz",
"abc.com": "abc"
}
}
}

You can load the configuration using an extension method:

services.AddTenantIdentification()
.TenantForHost(options =>
{
Configuration.BindTenantsMapping(options.Mapping);
});

Or you can just set the values manually, as we’ve seen before.

If you want to set some per-tenant configuration, you should use the Options Pattern with a named configuration (one per tenant):

services.Configure<SomeClass>("abc", options =>
{
options.Foo = "bar";
});

And then you need to retrieve it like this:

public HomeController(IOptionsSnapshot<SomeClass> optionsSnapshot, ITenantService tenantService)
{
var tenant = tenantService.GetCurrentTenant();
var options = optionsSnapshot.Get(tenant);
//…
}

There is yet another option: you can have a class that implements ITenantConfiguration , which is defined as:

public interface ITenantConfiguration
{
string Tenant { get; }
void ConfigureServices(IConfiguration configuration, IServiceCollection services);
}

You can have one class per tenant and in there you can register services that are specific for it. In order for it to work, you need to call the AddTenantConfiguration extension method:

services.AddTenantIdentification()
.TenantForHost(options =>
{
Configuration.BindTenantsMapping(options.Mapping);
})
.AddTenantConfiguration();

Conclusion

This is all I have for now, stay tuned for more on SharedFlat !


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创新者

创新者

[美] 沃尔特·艾萨克森 / 关嘉伟、牛小婧 / 中信出版社 / 2017-4 / 88.00元

《创新者》是沃尔特·艾萨克森继全球畅销书《史蒂夫·乔布斯传》之后的又一部力作,不仅讲述了计算机和互联网从无到有的发展历程,为我们 生动地刻画出数字时代的创新者群像,还深度挖掘互联网的精神内核,解读了“诗意科学”这个重大主题。 在近200年的数字化进程中群星闪耀,艾萨克森从第一个计算机程序的创造者、浪漫主义诗人拜伦之女埃达•洛夫莱斯伯爵夫人说起,细数了这一群将科学与人文融合的创新者,他们包括第......一起来看看 《创新者》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具