
فرض کنید یک سیستم بزرگ کنترل پروژه یا حسابداری یا مدیریت مشتریان قرار است به صفر تولید شود. در این موارد اصولن 2 روش معمول برای طراحی دیتابیس و سیستم وجود دارد.
1- همه مشتریان در یک دیتابیس بزرگ تجمیع شده و رکوردها توسط مثلن CompanyID یا TenantID یا مثلن CustomerID از همدیگر جدا میگردند.
2- جداسازی دیتابیس برای هم مشتری و انتقال مشتری یا به اصطلاح فنی همان ConnectionString به دیتابیس مورد نظر
من تمایلی به صحبت و پیاده سازی روش شماره 1 ندارم چرا که اگر بنا است سیستم زیر URL های مختلف به مشتری ارائه شود، استفاده از یک دیتابیس بزرگ و روبرو بودن با دریایی از رکوردهای متعلق به دیگران برای من مطلوب نیست و همیشه سبب دردسر بوده و خطرات خودش را نیز دارد. ضمنن مثلن اگر مشتری BackUP خودش را نیاز داشت، باید کوئری بزنم و با دردسر بسیار دیتاهای مشتریها را از هم جدا کنم. در نتیجه به بررسی روش دوم خواهیم پرداخت.
در روش شماره 2 که همان DataBase Level Multi Tenancy نامیده میشود ، مشتری برای خود دیتابیس و URL خودش را داد. مثلن فرض کنید سیستم ما به نام و زیر دامنه QuickERP.COM ثبت شده است. خوب هر مشتری یک SubDomain برای خودش دارد. یعنی آدرسهای مشتریان ما چیزی مشابه زیر است.
Iransystem.QuickERP.COM
Macdonald.QuickERP.COM
Kia.QuickERP.COM
خوب مشتریان من میتوانند مثلن 2000 تا باشند. تعداد اهمیتی ندارد. مشخص است که هر مشتری من یک دیتابیس برای خودش دارد که لزومن لازم نیست همنام Subdomain باشد، ولی من برای اینکه همه چیز مشخص تر باشد، از اسامی مشابه برای دیتابیسهایم استفاده میکنم، پس اسامی دیتابیسهای من اینگونه خواهد بود :
Iransystem
Macdonald
Kia
هر مشتری با استفاده از URL خودش نرم افزار ما را صدا میزند و همگی از یک Deployment ولی با دیتابیسهای مختلف استفاده میکنند. خوب حالا که همه چیز مشخص است، باید فقط آنچه شرح دادم را در ASP.NET 5 پیاده سازی کنیم..
برای پیاده سازی فنی چنین موضوعی ، 100 میلیون روش وجود دارد و نمیتوان گفت کدام از دیگری بهتر با بدتر است. من برای تسهیل این امر از یک Nuget package مجانی، سالم و قوی استفاده میکنم.
معرفی SaasKit.Multitenancy
از طریق استفاده از این افزونه و چند خط کد ساده برای DI به راحتی میتوانید Connection String های مختلف را در مثلن appsettings.json قرار دهید و بر اساس URL کاربر این Connection String صدا زده شده و سیستم به کار خودش ادامه خواهد داد.
خوب از اینجا دیگر صحبت کردن و فقط متن نوشتن دیگر فایده ای ندارد ،پس بهتر است یک پروژه بسازیم و همه چیز را در آن پیاده سازی کنیم. با نگاه کردن به آن پروژه ، همه چیز به راحتی مشخص میشود.
https://www.nuget.org/packages/SaasKit.Multitenancy/
مرحله یک : ایجاد نوع پروژه

مرحله دوم : نامگذاری پروژه

مرحله سوم : تعریف نوع پروژه در دات نت و ورژن دات نت

خوب پروژه را ساختیم. حالا اول از همه SaSSKit را به پروژه اضافه میکنیم

حالا Sasskit به پروژه ما افزوده شد

حالا یک Folder جدید به نام Infraبه پروژه اضافه میکنم. درون این فولدر فولدر دیگری به نام Tenant اضافه میکنم. هر آنچه برای Handle کردن Multi Tenancyنیاز دارم درون این فولدر قرار خواهد گرفت.
اولین آیتمی که نیاز دارم، یک Entity برای صدا زدن اجزای ConnectionStringدارم. اسم این Entity را AppTenant خواهم گذاشت.

کلاس دیگری به نام MultitenancyOptions نیز نیاز دارم به سادگی آنرا هم خواهیم ساخت

قسمت اصلی ماجرا ایجاد AppTenantResolverو Injectکردن آن در Startup.csیا همان MiddleWareاست و تقریبا تمام. شکل این کلاس به شکل زیر خواهد بود.

چون من بر اساس URL قصد دارم Connection Stringرا داشته باشم، باید URL را کمی در این فایل تمیز کاری کنم که مشابه تصویر بالا این کار انجام شده است. حالا به سراغ تنظیمات Startup.csمیرویم .
پس از Startup.cs ، فایل Appsettingرا هم تنظیم میکنم تا ConnectionString ها بر اساس URL استفاده شده توسط هر مشتری تنظیم شده باشد. حالا دیگر هرچقدر Repository و DBContextیا هرچه بسازید، وضعیت ConnectionString برای شما بر اساس URL درون Browserخواهد بود. در هر Request ، کانکشن مرتبط با URL از فایل Appsettingخوانده میشود و همه چیز مرتب است
میتوانید به جای Appsettings ، از هر جای دیگری هم کانکشن را بخوانید.
سورس را هم ZIP شده در کانال میگذارم تا حالش را ببرید.
موفق باشید...