选择哪种模式?Asp.net Mvc 4

Dan*_*zra 3 asp.net asp.net-mvc entity-framework dependency-injection asp.net-mvc-4

我真的很困惑,我用"Apress pro Asp.net Mvc 4"这本书了解到,Mvc 4的最佳模式是依赖注入,(将数据库的模型数据等放在另一个项目中) (域)然后为这些接口创建接口和实现,然后使用Ninja将其连接到控制器.

并且所有与数据库的连接仅来自数据层解决方案,这是viewModel中Web解决方案中唯一的模型

控制器

public class ProductController : Controller
{

    private IProductRepository repository;

    public ProductController(IProductRepository productRepository)
    {
        this.repository = productRepository;
    }
    ....
}
Run Code Online (Sandbox Code Playgroud)

和Ninject

 ninjectKernel.Bind<IProductRepository>().To<EFProductRepository>();
Run Code Online (Sandbox Code Playgroud)

另一方面,在我的上一份工作(网站管理员)中,公司使用了另一种模式用于mvc项目(我现在正在使用这种模式).

这些项目只使用One Solution并使用Static Classes来处理数据层

我不喜欢依赖注入,这太复杂了,'f12'你只看到了接口而不是Concrete类

一些问题:

  1. 哪种模式更适合性能(快速网站)?
  2. 不好用"public Db db = new Db();" 在控制器中,而不是仅在域层(解决方案)中使用它?
  3. 使用依赖注入有什么好处?使用我的模式是不是很糟糕?
  4. 将项目拆分为数据层的2个解决方案有什么好处?

例:

 public class LanguageController : AdminController
    {
         public Db db = new Db();

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        //
        // GET: /Admin/Language/
        public ActionResult Index()
        {
            return View(db.Languages.ToList());
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(short id)
        {
            Language language = db.Languages.Find(id);
            db.Languages.Remove(language);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    ...
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*vid 6

哪种模式更适合性能(快速网站)?

无法回答.您可以在这两种方法中使用不具有高性能的代码.不要试图过早地优化性能,优化干净和可支持的代码,并解决在实际场景中实际观察到的性能瓶颈.

不好用"public Db db = new Db();" 在控制器中,而不是仅在域层中使用它(解决方案)

这是一个分离问题和隔离依赖关系的问题.如果您的控制器在内部实例化与数据库的连接,那么该控制器只能在该数据库的上下文中使用.这将使单元测试控制器非常困难.这也意味着更换数据库意味着修改控制器,在这种情况下不需要修改.

依赖注入框架只是解决依赖性倒置原则的一种方法.这个想法是,如果对象A(控制器)需要对象B的实例(数据库对象),那么它应该要求提供实例,而不是在内部实例化它.这里的直接好处是,对象B可以只是一个可以有许多不同实现的接口或抽象类.对象A不应该关心给它的实现,只要它满足相同的可观察行为即可.

通过反转依赖项(无论是否使用依赖项注入框架),可以从控制器中删除对数据库的依赖性.控制器只处理客户端发起的请求.其他东西处理数据库依赖.这使得这两个单独的对象更具可移植性和可重用性.

使用依赖注入有什么好处?使用我的模式是不是很糟糕?

往上看.依赖注入是实现依赖性反转的一种方式,这是本案例的核心目标.请注意,有几种不同的方法可以实现此目的.一些框架更喜欢构造函数注入,一些支持属性/ setter注入等.我个人倾向于使用服务定位器模式,这具有能够抽象依赖注入器本身的依赖性的额外好处.

如果您在使用它时遇到任何问题,那么使用您的方法只会"不好".有很好的模式可以解决各种问题,但是如果你的项目没有合法地解决这些问题,那么使用这些模式会过度工程,实际上会损害代码的可支持性.因此,与任何事情一样,"这取决于".

将项目拆分为数据层的2个解决方案有什么好处?

两个解决方案 或者同一解决方案中的两个项目?(导致两个程序集.)优点是您可以重用一个而不依赖另一个.例如,在您发布的一些代码中,存在对存储库模式的暗示.如果您的程序集仅用于为后端数据实现存储库,那么任何应用程序都可以使用这些存储库.相反,它直接在MVC应用程序中实现,然后没有其他应用程序可以使用它,它与MVC应用程序紧密耦合.

如果您永远不需要重新使用该功能,那么这不是世界末日.如果您想重新使用该功能,将其分离为内部隔离其依赖项的可移植程序集将允许这样做.

  • @DanielEzra:完成.您正在寻找的是一些入门教程和依赖注入的示例.你问的是一个不错的问题,但它处于*非常*的概念层面.我真正能给出的唯一建议是练习,看看你需要的地方.我个人在我的代码中经常使用依赖注入,但我写的大部分内容都可以从使用它中获益.并非每个项目都会从中受益.与其他任何东西一样,依赖注入框架也是一种工具.它应该只在有益的地方应用(并正确应用). (2认同)
  • @CharlieBrown:虽然无条件地宣传DI并不合适,但在大多数情况下,新手会从学习中受益并遵循这一原则.请注意,对于新手来说,"只有在它有益的地方"才真正意义不大,并且可能不应该被解读为"如果你不理解就不要使用".我在辅导方面的经验是,开发人员可以从学习和关注DI以及罕见的情况中获益,因为他们并不总是因为DI太难(令人惊讶的是这是可能的). (2认同)
  • @WiktorZychla你的观点很好.DI不仅应该尽早和经常学习,它应该是如此常见,以至于我们不需要特殊名称.我们应该称之为"你做什么,因为它是正确的做法".DI有助于确保软件开发的bext原则之一; 单一责任原则.DI帮助您分离关注点,以便每个班级只有一个责任,因此,只有一个理由可以改变. (2认同)