1

I'm trying to setup a custom model validator provider using FluentValidation. Everything works until i try to inject a business layer manager into the validator's constructor to run some business logic.

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

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

public AutofacValidatorFactory : ValidatorFactoryBase
{
}

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

I wire everything up like so:

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());

Finally, i add the FluentValidator Model Provider like so:

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

The issue is occurring when my validator factory tries to spin up a validator instance. At which point i get the following exception:

"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."

I think the issue has something to do with the way Manager & Repository is configured in Autofac but i don't know what i'm missing.

EDIT: This issue is occurring in a Web API project.

4

1 回答 1

2

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

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

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

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

这就是你最有可能做的——将某些东西注册为 SingleInstance,它依赖于注册到 Matching Lifetime 范围的东西。

于 2014-02-28T10:44:49.397 回答