如何防止c#类中的构造函数滥用

M.R*_*.R. 10 c# asp.net asp.net-mvc dependency-injection inversion-of-control

我一直在尝试在asp.net MVC5应用程序中实现一个松散耦合的应用程序.我有一个控制器:

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);

        }

    }
Run Code Online (Sandbox Code Playgroud)

此控制器中使用的服务是:

public class MenuService : IMenuService
{
    private IMenuRespository _menuRepository;

    public MenuService(IMenuRespository menuRepository)
    {
        this._menuRepository = menuRepository;
    }

    public MenuItem GetMenu()
    {
        return this._menuRepository.GetMenu();
    }
}
Run Code Online (Sandbox Code Playgroud)

并且在服务类中使用的存储库是:

public class MenuRepository : IMenuRespository
    {
        public MenuItem GetMenu()
        {
            //return the menu items
        }
    }
Run Code Online (Sandbox Code Playgroud)

用于服务和存储库的接口如下:

 public interface IMenuService
    {
        MenuItem GetMenu();
    }

public interface IMenuRespository
    {
        MenuItem GetMenu();
    }
Run Code Online (Sandbox Code Playgroud)

为构造函数HeaderController需要在MenuService使用构造器注入,我已经ninject作为DI容器处理这个.

一切都很好 - 除了在我的控制器中,我仍然可以这样做:

MenuItem menu = new MenuService(new MenuRepository());
Run Code Online (Sandbox Code Playgroud)

......打破了建筑.如何防止以这种方式使用"新"?

Bro*_*ass 7

一种方法是将接口和实现移动到单独的Visual Studio项目/程序集中,并仅引用实际需要它的项目中的实现项目 - 其他一切都可以为您引用接口项目IMenuService- 此时代码可以使用接口,但实际上并不是任何实现本身.

然后,您可以在依赖项中的DI处引用实现项目.

WebApp解决方案:

WebApp Proj(控制器等) - >服务接口项目

服务Impl项目 - >服务接口项目

即便如此,这也是一种很好的方法,它并非一丝不苟 - 另一个组件是教育和代码审查,以便为您的团队提供最佳实践,例如可测试性和依赖注入.