在ASP.NET Core 1.1.2 web項目中,這取決於Microsoft.Extensions.DependencyInjection 1.1.1,我試圖註冊一個通用的FluentValidation驗證器與它的實現和它的接口。在運行時,主機建設過程中,我得到了以下異常:使用ASP.NET Core註冊部分關閉的泛型類型Microsoft.Extensions.DependencyInjection
An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.Extensions.DependencyInjection.dll
Cannot instantiate implementation type 'MyProj.Shared.Api.WithUserCommandValidator`1[T]' for service type 'FluentValidation.IValidator`1[MyProj.Shared.Model.WithUser`1[T]]'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceTable..ctor(IEnumerable`1 descriptors)
at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, Boolean validateScopes)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
at MyProj.Program.Main(String[] args) in X:\MySolution\src\MyProj\Program.cs:line 31
這是(通用,非抽象)的驗證器類:
public class WithUserCommandValidator<TCommand> : AbstractValidator<WithUser<TCommand>>
where TCommand : ICommand
{
public WithUserCommandValidator(IValidator<TCommand> commandValidator)
{
RuleFor(cmd => cmd).NotNull();
RuleFor(cmd => cmd.UserId).NotEqual(Guid.Empty);
RuleFor(cmd => cmd.Content).NotNull()
.SetValidator(commandValidator);
}
}
(不知道是很重要的,以顯示WithUser<T>
類,它只是持有Guid UserId
和T Content
)。
註冊偏偏喜歡這樣:
someInterface = typeof(FluentValidation.IValidator<WithUser<>>);
someImplementation = typeof(Shared.Api.WithUserCommandValidator<>);
// this is for top-level command validators, injected by interface
services.AddScoped(someInterface, someImplementation);
// this is for nested validators, injected by implementation
services.AddScoped(someImplementation);
,並在運行時這些變量持有:
+ someInterface {FluentValidation.IValidator`1[MyProj.Shared.Model.WithUser`1[TCommand]]} System.Type {System.RuntimeType}
+ someImplementation {MyProj.Shared.Api.WithUserCommandValidator`1[TCommand]} System.Type {System.RuntimeType}
這似乎是正確的。
我也在SO上尋找類似的問題和疑問,但它們並沒有真正相關,因爲它們是關於泛型實現的,而這是一個具體實現。
我已經通過了依賴注入模塊代碼,並拋出異常here。由於某種原因,serviceTypeInfo.IsGenericTypeDefinition
返回false(不應該是true,因爲接口類型是通用的?),因此採用else分支。在那裏,相反,實現類型返回true到implementationTypeInfo.IsGenericTypeDefinition
,所以你有例外。
運行值:
+ serviceTypeInfo {FluentValidation.IValidator`1[MyProj.Shared.Model.WithUser`1[TCommand]]} System.Reflection.TypeInfo {System.RuntimeType}
+ implementationTypeInfo {MyProj.Shared.Api.WithUserCommandValidator`1[TCommand]} System.Reflection.TypeInfo {System.RuntimeType}
雖然擺弄,我試過只註冊實施,也沒有註冊接口+實現,而且異常消失。但是如果可能的話,我想注入接口,而不是實現。
我在做什麼錯? TA
一些更詳細信息:.NET的核心代碼檢查'serviceTypeInfo.IsGenericTypeDefinition',這是假的,而不是'serviceTypeInfo.IsGenericType'是真實的。但是,我不知道前者是什麼意思。 – superjos