kurasa
kurasa

Reputation: 5323

How can I achieve the following using IOC?

I want to use IOC with my service and I want to instead inject a class not an interface in the constructor as below in the services layer but I do not want to create a new object from the calling layer like var service = new InvoiceService(new ChangeInvoiceDueDateCommand()) instead I want to create something like this from my controller in MVC where the IInvoiceService is injected into the controller constructor but the problem I see is that

  public InvoiceController(IInvoiceService invoiceService, IMapper mapper)
            {
                _invoiceService = invoiceService;
                _mapper = mapper;
            }

and then called like this

public ActionResult ChangeInvoiceDueDate(InvoiceChangeDueDateViewModel invoiceChangeDueDateViewModel )
            {
                var request = _mapper.Map<InvoiceChangeDueDateViewModel, ChangeInvoiceDuedateRequest>(invoiceChangeDueDateViewModel);
                InvoiceChangeDueDateResponse response =  _invoiceService.ChangeDueDate(request);

                return View();
            }

Service Layer

public class InvoiceService : IInvoiceService
    {
        private readonly ChangeInvoiceDueDateCommand _changeInvoiceDueDateCommand;

        public InvoiceService(ChangeInvoiceDueDateCommand changeInvoiceDueDateCommand)
        {
            _changeInvoiceDueDateCommand = changeInvoiceDueDateCommand;
        }

        public InvoiceChangeDueDateResponse ChangeDueDate(ChangeInvoiceDuedateRequest invoiceChangeDueDateRequest)
        {
            _changeInvoiceDueDateCommand.Execute(invoiceChangeDueDateRequest);
            return new InvoiceChangeDueDateResponse {Status = new Status()};
        }
    }

Command

public class ChangeInvoiceDueDateCommand :  ICommand<ChangeInvoiceDuedateRequest>
    {
        private readonly IRepository<Invoice> _invoiceRepository;

        readonly InvoiceDueDateChangeValidator _validator;

        public ChangeInvoiceDueDateCommand(IRepository<Invoice> invoiceRepository)
        {
            _invoiceRepository = invoiceRepository;
            _validator = new InvoiceDueDateChangeValidator();
        }


        public void Execute(ChangeInvoiceDuedateRequest request)
        {
            if (_validator.IsDuedateValid(request.NewDuedate))
            {
                Invoice invoice = _invoiceRepository.GetById(request.Id);
                invoice.ChangedDueDate(request.NewDuedate);
                _invoiceRepository.SaveOrUpdate(invoice);

            }
            else
            {
                throw new InvalidDueDateException();
            }
        }
    }

ICommand

public interface ICommand<T> where T : IRequest
    {
        void Execute(T request);
    }

IRequest

public interface IRequest
    {
        int Id { get; set; }
    }

Upvotes: 1

Views: 22

Answers (1)

kurasa
kurasa

Reputation: 5323

I worked it out. It was just a Windsor syntax issue. It ended up being as simple as registering the Command using the container.Register(Component.For<ChangeInvoiceDueDateCommand>());

Upvotes: 1

Related Questions