gpt4 book ai didi

inversion-of-control - Autofac - 如何从单例中解析 ISomething 的 Func,其中 ISomething 是 InstancePerHttpRequest

转载 作者:行者123 更新时间:2023-12-03 20:04:56 26 4
gpt4 key购买 nike

我正在尝试使用 Autofac 将依赖项注入(inject)到 MVC 4 应用程序中的 FluentValidation 中。我想我已经制定了策略,但是我一直无法解决我的单例请求 ISomething。

这是场景:
我有一个从 FluentValidation 的 AbstractValidator 派生的验证器。我读过 FluentValidation 验证器作为单例执行得最好,所以我的构造函数需要一个 Func 并存储该 Factory 以供以后使用。使用验证器时,它应该向存储的工厂请求 IDataStore,获取为该请求创建的实例并使用它。这就是理论。我想感谢 https://github.com/robdmoore/UnobtrusiveMVCTechniques ,这帮助我解决了这个解决方案。这是验证器...

public class SiteAdminViewModelValidator : AbstractValidator<SiteAdminViewModel> {
private readonly Func<IDataStore> _dbFactory;

public SiteAdminViewModelValidator(Func<IDataStore> dbFactory) {
_dbFactory = dbFactory;

RuleFor(model => model.SiteCode).Length(1, 40).Must(BeSpecial);
}

public bool BeSpecial(string siteCode) {
var db = _dbFactory();
List<Stuff> stuffs = db.All<Stuff>().ToList();

return true;
}
}

如果有人可以为我指出我正在尝试完成的工作示例,那就太好了,但我也想知道解决这个特定的 Autofac 技巧的方法。

这是我的验证人注册...
public class FluentValidatorModule : Module {
protected override void Load(ContainerBuilder builder) {
base.Load(builder);
builder.RegisterType<AutofacValidatorFactory>().As<IValidatorFactory>().SingleInstance();

var validators = AssemblyScanner.FindValidatorsInAssembly(System.Reflection.Assembly.GetExecutingAssembly());
validators.ToList().ForEach(v => builder.RegisterType(v.ValidatorType).As(v.InterfaceType).SingleInstance());
}
}

这是我对 IDataStore 工厂的注册...
builder.RegisterType<SuperDB>().As<IDataStore>().InstancePerHttpRequest();
builder.Register<Func<IDataStore>>(c => {
var context = c.Resolve<IComponentContext>();
return context.Resolve<IDataStore>;
});

这是我的验证器在线请求 IDataStore 时遇到的错误 -
var db = _dbFactory();

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.



...这正是我在编写自己的工厂注册之前尝试它时得到的——Func 注册。通过阅读类似问题的各种答案,看起来我上面的内容应该可以工作,因为我认为我现在正在解析 Func 以获得当前的解析器。

任何帮助将不胜感激。

最佳答案

我同意这应该可行 - Func<IDataStore>正在定义一个工厂,它将根据需要在每个方法中生成依赖项。

我绕过这种方法的方法是使用 DependencyResolver.Current就像错误消息所暗示的那样。主要原因是我已经使用 Autofac.Mvc4 nuget 包进行了设置...

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

所以要实际设置方法,我有以下功能
public Func<T> PerHttpSafeResolve<T>()
{
return () => DependencyResolver.Current.GetService<T>();
}

并且在构建容器时
builder.RegisterType<SuperDB>().As<IDataStore>().InstancePerHttpRequest();
builder.RegisterInstance(PerHttpSafeResolve<IDataStore>());

编辑:注册实例的第二行是 - 如果您需要 Func<IDataStore>然后使用传递给方法的值。 PerHttpSafeResolve<IDataStore> 的结果只是一个函数(工厂),因此它可以作为单个实例存在。

关于inversion-of-control - Autofac - 如何从单例中解析 ISomething 的 Func,其中 ISomething 是 InstancePerHttpRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15538665/

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