Autofac范围问题

时间:2013-11-14 14:44:00

标签: dependency-injection asp.net-web-api autofac fluentvalidation

我正在尝试使用FluentValidation设置自定义模型验证程序提供程序。一切正常,直到我尝试将业务层管理器注入验证器的构造函数以运行某些业务逻辑。

public class Repository : IRepository
{
    public Repository(IDbConnection)
    {
    }
}

public class Manager : IManager
{
    public Manager(IRepository)
    {
    }
}

public AutofacValidatorFactory : ValidatorFactoryBase
{
}

public MyModelValidator : AbstractValidator<MyModel>
{
    public MyModelValidator(IManager) { }
}

我把所有东西都连接起来:

builder.Register(c => new SqlConnection(ConfigurationManager.ConnectionStrings["MyCS"].ConnectionString))
               .As<IDbConnection>().InstancePerApiRequest();

builder.RegisterType<Repository>()
               .As<IRepository>()
               .InstancePerDependency();

builder.RegisterType<Manager>()
               .As<IManager>()
               .InstancePerDependency();

builder.RegisterType<ValidatorFactory>()
               .As<IValidatorFactory>()
               .InstancePerLifetimeScope();

        builder.RegisterType<FluentValidation.Mvc.WebApi.FluentValidationModelValidatorProvider>()
               .As<ModelValidatorProvider>()
               .InstancePerLifetimeScope();

        AssemblyScanner.FindValidatorsInAssembly(assembly)
                       .ForEach(
                           result =>
                           Builder.RegisterType(result.ValidatorType).As(result.InterfaceType).InstancePerApiRequest());

最后,我添加了FluentValidator Model Provider,如下所示:

// _validatorProvider is injected as per Autofac config above.    
GlobalConfiguration.Configuration.Services.Add(typeof(ModelValidatorProvider), _validatorProvider);

当我的验证器工厂尝试启动验证器实例时,问题就出现了。此时我得到以下异常:

  

“从请求实例的作用域中看不到具有匹配'AutofacWebRequest'的标记的作用域。这通常表示SingleInstance()组件(或类似组件)正在请求按HTTP请求注册的组件场景。)在Web集成下,总是从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖,永远不要从容器本身请求。“

我认为这个问题与Manager&amp;的方式有关。存储库在Autofac中配置,但我不知道我错过了什么。

编辑:此问题发生在Web API项目中。

1 个答案:

答案 0 :(得分:2)

在没有看到更多代码的情况下,我无法回答您的直接问题,但我可以回答这个异常通常意味着什么

Autofac支持嵌套生命周期范围(即子容器)。主容器实际上只是根生命周期范围。每个生命周期范围都可以被视为一个工作单元。您可以创建生命周期范围,解析执行该任务所需的实例,然后处置生命周期范围。然后处理由生命期范围创建的任何内容。

注册为SingleInstance意味着单个实例由根范围解析和存储。使用InstancePerLifetimeScope将为每个已解析的作用域重新创建每个实例,因此您最终可以在根作用域和子作用域中使用实例。 InstancePerMatchingLifetimeScope允许您注册一个类型,以便在树的特定分支的所有子容器之间共享它。这些类型永远不会存在,也不会被根范围内的任何内容访问。 InstancePerApiRequest与InstancePerMatchingLifetimeScope(“AutofacWebRequest”)相同。

在您的应用程序中,每个请求都将是一个子autofac范围。注册到子范围的东西(即您的IDBConnection)可以使用同一范围内的任何其他内容(注册为InstancePerLifetimeScope)以及父范围内的任何内容(注册为SingleInstance),但此处存在潜在问题。注册到父作用域的某些内容(例如,作为根容器中的SingleInstance)无法访问在子作用域中注册为InstancePerMatchingLifetimeScope的任何内容,因为父作用域无法访问子作用域中的实例。

这是您最有可能完成的事情 - 注册为SingleInstance,它依赖于在匹配生命周期范围内注册的内容。