【发布时间】:2013-03-21 02:56:54
【问题描述】:
我正在尝试使用 Autofac 将依赖项注入到 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();
标签匹配“AutofacWebRequest”的范围不可见 请求实例的范围。这通常表明 正在请求注册为 per-HTTP 请求的组件 一个 SingleInstance() 组件(或类似的场景)。在 web 下 集成总是从 DependencyResolver.Current 或 ILifetimeScopeProvider.RequestLifetime, 永远不要来自容器本身。
...这正是我在编写自己的工厂注册(Func 注册)之前尝试过的结果。通过阅读类似问题的各种答案,我上面的内容看起来应该可以工作,因为我认为我现在正在解析 Func 以获得当前的解析器。
任何帮助将不胜感激。
【问题讨论】:
标签: inversion-of-control autofac fluentvalidation