Majesty Cherry Tomato
Majesty Cherry Tomato

Reputation: 181

DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type

It was working earlier before adding actionedService which is similar to rejectionService, throws following error

An unhandled exception occurred while processing the request. DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Sx.Workflow.Server.Controllers.ReportController' can be invoked with the available services and parameters: Cannot resolve parameter 'Sx.Workflow.Reporting.Services.IActionedService actionedService' of constructor 'Void .ctor(NLog.ILogger, AutoMapper.IMapper, Sx.Workflow.Reporting.Services.IRejectionService, Sx.Workflow.Reporting.Services.IActionedService)'. Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(ConstructorInfo[] availableConstructors, IComponentContext context, IEnumerable parameters) in ReflectionActivator.cs, line 160

Controller

namespace Sx.Workflow.Server.Controllers
{
    [MenuItem("report")]
    [ServiceFilter(typeof(SettingsFilter))]
    [Authorize(Policy = Security.Constants.RolePolicy)]
    public class ReportController : Controller
    {
        private readonly ILogger _logger;
        private readonly IMapper _mapper;
        private readonly IRejectionService _rejectionService;
        private readonly IActionedService _actionedService;

        public ReportController(ILogger logger, IMapper mapper, IRejectionService rejectionService, IActionedService actionedService)
        {
            _logger = logger;
            _mapper = mapper;
            _rejectionService = rejectionService;
            _actionedService = actionedService;
        }

        [HttpGet]
        public IActionResult Index()
        {
            _logger.Info("Report Controller");
            return View();
        }

        [HttpPost]
        [ApiExceptionFilter]
        public async Task<IActionResult> Reject(RejectionReportRequestDto criteria)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            _logger.Info("Generate Rejection Report");
            var result = await _rejectionService.Generate(criteria.From, criteria.To);
            var items = _mapper.Map<RejectionReportDto>(result);
            return Ok(items);
        }

        [HttpPost]
        [ApiExceptionFilter]
        public async Task<IActionResult> Actioned(ActionedReportRequestDto criteria)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            _logger.Info("Generate Actioned Report");
            var result = await _actionedService.Generate(criteria.From, criteria.To);
            var items = _mapper.Map<ActionedReportDto>(result);
            return Ok(items);
        }
    }
}

Handler

namespace Sx.Workflow.Reporting.Handlers
{
    public class ActionedReportHandler : IHandleEvent<ApplicationActionedEvent>
    {
        private readonly IActionedService _service;

        public ActionedReportHandler(IActionedService service)
        {
            _service = service;
        }

        public Task Handle(ApplicationActionedEvent args)
        {
            var actioned = new Actioned
            {
                ApplicationNumber = args.ApplicationNumber,
                AssigneeFrom = args.AssigneeFrom,
                AssigneeTo = args.AssigneeTo,
                DepartmentFrom = args.DepartmentFrom.Name,
                DepartmentTo = args.DepartmentTo.Name,
                Reason = args.RejectReasonName,
                Comments = args.RejectReasonText,
                RejectionDate = DateTime.Now
            };

            return _service.Save(actioned);
        }
    }
}

Service

namespace Sx.Workflow.Reporting.Services
{
    public class ActionedService : IActionedService
    {
        private readonly ISaveActioned _saveActioned;
        private readonly IGenerateActionedReport _actionedReport;

        public ActionedService(ISaveActioned saveActioned, IGenerateActionedReport actionedReport)
        {
            _saveActioned = saveActioned;
            _actionedReport = actionedReport;
        }

        public Task<ActionedReport> Generate(DateTime from, DateTime to)
        {
            return _actionedReport.Generate(from, to);
        }

        public Task Save(Actioned actioned)
        {
            return _saveActioned.Save(actioned);
        }
    }
}

Interface

namespace Sx.Workflow.Reporting.Services
{
    public interface IActionedService
    {
        Task Save(Actioned actioned);
        Task<ActionedReport> Generate(DateTime from, DateTime to);
    }
}

Service Module

public class ServiceModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<RejectionService>()
            .As<IRejectionService>()
            .InstancePerLifetimeScope();

        builder.RegisterType<ActionedService>()
            .As<IActionedService>()
            .InstancePerLifetimeScope();
    }
}

Upvotes: 4

Views: 8900

Answers (1)

Athanasios Kataras
Athanasios Kataras

Reputation: 26342

Makes sense. While you are registering the type in DI, you have nothing for:

        public ActionedService(ISaveActioned saveActioned, IGenerateActionedReport actionedReport)

So autofac assumes that there must be an empty constructor in ActionedService

So there are 2 solutions:

  1. Remove the constructor parameters and create them without DI
  2. Create the registrations for the two parameters of the constructor. Something like the following:
protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<RejectionService>()
            .As<IRejectionService>()
            .InstancePerLifetimeScope();

        builder.RegisterType<ActionedService>()
            .As<IActionedService>()
            .InstancePerLifetimeScope();

        builder.RegisterType<SaveActioned>()
            .As<ISaveActioned>()
            .InstancePerLifetimeScope();

        builder.RegisterType<GenerateActionedReport>()
            .As<IGenerateActionedReport>()
            .InstancePerLifetimeScope();
    }

Upvotes: 4

Related Questions