3

I'm currently developing a web application which uses MVC3. the MVC3 project accesses our Application logic through a Service layer. The Service layer accesses the Database using repositories accessed via the UnitOfWork pattern.

I just installed StructureMap to take care of injecting my Services into the MVC3 project. An Example controller would look like this

public class AccountManagementController : Controller
{
    IAccountService accountService;

    public AccountManagementController(IAccountService accountService)
    {
        this.accountService = accountService;
    }

Now, my problem is that my AccountService class needs to have the UnitOfWork injected when structure map creates it. Currently I handle this by having 2 controllers. One takes an interface, the other instantiates a concrete class.

public class AccountService : IAccountService, IDisposable
{
    private IUnitOfWork unitOfWork;

    internal AccountService(IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
    }
    public AccountService()
    {
        this.unitOfWork = new UnitOfWork();
    }

This seems like code smell to me. Is there a more correct way to handle this?

Thanks, AFrieze

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
AFrieze
  • 844
  • 1
  • 10
  • 26
  • 4
    Delete the default constructor... – Mark Seemann Dec 15 '11 at 17:57
  • I think the fluent interface for configuring StructureMap has changed over the years, so I don't know specifically what code will work with what version. But you should be able to tell your bootstrapper code to use a specific `IUnitOfWork` implementation if need be. Take a look here: http://stackoverflow.com/q/289512/328193 – David Dec 15 '11 at 17:59
  • Thanks, I will take a look. This would require a reference to my DAL from my website which I generally try to avoid. – AFrieze Dec 15 '11 at 18:14
  • 1
    But a reference to an application layer that references the DAL is effectively the same. Also: there is nothing wrong about having an application root the references and configures/wires the whole application. – Christian Horsdal Dec 15 '11 at 18:28

2 Answers2

1

I don't smell anything as long as, like comments suggest, you remove the default parameterless constructor from AccountService. Any decent IoC container should be able to cascade the dependencies, so that when you inject IAccountService into AccountManagementController, it will resolve AccountService's dependency on IUnitOfWork

danludwig
  • 46,965
  • 25
  • 159
  • 237
1

As Mark suggested I would delete the default constructor, but...

AFAIK, StructureMap choses always the constructor with the most arguments so this should not be an issue while resolving IUnitOfWork dependency.

On the other hand, IDisposable seems to me like a smell. AFAIK structureMap advice how to deal with disposable instances like that :

  • we should wrap the disposable service into the non disposable wrapper. the non disposable wrapper should dispose the instance it wrapps.
  • we should inject the factory of disposable service to the non disposable wrapper.

In these two cases we inject to the consumers the wrapper insteed of directly injecting the disposable service.

For structureMap we could also take advantage of the nested containers features, which tracks the disposable instances. So when the nested container is disposed, all object graph is released.

Tomasz Jaskuλa
  • 15,723
  • 5
  • 46
  • 73