Search code examples
c#asp.net-mvcdependency-injectioninversion-of-control

How to inject object builders into MVC controller?


I'm working on ASP.NET MVC project. In order to map view model to domain entity, I've decided to use a builder pattern. PtoRequest, UtoRequest are a part of the domain and inherit from abstract TimeOffRequest class which implements ITimeOffRequest. For each of them I have a separate builder. Each builder implements IRequestBuilder. The problem I'm having is how to enject those builders into the controller (Assuming I do not have to enject one builder for each type of request)?

  • Pto - paid time off
  • Uto - unpaid time off

Code:

public class TimeOffManager : Controller
{
   private readonly IUnitOfWork _uow;

   public TimeOffManager(IUnitOfWork uow)
   {
       _uow = uow;
   }

   [HttpPost]
   public ActionResult RequestPto(PtoFormVm vm)
   {
       //validate view model...

       ITimeOffRequest pto = new PtoRequestBuilder()
                               .Id(vm.Id)
                               .InRange(vm.StartDate, vm.EndDate)
                               .State((RequestState)vm.State)
                               .Note(vm.Comment)
                               .Build();
       // Etc...
   }

   [HttpPost]
   public ActionResult RequestUto(UtoFormVm vm)
   {
       //validate view model...

       ITimeOffRequest uto = new UtoRequestBuilder()
                               .Id(vm.Id)
                               .IsFullDay(vm.FullDay)
                               .InRange(vm.StartDate, vm.EndDate)
                               .State((RequestState)vm.State)
                               .Note(vm.Comment)
                               .Build();
       // Etc...
   }
}

Solution

  • Like this?

    public class TimeOffManager : Controller
    {
       private readonly IUnitOfWork _uow;
       private readonly IRequestBuilder ptoBuilder;
       private readonly IRequestBuilder utoBuilder;
    
       public TimeOffManager(IUnitOfWork uow, IRequestBuilder ptoBuilder, IRequestBuilder utoBuilder)
       {
           _uow = uow;
           this.ptoBuilder = ptoBuilder;
           this.utoBuilder = utoBuilder;
       }
    
       [HttpPost]
       public ActionResult RequestPto(PtoFormVm vm)
       {
           //validate view model...
    
           ITimeOffRequest pto = ptoBuilder
                                   .Id(vm.Id)
                                   .InRange(vm.StartDate, vm.EndDate)
                                   .State((RequestState)vm.State)
                                   .Note(vm.Comment)
                                   .Build();
           // Etc...
       }
    
       [HttpPost]
       public ActionResult RequestUto(UtoFormVm vm)
       {
           //validate view model...
    
           ITimeOffRequest uto = utoBuilder()
                                   .Id(vm.Id)
                                   .IsFullDay(vm.FullDay)
                                   .InRange(vm.StartDate, vm.EndDate)
                                   .State((RequestState)vm.State)
                                   .Note(vm.Comment)
                                   .Build();
           // Etc...
       }
    }
    

    Apart from that, why do you have an abstract class that implements an interface? An abstract class is already polymorphic...