I've been trying to implement a loosely coupled application in an asp.net MVC5 app. I have a controller:
public class HeaderController : Controller
{
private IMenuService _menuService;
public HeaderController(IMenuService menuService)
{
this._menuService = menuService;
}
//
// GET: /Header/
public ActionResult Index()
{
return View();
}
public ActionResult GetMenu()
{
MenuItem menu = this._menuService.GetMenu();
return View("Menu", menu);
}
}
And service being used in this controller is:
public class MenuService : IMenuService
{
private IMenuRespository _menuRepository;
public MenuService(IMenuRespository menuRepository)
{
this._menuRepository = menuRepository;
}
public MenuItem GetMenu()
{
return this._menuRepository.GetMenu();
}
}
And the repository being used in the service class is:
public class MenuRepository : IMenuRespository
{
public MenuItem GetMenu()
{
//return the menu items
}
}
The interfaces used for the service and repository are as such:
public interface IMenuService
{
MenuItem GetMenu();
}
public interface IMenuRespository
{
MenuItem GetMenu();
}
The constructor for HeaderController
takes in the MenuService
using Constructor Injection, and I have ninject as the DI container handling this.
It all works great - except, in my controller, I can still do this:
MenuItem menu = new MenuService(new MenuRepository());
...which breaks the architecture. How can I prevent the 'new' being used in this way?
One way to do it would be to move your interfaces and implementations into separate Visual Studio projects / assemblies and only reference the implementation project in the project(s) that actually needs it - everything else can reference the interface project for your IMenuService
- at that point the code can consume the interface, but not actually new up any implementations itself.
You can then reference the implementation project wherever you DI in your dependencies.
WebApp Solution:
WebApp Proj (Controllers etc.) --> Service Interface Proj
Service Impl Project --> Service Interface Proj
Even so this is a good approach, it's not fool proof by all means - the other component is education and code review to come up with best practices that work for your team such as testability and dependency injection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With