Multi-tenancy web application with filtered dbContext

前端 未结 2 1808
一向
一向 2020-12-28 23:47

I am new to ASP.Net MVC and multi-tenancy web application. I have done lots of reading, but being a beginner I just follow what I understand. So I managed to built a sample

相关标签:
2条回答
  • 2020-12-29 00:01

    NInject DI can do the magic !! Provided you will have a login routine which creates the session variable "thisTenantID".

    In the Web Layer:

    private void AddBindings()
    {
        //Modified to inject session variable
        ninjectKernel.Bind<EFDbContext>().ToMethod(c => new EFDbContext((int)HttpContext.Current.Session["thisTenantID"]));
    
        ninjectKernel.Bind<IAppUserRepository>().To<EFAppUserRepository>();
        ninjectKernel.Bind<IEmployeeRepository>().To<EFEmployeeRepository>().WithConstructorArgument("tenantID", c => (int)HttpContext.Current.Session["thisTenantID"]);
    }
    
    0 讨论(0)
  • 2020-12-29 00:23

    The way you have designed your repository follows a very clear design, but the parameter that you are passing in the constructor makes things a bit more complicated when using dependency injection.

    What I propose here below, is perhaps not the best design, but it will allow you to progress without doing too much changes to your existing code.

    The catch in this solution is that you have to call the "Initialise" method when creating the controller, which potentially you might not like, but it is quite effective.

    Here are the steps:

    • Create a new method in your IEmployeeRepository
    public interface IEmployeeRepository
    {
        //leave everything else as it is
        void Initialise(int tenantId);
    }
    
    • Implement that method in the EFEmployeeRepository
    public class EFEmployeeRepository
    {
        //leave everything else as it is
    
        public void Initialise(int tenantID = 0)
        {
            context = new EFDbContext(tenantID);
        }
    }
    
    • In the HomeController, you would need to call "Initialise" in the constructor
    public HomeController(IEmployeeRepository empRepository)
    {
        repoEmployee = empRepository;
        repoEmployee.Initialise(/* use your method to pass the Tenant ID here*/);
    }
    

    An alternative to this approach could be to create a RepositoryFactory that would return the Repository filled out with all the filters you need. In that case you will inject the Factory rather than the Repository to the Controller.

    0 讨论(0)
提交回复
热议问题