简体   繁体   English

我可以使用全局过滤器处理不同的多租户吗?

[英]Can I handle different multi-tenancy with a global filter?

I have an asp.net mvc app which has membership implemented. 我有一个实现成员身份的asp.net mvc应用程序。 So a user has to log in. Each user belongs to a organisation (multi-tenancy). 因此,用户必须登录。每个用户都属于一个组织(多租户)。

How would I handle the organisation parameter globaly? 我将如何全局处理组织参数? I was thinking this could be a good thing for a global filter because all the data needs to be filtered for the given organisation. 我当时认为这对于全局过滤器可能是一件好事,因为对于给定的组织,所有数据都需要过滤。 And the organisation is connected with the username but not in the same table. 并且该组织与用户名关联,但不在同一表中。

for example I have a index action like this 例如我有这样的索引动作

public ActionResult Index()
{
var result = _repository.GetListByOrganisation(organisation);
return View(result);
}

I was thinking about having a global attribute thats queries the db for an organisation based on a giving username. 我正在考虑具有一个全局属性,该属性根据给定的用户名查询数据库中的组织。 Since my controller already contains the authorize attribute I have the user name. 由于我的控制器已经包含authorize属性,因此我具有用户名。 It would be nice to cache the organisation (session, controllercontext) and not query the organisation from db on each request. 最好缓存组织(会话,controllercontext),而不是在每次请求时都从db查询组织。

Is this a way to implement something like this? 这是实现这种方式的一种方法吗? Or are there other ways which would be better? 还是还有其他更好的方法? And how can I set a property on the controller / controllercontext from whithin a filter? 以及如何通过过滤器在controller / controllercontext上设置属性?

So any thoughts on this as well as comments would be great... 因此,对此的任何想法以及评论都是很棒的...

I would do this via DI. 我会通过DI来做到这一点。

You can use either a third-party DI container or your own code. 您可以使用第三方DI容器或您自己的代码。 Either way, you want to set the organization ID on a per-request basis. 无论哪种方式,您都希望基于每个请求设置组织ID。

So you'll be creating a unit of work and injecting that in your controller. 因此,您将创建一个工作单元并将其注入到控制器中。 For the sake of simplicity, let's pretend that your unit of work is the _repository field in your sample code, even though most real-world apps are more complex. 为了简单起见,我们假设您的工作单元是示例代码中的_repository字段,即使大多数现实世界中的应用程序更为复杂。

You add a constructor parameter to the controller: 您向控制器添加构造函数参数:

public FooController(IFooRepository repository)
{
    this._repository = repository;
}

...and an organization ID on FooRepository : ...以及FooRepository上的组织ID:

public class FooRepository: IFooRepository
{
    public FooRepository(long organizationId)
    {
        this._organizationId = organizationId;
    }
}

Now in either your DI container setup or a MVC controller factory, you set this all up: 现在,在您的DI容器设置或MVC控制器工厂中,您都需要进行以下设置:

builder.Register(c => new FooRepository(GetOrgIdForCurrentUser()).As<IFooRepository>();
builder.Register(c => new FooController(c.Resolve<IFooRepository>());

Perhaps you could have the organization embedded on the URL, for example if your route looks like this /{organization}/{controller}/{action} 也许您可以将组织嵌入到URL中,例如,如果您的路由看起来像是/ {organization} / {controller} / {action}

then you'll get URLs like 那么您将获得如下网址

  • /bigorg/products/list / bigorg / products / list
  • /smallorg/products/list / smallorg / products / list

and you'll receive the organization in your controller either a parameter to your method or via the RouteData object. 然后您将在控制器中通过方法的参数或通过RouteData对象接收组织。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM