Open Closed

Architectural question on whether to choose Multi Tenancy or not #1084


User avatar
0
Sturla created

Hi, I have tried to read everything on abp.io multi-tenancy (github/discussions/formums) but I´m unsure what route I should take and would like some guidance on how to start the project the correct way.

Scenario: "We give 3party entities access to use our portal and they sell their material back to others (clients)"

  • We offer access to entities (companies/teams/etc) to our portal/framework for a fee (and cut per usage)
  • Entities use the portal for their own material and sell access to it
  • Entities have different users/roles (admin/bookkeeping/agenda/etc)
  • Entities need to be able to do some basic CRM stuff and have access to usage and monetary reports
  • Entities can manage their "subdomain" www.entity.ourPortal.com (or www.ourPortal.com/entity)
  • Clients (random people) can sign-up and pay for access to entities material
  • Logged in client can access material from every entity and pay/subscribe to it.
  • Clients should not need to explicitly choose tenants when logging in. They should be able to login once and browse (and pay for) all material from other tenants
  • We have system-wide settings (look and feel, blog, reports, disable tenants, etc)
  • We distribute fees (money) back to entities based on amount of usage by clients

So my question is basically what architecture approach should we choose based on our requirements and abp.io capabilities? What is possible and/or best approach and/or do you have examples (that attempt to do something similar) for us?

I hope I made myself clear enough, and what my requirements are. If not just shoot back.

  • ABP Framework version: v4.2.2 (or newer since I havent started)
  • UI type: Blazor
  • DB provider: EF Core
  • Identity Server Separated: yes

10 Answer(s)
  • User Avatar
    0
    alper created
    Support Team Director

    These 2 requirements force your architecture as multi-tenant:

    • Entities can manage their "subdomain" www.entity.ourPortal.com (or www.ourPortal.com/entity)
    • Entities have different users/roles (admin/bookkeeping/agenda/etc)

    Otherwise I would say you don't need multitenancy. On the other hand, you need 2 different setups: a public front facing website and backoffice (management) website.

    The products can be non-multitenant (otherwise clients cannot reach them). And you can filter the products manually as per your tenants (entities). (for managing products)

    Clients can be normal IdentityUser (AbpUser). They can access products without any issues.

    In exceptional cases you might need to access to your tenant's data, in this case you can switch to a tenant. this is possible with this code

    For the backend you can use MVC or Blazor (doesn't matter) For the front-facing side you should use MVC (for SEO friendliness).

    I suggest you to make a prototype, an MVP before starting your real project. This will be good to foresee some potential future issues.

    And let me know how you implement this

  • User Avatar
    0
    Sturla created

    Thank you so much for this great answer! It has really helped me to scope the work that lies ahead and the tech I should choose. I will explore the path you suggest and do some MVP stuff next couple of days.

    After that, I'll mark this question answered and let you know what I decided to do.

  • User Avatar
    0
    alper created
    Support Team Director

    thank you Sturla

  • User Avatar
    0
    Sturla created

    Hi again!

    I did a MVP and settled on a multi-tenancy option but I didn't go into every detail and need some help with this comment

    Clients can be normal IdentityUser (AbpUser). They can access products without any issues.

    What I need to know is how do I separate the Client (ordinary user) from Tenant/Host? How can I show clients their menu items that are totally different from the Tentan ones? I have been having this discussion on github but remembered that I had asked this question and gotten this comment and now beleve the question belongs here.

    This is (I hope) the last puzzle to get my Beta out the door so I hope you can point me in the right direction with this.

    p.s I have a separate Identity Servar and have added the Account source module so I can modify it.

  • User Avatar
    0
    alper created
    Support Team Director

    how do I separate the Client (ordinary user) from Tenant/Host? How can I show clients their menu items that are totally different from the Tentan ones?

    ** This is done by ABP Framework, when you add a new menu item you can set it as Host or Tenant. You cannot customize the menu for a specific tenant. if you add a menu item as Tenant side, all tenants will be able access (if they grant access the related permission)

    ** Permissions can also be set for Host and Tenant (same as menu item)

    you can also check out Feature system. this is used to enable, disable or change the behavior of the application features on runtime.

  • User Avatar
    0
    Sturla created

    You are misunderstanding this.

    I´m trying to have different menu for a user that is not a Tenant and not Host.

    I´m the host and Tenants can register with my system and add content that ordinary users can enjoy (for payment to me that I then monthly dish out to Tentans). The ordinary users need to be able to view collection of content from all the tenants in the system.

    Did that explain it?

  • User Avatar
    0
    alper created
    Support Team Director

    then you can use "Role". create a new permission for the new menuItem (page) create a new Role for your customers Add the permission to this new role. set the role to your customers who are allowed to see that page.

  • User Avatar
    0
    Sturla created

    Ok I have been looking at this and mabe creating a role and asigning it to the user when he is created is the correct way about doing this.

    Here is a working sample for others to follow.

    Its still unclear if I should be using IDistributedEventHandler<EntityCreatedEventData<IdentityUser>> or IDistributedEventHandler<EntityCreatedEto<UserEto>>. Seemy question here.

    public class RegisteredUserHandler : IDistributedEventHandler<EntityCreatedEventData<IdentityUser>>, ITransientDependency
        {
            private readonly IPermissionManager permissionManager;
            private readonly IdentityUserManager identityUserManager;
    
            public RegisteredUserHandler(IPermissionManager permissionManager,IdentityUserManager identityUserManager)
            {
                this.permissionManager = permissionManager;
                this.identityUserManager = identityUserManager;
            }
    
            [UnitOfWork]
            public async Task HandleEventAsync(EntityCreatedEventData<IdentityUser> eventData)
            {            
                // Add the permission to the role
                await permissionManager.SetForRoleAsync("OrdinaryClientRole", "MyPermission.Client", true);
                
                // Add the user to the role. 
                await identityUserManager.AddToRoleAsync(eventData.Entity, "OrdinaryClientRole");
            }
        }`
    

    I will seed the role and add the permissions in one go like shown here.

  • User Avatar
    0
    alper created
    Support Team Director

    there maybe alternative ways but these are the ones that come to my mind

  • User Avatar
    0
    ServiceBot created
    Support Team Automatic process manager

    This question has been automatically marked as stale because it has not had recent activity.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 13, 2024, 06:09