Autofac:DependencyResolutionException FluentValidation.IValidator

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Autofac:DependencyResolutionException FluentValidation.IValidator相关的知识,希望对你有一定的参考价值。

除IValidator注射外,一切正常。

我收到如下错误:

Autofac.Core.DependencyResolutionException:'在激活特定注册期间发生错误。有关详细信息,请参阅内部异常注册:Activator = SampleCommandHandler(ReflectionActivator),Services = [MyApp.Domain.Core.ICommandHandler`1 [[MyApp.Domain.SampleCommand,MyApp.Domain,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,Sharing = None,Ownership = OwnedByLifetimeScope'

内部异常DependencyResolutionException:可以使用可用的服务和参数调用在'MyApp.Domain.SampleCommandHandler'类型上找到'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'的构造函数:无法解析参数'FluentValidation.IValidator1[MyApp.Domain.SampleCommand] sampleCommandValidator' of constructor 'Void .ctor(MyApp.Domain.ISampleRepository, FluentValidation.IValidator1 [MyApp。 Domain.SampleCommand])”。

我的应用程序是Web API ...我的参考项目:https://github.com/Weapsy/Weapsy.CMS

namespace MyApp.Service.WebAPI
{
    /// <summary>
    /// http://autofac.readthedocs.io/en/latest/register/scanning.html#scanning-for-modules
    /// </summary>
    public class AutofacModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // MyApp.Application.Core
            builder.RegisterAssemblyTypes(typeof(IService).GetTypeInfo().Assembly).AsImplementedInterfaces();

            // MyApp.Application
            builder.RegisterAssemblyTypes(typeof(ISampleService).GetTypeInfo().Assembly).AsImplementedInterfaces();

            // MyApp.Domain.Core
            builder.RegisterAssemblyTypes(typeof(IResolver).GetTypeInfo().Assembly).AsImplementedInterfaces();

            // MyApp.Domain
            builder.RegisterAssemblyTypes(typeof(ISampleRepository).GetTypeInfo().Assembly).AsImplementedInterfaces();
            //builder.RegisterAssemblyTypes(typeof(SampleApplyCommand).GetTypeInfo().Assembly).AsImplementedInterfaces();

            // MyApp.Infrastructure.Data
            builder.RegisterAssemblyTypes(typeof(IDbFactory).GetTypeInfo().Assembly).AsImplementedInterfaces();   
        }
    }
}

namespace MyApp.Service.WebAPI
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            var builder = new ContainerBuilder();
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            builder.RegisterModule(new AutofacModule());
            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

namespace MyApp.Domain
{
    public class SampleCommandHandler : ICommandHandler<SampleCommand>
    {
        private readonly ISampleRepository _sampleRepository;
        private readonly IValidator<SampleCommand> _sampleCommandValidator;

        public SampleCommandHandler(ISampleRepository sampleRepository, IValidator<SampleCommand> sampleCommandValidator)
        {
            _sampleRepository = sampleRepository;
            _sampleCommandValidator = sampleCommandValidator;
        }

        public IEnumerable<IEvent> Handle(SampleCommand command)
        {
            var validate = _sampleCommandValidator.Validate(command);
            if (!validate.IsValid)
            {
                throw new DomainException(validate.Errors.Select(s => s.ErrorMessage));
            }

            var sample = _sampleRepository.Read(command.SampleNumber);

            sample.Apply(command);

            _sampleRepository.Update(sample);

            return sample.Events;
        }
    }
}

namespace MyApp.Domain
{
    public class SampleCommand : ICommand
    {
        public SampleCommand()
        {
        }

        public SampleCommand(string sampleNumber)
        {
            SampleNumber = sampleNumber;
        }

        public string SampleNumber { get; set; }
    }
}

namespace MyApp.Domain
{
    public class SampleValidator<T> : AbstractValidator<T> where T : SampleCommand
    {
        private readonly ISampleRules _sampleRules;

        public SampleValidator(ISampleRules sampleRules)
        {
            _sampleRules = sampleRules;

            RuleFor(rule => rule.SampleNumber)
                .NotEmpty().WithMessage(DomainValidationMessages.SampleNumberCannotBeEmpty);
        }
    }
}

namespace MyApp.Domain.Core
{
    public interface IResolver
    {
        T Resolve<T>();
        IEnumerable<T> ResolveAll<T>();
    }
}

namespace MyApp.Domain.Core
{
    public class AutofacResolver : IResolver
    {
        private readonly IComponentContext _context;

        public AutofacResolver(IComponentContext context)
        {
            _context = context;
        }

        public T Resolve<T>()
        {
            return _context.Resolve<T>();
        }

        public IEnumerable<T> ResolveAll<T>()
        {
            return _context.Resolve<IEnumerable<T>>().ToList();
        }
    }
}

图层:

MyApp.Service.WebAPI

MyApp.Application

MyApp.Application.Core

MyApp.Domain

MyApp.Domain.Core

my app.infrastructure.data

我已经尝试了一切解决但没有奏效。救命!

答案

在没有看到你的实际项目的情况下我无法确定,但Weapsy示例应用程序依赖于以下事实:所有程序集(包括包含对IValidator接口的引用的域程序集)都通过使用AutofacModule上的每个类或接口进行注册:

var infrastructureAssembly = typeof(AggregateRoot).GetTypeInfo().Assembly;
var domainAssembly = typeof(CreateSite).GetTypeInfo().Assembly;
var dataAssembly = typeof(IDataProvider).GetTypeInfo().Assembly;
var reportingAssembly = typeof(GetAppAdminModel).GetTypeInfo().Assembly;
var servicesAssembly = typeof(IMailService).GetTypeInfo().Assembly;

但是,根据您提供的修剪代码,看起来像验证程序所属的域程序集,未注册:

builder.RegisterAssemblyTypes(typeof(IDbFactory).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(IResolver).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(ISampleRepository).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(IService).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(ISampleService).GetTypeInfo().Assembly).AsImplementedInterfaces();

看起来在验证器程序集中注册类型可以使其工作:

builder.RegisterAssemblyTypes(typeof(SampleApplyCommand).GetTypeInfo().Assembly).AsImplementedInterfaces();

如果没有,请确保注册验证程序实现所在的程序集。

这种用于注册依赖项的模式可能非常不透明,很难推断出哪些依赖项已注册,我建议您在注册中明确并使用Autofac模块在程序集之间拆分它们。

以上是关于Autofac:DependencyResolutionException FluentValidation.IValidator的主要内容,如果未能解决你的问题,请参考以下文章

Autofac

Autofac 同时支持MVC 与Webapi

依赖注入容器Autofac的详解

AutoFac

浅析依赖注入框架Autofac的使用

.NET Core下自带容器IServiceCollection以及AutoFac以及AutoFac中AOP简介