使用 Ninject (ASP.NET MVC) 将会话变量注入 IService
Injecting a session variable into an IService using Ninject (ASP.NET MVC)
我有一个大小适中的 Web 应用程序,我想制作多客户端。所以现在我有一个用户 table,我的计划是向该 table 添加一个 ClientId 字段,然后我可以限制用户只能看到他们所属的客户端的数据。
在理想情况下,我想尝试将安全性设置在最低级别,这样就很难意外创建导致客户端看到另一个客户端数据的功能。因此,当我在控制器中使用服务时,不必每次都传递 clientId:
var messages = _messageService.GetMessagesByType(clientId, type);
它是自动的:
var messages = _messageService.GetMessagesByType(type);
我正在使用 Ninject 将我的服务注入控制器:
public static void RegisterTypes(IKernel kernel)
{
kernel.Bind<IMessageService>().To<MessageService>();
}
我目前的想法是将当前用户的 clientId 存储为会话变量,然后以某种方式将其注入 IServices,然后再在控制器中使用它们。
但是,我假设 RegisterTypes 方法在 App_Start 上被调用了一次,那么当一个动作被调用时我将如何注入它?还是有更好的方法来实现我想要实现的目标?
可悲的是,我对 web 开发和特别是 asp.net-mvc 知之甚少。但是,以下可能是您可以接受的解决方案:
(注意:我假设客户端 ID 的类型为 ClientId
。请参阅 here 了解原因。)
给定:
public class MessageService : IMessageService
{
public MessageService(ClientId clientId,...) {...}
...
}
您可以定义绑定:
kernel.Bind<IMessageService>().To<MessageService>
.WithParameter(new TypeMatchingConstructorArgument(
typeof(ClientId),
(ctx, target) => (ClientId)HttpContext.Current.Session["clientId"]));
将 HttpContext.Current.Session["clientId"]
的值注入 ClientId
类型的参数到 MessageService
的构造函数中。
除了 TypeMatchingConstructorArgument
,您还可以使用 ConstructorArgument
参数,它按参数名称而不是参数类型进行匹配。
现在更进一步,它也适用于其他服务,我们也可以简单地做:
kernel.Bind<ClientId>()
.ToMethod(ctx => ClientId)HttpContext.Current.Session["clientId"]);
kernel.Bind<IMessageService>().To<MessageService>();
注意:您可能需要考虑添加(到绑定)验证是否存在会话以及是否设置了 clientId。
另请注意:在实例化服务(= 由控制器或其依赖项之一请求)之前,您需要注意 clientId
实际上是已知的(放在会话中)。
我有一个大小适中的 Web 应用程序,我想制作多客户端。所以现在我有一个用户 table,我的计划是向该 table 添加一个 ClientId 字段,然后我可以限制用户只能看到他们所属的客户端的数据。
在理想情况下,我想尝试将安全性设置在最低级别,这样就很难意外创建导致客户端看到另一个客户端数据的功能。因此,当我在控制器中使用服务时,不必每次都传递 clientId:
var messages = _messageService.GetMessagesByType(clientId, type);
它是自动的:
var messages = _messageService.GetMessagesByType(type);
我正在使用 Ninject 将我的服务注入控制器:
public static void RegisterTypes(IKernel kernel)
{
kernel.Bind<IMessageService>().To<MessageService>();
}
我目前的想法是将当前用户的 clientId 存储为会话变量,然后以某种方式将其注入 IServices,然后再在控制器中使用它们。
但是,我假设 RegisterTypes 方法在 App_Start 上被调用了一次,那么当一个动作被调用时我将如何注入它?还是有更好的方法来实现我想要实现的目标?
可悲的是,我对 web 开发和特别是 asp.net-mvc 知之甚少。但是,以下可能是您可以接受的解决方案:
(注意:我假设客户端 ID 的类型为 ClientId
。请参阅 here 了解原因。)
给定:
public class MessageService : IMessageService
{
public MessageService(ClientId clientId,...) {...}
...
}
您可以定义绑定:
kernel.Bind<IMessageService>().To<MessageService>
.WithParameter(new TypeMatchingConstructorArgument(
typeof(ClientId),
(ctx, target) => (ClientId)HttpContext.Current.Session["clientId"]));
将 HttpContext.Current.Session["clientId"]
的值注入 ClientId
类型的参数到 MessageService
的构造函数中。
除了 TypeMatchingConstructorArgument
,您还可以使用 ConstructorArgument
参数,它按参数名称而不是参数类型进行匹配。
现在更进一步,它也适用于其他服务,我们也可以简单地做:
kernel.Bind<ClientId>()
.ToMethod(ctx => ClientId)HttpContext.Current.Session["clientId"]);
kernel.Bind<IMessageService>().To<MessageService>();
注意:您可能需要考虑添加(到绑定)验证是否存在会话以及是否设置了 clientId。
另请注意:在实例化服务(= 由控制器或其依赖项之一请求)之前,您需要注意 clientId
实际上是已知的(放在会话中)。