پیاده سازی برنامههای چند مستاجری در ASP.NET Core
نویسنده: محمد رعیت پیشه
تاریخ: ۱۳۹۶/۰۶/۳۰ ۲۰:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
سناریویی را در نظر بگیرید که یک برنامه وب نوشته شده، قرار است به چندین مستاجر (مشتری یا tenant) خدماتی را ارائه کند. در این حالت اطلاعات هر مشتری به صورت کاملا جدا شده از دیگر مشتریان در سیستم قرار دارد و فقط به همان قسمتها دسترسی دارد.
مثلا یک برنامه مدیریت رستوران را در نظر بگیرید که برای هر مشتری، در دامین
مخصوص به خود قرار دارد و همه آنها به یک سیستم متمرکز متصل شده و اطلاعات
خود را از آنجا دریافت میکنند.
در معماری Multi-Tenancy، چندین کاربر میتوانند از یک نمونه (Single
Instance) از اپلیکیشن نرمافزاری استفاده کنند. یعنی این نمونه روی سرور
اجرا میشود و به چندین کاربر سرویس میدهد. هر کاربر را یک Tenant
مینامیم. میتوان به Tenantها امکان تغییر و شخصیسازی بخشی از اپلیکیشن
را داد؛ مثلا امکان تغییر رنگ رابط کاربری و یا قوانین کسبوکار، اما آنها نمیتوانند
کدهای اپلیکیشن را شخصیسازی کنند.
PM> Install-Package SaasKit.Multitenancy
public class AppTenant
{
public string Name { get; set; }
public string[] Hostnames { get; set; }
} public class AppTenantResolver : ITenantResolver<AppTenant>
{
IEnumerable<AppTenant> tenants = new List<AppTenant>(new[]
{
new AppTenant {
Name = "Tenant 1",
Hostnames = new[] { "localhost:6000", "localhost:6001" }
},
new AppTenant {
Name = "Tenant 2",
Hostnames = new[] { "localhost:6002" }
}
});
public async Task<TenantContext<AppTenant>> ResolveAsync(HttpContext context)
{
TenantContext<AppTenant> tenantContext = null;
var tenant = tenants.FirstOrDefault(t =>
t.Hostnames.Any(h => h.Equals(context.Request.Host.Value.ToLower())));
if (tenant != null)
{
tenantContext = new TenantContext<AppTenant>(tenant);
}
return tenantContext;
}
} public void ConfigureServices(IServiceCollection services)
{
services.AddMultitenancy<AppTenant, AppTenantResolver>();
} public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// after .UseStaticFiles()
app.UseMultitenancy<AppTenant>();
// before .UseMvc()
} public class HomeController : Controller
{
private AppTenant tenant;
public HomeController(AppTenant tenant)
{
this.tenant = tenant;
}
} @inject AppTenant Tenant;
<a asp-controller="Home" asp-action="Index">@Tenant.Name</a>
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel --server.urls=http://localhost:6000;http://localhost:6001;http://localhost:6002",
}, dotnet run
از آنجائیکه نوشتن مشخصات مستاجرها در کد زیاد جالب نیست، برای همین
تصمیم داریم که این مشخصات را با استفاده از قابلیتهای ASP.NET Core از
فایل appsettings.json دریافت کنیم. تنظیمات مستاجرها را مطابق اطلاعات زیر به این فایل اضافه کنید:
"Multitenancy": {
"Tenants": [
{
"Name": "Tenant 1",
"Hostnames": [
"localhost:6000",
"localhost:6001"
]
},
{
"Name": "Tenant 2",
"Hostnames": [
"localhost:6002"
]
}
]
} public class MultitenancyOptions
{
public Collection<AppTenant> Tenants { get; set; }
} services.Configure<MultitenancyOptions>(Configuration.GetSection("Multitenancy")); public class AppTenantResolver : ITenantResolver<AppTenant>
{
private readonly IEnumerable<AppTenant> tenants;
public AppTenantResolver(IOptions<MultitenancyOptions> options)
{
this.tenants = options.Value.Tenants;
}
public async Task<TenantContext<AppTenant>> ResolveAsync(HttpContext context)
{
TenantContext<AppTenant> tenantContext = null;
var tenant = tenants.FirstOrDefault(t =>
t.Hostnames.Any(h => h.Equals(context.Request.Host.Value.ToLower())));
if (tenant != null)
{
tenantContext = new TenantContext<AppTenant>(tenant);
}
return Task.FromResult(tenantContext);
}
} اولین قدم در پیاده سازی یک معماری multi-tenant، تصمیم گیری درباره این
موضوع است که شما چطور مستاجر خود را شناسایی کنید. به محض این شناسایی شما میتوانید عملیاتهای بعدی خود را مثل تفکیک بخشی از برنامه، فیلتر کردن دادهای، نمایش یک view خاص برای هر مستاجر و یا بازنویسی قسمتهای مختلف
برنامه بر اساس هر مستاجر، انجام دهید.
_ سورس مثال بالا در گیت هاب قابل دریافت میباشد.
_ منبع: اینجا