1

我正在嘗試使用FluentValidation來設置自定義模型驗證器提供程序。一切工作,直到我嘗試注入一個業務層管理器到驗證器的構造函數來運行一些業務邏輯。Autofac範圍界定問題

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模型提供像這樣:

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

問題發生時,我的驗證工廠嘗試分拆啓動一個驗證器實例。在這一點上,我收到以下例外情況:

「沒有與標籤匹配的範圍'AutofacWebRequest'在請求實例的作用域中可見,這通常表示註冊爲每個HTTP請求的組件是被SingleInstance()組件(或類似的場景)請求。在Web集成下,總是從DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime請求依賴關係,而不是從容器本身。「

我認爲這個問題與管理器&存儲庫配置在Autofac中的方式有​​關,但我不知道我錯過了什麼。

編輯:在Web API項目中發生此問題。

+1

你如何解決驗證器?你可以發佈你的Validator工廠實現嗎? –

回答

2

沒有看到更多的代碼,我不能回答你直接的問題的,但是我可以回答一下這個異常通常意味着

Autofac支持嵌套的壽命範圍(即子容器)。主容器實際上只是根生命週期的範圍。每個生命週期的範圍可以被認爲是一個工作單元。您可以創建生命週期範圍,解決執行該任務所需的實例,然後處置生命週期範圍。然後處置終身範圍創建的任何東西。

註冊爲SingleInstance表示單個實例由根作用域解析並存儲。使用InstancePerLifetimeScope將會重新創建每個作用域的實例,這樣您就可以在根作用域和子作用域中創建一個實例。 InstancePerMatchingLifetimeScope允許您註冊一個類型,以便它在樹的特定分支的所有子容器之間共享。這些類型永遠不會存在,或者可以被根作用域中的任何內容訪問。 InstancePerApiRequest與InstancePerMatchingLifetimeScope(「AutofacWebRequest」)相同。

在您的應用程序中,每個請求都將是一個子autofac範圍。註冊到子範圍的東西(即您的IDBConnection)可以使用同一範圍內的任何其他內容(註冊爲InstancePerLifetimeScope)以及父範圍內的任何內容(註冊爲SingleInstance),但這裏存在潛在的問題。註冊到父作用域的東西(例如根容器中的SingleInstance)無法訪問在子作用域中註冊爲InstancePerMatchingLifetimeScope的任何東西,因爲父作用域無法訪問子作用域中的實例。

這就是你最有可能完成的事情 - 註冊了一個SingleInstance,它依賴於註冊到匹配生存期範圍的東西。