5

I just have started to design with DDD (I have no experience neither a teacher)

I have some domain service classes that have to reference each other in some point. So I decided to inject the references through constructor.

And when I created a view that has a lot of data to display in the controller I had to create a bunch of service (some of which referencing each other)

At this point one of my controller's first lines looked like this:

        EmployeeRepository employRepository = new EmployeeRepository();
        ShiftModelRepository shiftModelRepository = new ShiftModelRepository();
        ShiftModelService shiftModelService = new ShiftModelService(shiftModelRepository);
        EmployeeService employeeService = new EmployeeService(employRepository, shiftModelService);
        OvertimeRepository overtimeRepository = new OvertimeRepository();
        OvertimeService overtimeService = new OvertimeService(overtimeRepository, employeeService);

But I started to create interfaces for the services and using a IoC controller (named StructureMap)

And now the same controller's first lines looked like this:

        IShiftModelService shiftModelService = ObjectFactory.GetInstance<IShiftModelService>();
        IOvertimeService overtimeService = ObjectFactory.GetInstance<IOvertimeService>();
        IEmployeeService employeeService = ObjectFactory.GetInstance<IEmployeeService>();

I think that it's far more good to use, but I to know if it is a good practice in DDD or not.

dvjanm
  • 2,351
  • 1
  • 28
  • 42
  • 3
    The interfaces are good, but you should look also look at injection (specifically [constructor injection](http://stackoverflow.com/questions/2531612/structuremap-resolve-dependency-through-injection-instead-of-service-location)) instead of using service location. – StuartLC Oct 18 '13 at 15:03
  • Please read my answer to Matt Whetton – dvjanm Oct 18 '13 at 16:18

2 Answers2

2

Using interfaces is almost always preferable and good practice - so what you have in the second example is better.

But as StuartLC mentions, your really want to look at injecting these dependencies as constructor arguments.

ObjectFactory.GetInstance is really a kind of service locator which is generally not the best pattern to use as the object doesn't declare what dependencies it has. It is generally better to expose the dependencies as constructor arguments and have them injected in.

Matt Whetton
  • 6,616
  • 5
  • 36
  • 57
  • I'm not sure if I understand how you mean this. (I do all of the injections through constructor and the StructureMap find these dependencies) Please tell me in other worlds. Thanks. – dvjanm Oct 18 '13 at 16:12
  • So yes, you are resolving these dependencies in the constructor, but what you should do is have them as arguments on constructor. Then the class that creates the object would inject the dependencies into the object. – Matt Whetton Oct 18 '13 at 20:59
  • No, I actually have them as arguments on constructor. When I call this "IEmployeeService employeeService = ObjectFactory.GetInstance();" the StructureMap creates it with the required arguments. The EmployService's constructor has two constructor arguments (IEmployRepository, IShiftModelService) and have no default constructor. – dvjanm Oct 19 '13 at 07:04
  • Yes, that's great and the right thing to do. You also inject the services into your controller using an MVC dependency resolver...so you never have to call ObjectFactory.GetInstance in your controller - see this question http://stackoverflow.com/questions/12218300/asp-net-mvc-4-with-structuremap – Matt Whetton Oct 19 '13 at 08:22
2

Yes, it is OK to use an interface per implementation when you use DI (dependency injection) frameworks.

You should avoid ObjectFactory.GetInstance<IShiftModelService>() and let your framework resolve dependencies automatically using YourImplementationOfControllerFactory.

I haven't used Structure Map in my projects but I've been using Castle Windsor, another one dependency injection framework. Also you can have a look at Ninject.

Anyway, there are steps that are similar for many frameworks:

  1. Write a custom implementation of controller factory - a class that inherits DefaultControllerFactory.
  2. Register types that container should resolve.
  3. Bootstrap container in Global.asax.cs.
  4. Set up an instance of your controller factory in Global.asax.cs.

Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
{    
    protected void Application_Start()
    {
        /* code that bootstraps your container */

        //Set the controller builder to use our custom controller factory
        var controllerFactory = new YourControllerFactory();
        ControllerBuilder.Current.SetControllerFactory(controllerFactory);
    }
}

There are several useful links:

Community
  • 1
  • 1
Ilya Palkin
  • 14,687
  • 2
  • 23
  • 36