I have a question. I am finally getting around to migrating over to the new release(which is awesome by the way!). I guess a quick recap of what I am doing:
I am splitting the context. I have a HostDbContext (inherits from AbpZeroHostDbContext) and an TenantDbContext (inherits from AbpZeroTenantDbContext). I am making the Host database strictly Hosts, if I am going to have a Shared database, it will not be in the Host DB. This makes Migrations much simpler IMO.
So, as I am making my changes, I come accross the AbpZeroDbMigrator. I notice this object that it inherits from will run migrations against both the Host and the Tenant databases but the class is only accepting one Context / Migration Configuration:
using Abp.Dependency;
using Abp.Domain.Uow;
using Abp.MultiTenancy;
using Abp.Zero.EntityFramework;
namespace MyPortal.Framework.EntityFramework
{
public class AbpZeroDbMigrator : AbpZeroDbMigrator<TenantDbContext, Migrations_Tenant.Configuration>
{
I changed this code to use just the TenantDbContext and the Tenant Migrations but this will only make the Create Tenant part of the system work. The Migrator console application needs to execute Migrator code for both the Host and the Tenant.
I am not sure what was intended for me to do here. Do I create a AbpTenantDbMigrator and AbpHostDbMigrator and modify the console application accordingly? I could implement another MultiTenantMigratorExecuter that would take in both Migrators....
Anyway, I am just looking for guidance. I sort of worked my way through what I thought you were intending me to do but there is not alot of guidance on using Multiple contexts, how to use the current migrations with both contexts, etc. I think you all need to come up with an example of using seperate DB's so we can see what you intended for us to do when using multiple contexts.
I will try and create a document on what I did. I would really like to know if I am doing everything "as intended". Once I get this part worked out, hopefully I can get that done.
Thanks!
Yes. That is exactly what we are doing. We are not touching any ABP or Zero files. We are just implementing our own controllers / modules / directives in TS.
What I did to do an example typescript controller, I copied there User list page into another folder and made a User list using TS. Once you dig in, it's not bad at all. If you just take the example walk-through they did and try and do that in Typescript, it will not be that bad. You will just find you need to declare some of the global variables they use. My post has a few in it. My post is a little vague, but if you just sit down and try and write a typescript controller in your own implementation, you will figure it out pretty quickly.
We are using Typescript in our project but we did not convert anything from the framework. We had to declare a few variables from abp and AspZero(just declared them as any), but overall the experience has not been too bad. I don't want to convert the framework because the more we touch the framework, the harder it is to merge changes that are released.
Here is the first part of our custom typings file for the project:
declare var App: any;
declare var app: any;
declare var abp: any;
declare var appModule: angular.IModule;
declare var _: any;
Those few declares have got us through several screens. You can see we were able to add a type to appModule. If there are things we can add types to as we go we usually add them in. I think the "_" var is from underscore.js, but we have not checked to see if we can download a typing for that yet.
Here is a look at one of our controller constructors and how we inject the common items:
//- Injects dependencies into the constructor. Used by Angular.
static $inject = ["$scope", "$uibModal", "$stateParams", "uiGridConstants", "abp.services.app.pbcSection", "framework.services.kendo.datasourceservice"];
constructor(
private $scope: angular.IScope,
private $uibModal: angular.ui.bootstrap.IModalService,
private $stateParams: Framework.Interfaces.IFilterTextStateParamsService,
private uiGridConstants: any,
private pbcSectionService: any,
private kendoDataSourceService: Framework.Services.Kendo.IDataSourceService) {
It would be nice if we had typed Services and DTO's. It would make the development experience a little nicer. I am strongly debating writing a T4 template that creates typings for our DTO / ApplicationServices. I think this would go a long ways to making the experience better.
Anyway, just wanted to pass along our strategy. We are only about a month into development so we are still learning.
Is it documented somewhere what I can remove from the web application if I want to do the SPA vs MPA? I would like to get rid of the MPA version to limit developer confustion. We removed Area, but I wanted to double check and make sure if there was anything else or I already got it wrong lol.
Thanks
Wow. I am impressed. I have a timeline of about end of July for my project. If you think it might be possible to have this implemented by then, that is more than awesome.
I agree with you, that implementation sounds awesome. The contexts and the settings were my hangups. You have some specific settings classes and I was thinking there needed to be some concept around Host settings. Basically, you will bring in the idea of a Host DB. Sounds very good!
And as far as the filter goes. In reality, you could remove the filtering from the code when you are in a Multi-DB environment, but in reality, I would almost be in favor of leaving it in. Let's say I have a trial version of the product, maybe I want to run some tenants on one database. Like you said, the code should not have to be aware of the "separation" of the Host and the Tenants.
Anything I can help with just let me know. I will gladly help, test, anything I can do I am here.
I am wondering if anyone has any experience in converting the framework to work with a database per tenant. With Azure Elastic DB coming out, this is a great way to architect a multi-tenant solution. Having worked with a very large Multiple-Tenant, Single Database before, I just can't see using this ever again. Very limited on what you can do to scale out. Not a fan of sharding. Of course, this is my preference and doesn't have to be everyone's, so choices are good!
<a class="postlink" href="https://channel9.msdn.com/Events/Build/2016/P522">https://channel9.msdn.com/Events/Build/2016/P522</a>
So, I am setting off on the journey to modify this to work with multiple databases. I am hoping some thought has been put into this by others and hoping to have a discussion about what it takes. I hope I can give back to the community with this. So, I don't mind doing some work here, but hoping I can get a little assistance with this to get started.
Here are my thoughts and I am curious to see if anyone else has thought about this or might make sure that my logic is correct:
Design
Changes that I see:
Any thoughts would be very helpful. I am sure you all have thought about this and any pointers would be helpful.