gpt4 book ai didi

c# - 在 StartUp 中使用 Autofac 解决每个用户/每个请求的依赖

转载 作者:行者123 更新时间:2023-11-30 14:25:05 25 4
gpt4 key购买 nike

我正在尝试解决 ASP.Net WebApi 2 项目的 StartUp 类中的依赖项。 Autofac 用于配置依赖注入(inject)。场景如下:

  • 不同的用户看到不同的数据。每个用户都有特定的权限,允许该用户查看特定的数据。
  • 正在使用包含多个边界的领域驱动架构。不允许在域和数据访问层进行跨界调用。这一点很重要,因为为了获取用户允许数据的所有代码,我们需要进行一些跨界调用。
  • 我们想过滤数据访问层内的数据,以便只为每个用户检索允许的数据。这里不允许跨界调用。
  • 为了实现这一点,我想从用户可以看到的记录中注入(inject)所有代码的列表。
  • 为此,我尝试向 Autofac 注册一个工厂,该工厂根据用户创建此列表。我们将工厂称为 StuffFactory,将列表称为 StuffModel

现在的问题是所有这些都需要注册为InstancePerRequest。这会抛出一个 InvalidOperatonException,这听起来很合理,因为在 StartUp?

中无法访问 Request 生命周期范围

No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

允许的东西在容器中注册的代码:

private IContainer RegisterAllowedStuff(IContainer container)
{
var builder = new ContainerBuilder();

builder.Register(x => GetAllowedStuffForUser(container))
.As<StuffModel>()
.InstancePerRequest();

builder.Update(container);
return container;
}

private static StuffModel GetAllowedStuffForUser(IContainer container)
{
var stuffFactory = container.Resolve<IStuffFactory>();
return stuffFactory.CreateStuffModel(Helper.GetParsedUserName());
}

我有点卡在如何从这里前进。对于我完全监督的 Autofac 问题,是否有一个简单的解决方案?有人可能对我如何实现这个有更好的想法吗?提前致谢!

最佳答案

您的启动类中不应该有任何业务逻辑。 Autofac 允许您注册将在解析时调用的 lambda 方法。此时,一个HttpRequest 可用,因此您可以将这些lambda 注册为InstancePerRequest

在您的情况下,如果您想将 StuffModel 注册为 InstancePerRequest,您可以这样做:

builder.RegisterType<ConcreteStuffFactory>()
.As<IStuffFactory>();
builder.Register(c => c.Resolve<IStuffFactory>()
.CreateStuffModel(Helper.GetParsedUserName()))
.As<IStuffModel>()
.InstancePerRequest();

顺便说一下,我也不会使用看起来像反模式的 Helper 类,您可以创建一个服务来获取当前用户的用户名,例如 IUserContextProvider。您还可以添加 IUserContextProviderConcreteStuffFactory

的依赖
public class ConcreteStuffFactory
{
public ConcreteStuffFactory(IUserContextProvider userContextProvider)
{
this._userContextProvider = userContextProvider;
}

private readonly IUserContextProvider _userContextProvider;


public IStuffModel CreateStuffModel()
{
String userName = this._userContextProvider.UserName;
// do things with userName
}
}

和注册:

builder.RegisterType<ConcreteStuffFactory>()
.As<IStuffFactory>();
builder.RegisterType<HttpContextUserContextProvider>()
.As<IUserContextProvider>()
.InstancePerRequest();
builder.Register(c => c.Resolve<IStuffFactory>().CreateStuffModel())
.As<IStuffModel>()
.InstancePerRequest();

关于c# - 在 StartUp 中使用 Autofac 解决每个用户/每个请求的依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39697933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com