如何使用EF构建ASP.Net MVC应用程序?

时间:2011-10-19 03:36:56

标签: asp.net-mvc entity-framework architecture

我在构建如何使用Entity Framework构建MVC应用程序到n层应用程序时遇到了一些麻烦。

正常的教科书3层应用应该看起来像

数据访问 - >业务逻辑 - >演示文稿

演示文稿不应该知道有关数据访问的任何信息。使用EF,所有图层都需要了解模型。所以我的架构看起来更像是

Data Access->Business Logic
     |               |
      ---------------
             |
            MVC

我在这里遗漏了什么,或者我是以错误的方式思考这个问题?

我是否应该将EF本身视为数据访问层并将实体置于业务逻辑中?

3 个答案:

答案 0 :(得分:9)

好吧,我想你的问题是,如何在MVC应用程序中构建“层”。 看看这个简单的架构,我将它用于我的MVC应用程序,它看起来干净而高效。

  1. 解决方案中的项目 - 业务模型 - 充满代表业务领域的POCO类的简单类库。您可以在此处使用数据注释,使用验证逻辑的元数据类等。

  2. project - 基于EF的存储库 - 另一个简单的类库;这里是定义的上下文(EF代码首先很好,但你可以先使用EF数据库或首先使用模型 - 你只需要将POCO T4模板添加到业务模型类库中,没什么大不了的)和一组类 - 存储库

  3. 项目 - 我通常称它为“ServiceLayer”左右(我建议更好的名字:) - 它只包含接口,用于存储库和其他服务(在单独的项目中实现),这将是我的MVC(或基于任何其他技术的应用程序; 2.project中的存储库实现了这些接口

  4. 项目 - MVC网站。它使用依赖注入(在DependencyResolver中构建,我喜欢使用Ninject容器)来映射存储库(和其他服务);然后你可以使用构造函数注入控制器,或者一些“懒惰”方法(见下文)

  5. 它看起来像这样:

    Skinny控制器:

    public class SomethingController : BaseController
    {
        public ActionResult DoSomething(SomeBusinessThing input)
        {
             if (ModelState.IsValid)
             {
                 var result = CustomerRepository.DoSomeBusinessLogicAndPersistenceAndStuff(input);
                 return View(result); // you can use AutoMapper here, if you dont want to use business object as viewmodels
             }
        }
    }
    

    我的存储库“property”继承自我的BaseController:

    public class BaseController : Controller 
    {
        // ... other stuff used by all (or multiple) controllers
    
        private ICustomerRepository _customerRepository;
            protected ICustomerRepository CustomerRepository
            {
                get
                {
                    if (_customerRepository== null)
                        _customerRepository= DependencyResolver.Current.GetService();
                    return _customerRepository;
                }
            }
    }
    

    如果您的控制器使用许多服务,您可以使用这个“懒惰”DI,但每个操作只能使用1-2个,因此使用构造函数注入所有服务会效率低下。有人可以通过这种方式告诉你“隐藏”依赖,但是如果你把所有这些东西放在一个地方--BaseController,那没关系。

    好吧,存储库的实现确实是您的业务。 MVC应用程序甚至不知道你正在使用EF,它只知道服务的接口,并不关心底层实现(如果你需要,你可以随时切换!)

    结论:

    • 控制器是瘦的 - 没有业务逻辑

    • 模型是FAT - 在这种情况下,存储库封装了所有业务逻辑(您可以确定使用其他类型的服务,例如一些计算器用于处理等等,请记住,MVC不关心,只知道接口)

    • ViewModel是Views的输入(ViewModel可以直接作为您的商业模式,也可以使用AutoMapper创建“纯”ViewModels)

答案 1 :(得分:5)

您可以将EF实体视为数据对象,并将单独的视图模型传递给视图。来自EF对象的数据可用于填充视图模型(像AutoMapper这样的库在这里很有用)。这样,您的视图永远不会直接依赖于EF对象,只能在视图模型上。

答案 2 :(得分:0)

我可以推荐一本关于.NET平台上域驱动架构设计的好书(我认为)。使用.NET 4.0编写称为N层域驱动架构的si。在书中解释了如何使用EF和MVC(以及许多其他东西,如Silverlight,IoC和Unity等)创建良好的架构。

可以在此地址下载书籍:

http://msdn.microsoft.com/es-es/architecture/en/

示例应用程序也非常有趣:

http://microsoftnlayerapp.codeplex.com/

如何为EF创建实体的最佳方法是创建独立于持久层的POCO类。这些域实体包含在域(业务)逻辑层中。

书中还解释了应用程序应分为更多层,它们解释了演示文稿,应用程序,域,基础架构(主要是数据持久性),交叉和分布式服务层。