如何使用 EF 构建 ASP.Net MVC 应用程序? [英] How do architect an ASP.Net MVC app with EF?

查看:25
本文介绍了如何使用 EF 构建 ASP.Net MVC 应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在构思如何将带有实体框架的 MVC 应用程序构建为 n 层应用程序时遇到了一些麻烦.

普通的、教科书式的 3 层应用程序应该看起来像

数据访问->业务逻辑->展示

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

数据访问->业务逻辑||---------------|MVC

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

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

解决方案

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

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

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

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

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

它看起来像这样:

瘦控制器:

<前>公共类SomethingController:BaseController{公共 ActionResult DoSomething(SomeBusinessThing 输入){如果(模型状态.IsValid){var 结果 = CustomerRepository.DoSomeBusinessLogicAndPersistenceAndStuff(input);返回视图(结果);//你可以在这里使用 AutoMapper,如果你不想使用业务对象作为视图模型}}}

我的存储库属性"是从我的 BaseController 继承的:

<前>公共类 BaseController :控制器{//...所有(或多个)控制器使用的其他东西私人 ICustomerRepository _customerRepository;受保护的 ICustomerRepository CustomerRepository{得到{如果(_customerRepository== null)_customerRepository= DependencyResolver.Current.GetService();返回 _customerRepository;}}}

如果您的控制器使用许多服务,您可以使用这种懒惰"的 DI,但每个操作只有 1-2 个,因此将所有这些服务注入构造函数会有点低效.有人可能会说你通过这种方式隐藏"了依赖关系,但如果你将所有这些东西放在一个地方 - BaseController,这没什么大不了的.

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

结论:

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

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

  • ViewModels 是 Views 的输入(ViewModel 可以直接作为你的业务模型,或者你可以使用 AutoMapper 来创建纯"ViewModels)

I'm having a little bit of trouble conceptualizing how to architect an MVC App with Entity Framework into a n-tiered app.

The normal, textbook 3-tiered app should look something like

Data Access->Business Logic->Presentation

The presentation shouldn't know anything about the data access. With EF, ALL layers need to know about the model. So my architecture now looks more like

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

Am I missing something here or am I thinking about this in the wrong way?

Should I be thinking of EF itself as the data access layer and put the entities in the business logic?

解决方案

Well, I suppose your question is, how to architect "layers" in MVC application. Take a look at this simple architecture, I use it for my MVC apps and it seems to be clean and efficient.

  1. project in solution - business model - simple class library full of POCO classes representing business domain. You can use data annotation here, metadata classes for validation logic, etc.

  2. project - EF-based repositories - another simple class library; here is defined context (EF code first is great, but you can use EF database first or model first - you just have to add POCO T4 template to the business model class library, no big deal) and set of classes - repositories

  3. project - i usually call it "ServiceLayer" or so (i am open for suggestion for better name :) - it contains only interfaces, for repositories and other services (implemented in separate projects) which will my MVC (or any other technology) based application use; repositories from 2.project implement these interfaces

  4. project - MVC website. It uses dependency injection (build in DependencyResolver, and i love to use Ninject container) for mapping repositories (and other services); Then you can use constructor injection into controllers, or some "lazy" approach (see below)

It looks something like this :

Skinny controller :

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
         }
    }
}

My repository "property" is inherited from my 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;
            }
        }
}

You can use this "lazy" DI if your controller use many services, but only 1-2 per action, so it would be kind of inefficient to inject all of them with constructor. Somebody could tell you are "hiding" dependency this way, but if you keep all this stuff in one place - BaseController, its no big deal.

Well, implementation of repository is really your business. MVC application dont even know you are using EF, it knows only interfaces of services and doesnt care about underlaying implementation (which you can switch any time later if you need to !)

Conslusion :

  • Controllers are skinny - no business logic

  • Model is FAT - and in this case, repositories encapsulate all the business logic (you can sure use other type of services as well, for example some calculators for processing etc., remember, MVC doesnt care, knows only interfaces)

  • ViewModels are input for Views (and ViewModel can be your business model directly, or you can use AutoMapper for creating "pure" ViewModels)

这篇关于如何使用 EF 构建 ASP.Net MVC 应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆