Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent constructor misuse in c# class

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?

like image 808
M.R. Avatar asked Apr 21 '15 02:04

M.R.


1 Answers

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.

like image 126
BrokenGlass Avatar answered Oct 30 '22 07:10

BrokenGlass