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

发布于 2024-12-10 19:27:51 字数 384 浏览 0 评论 0原文

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

正常的教科书 3 层应用程序应该类似于

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

文稿不应该了解有关数据访问的任何信息。对于 EF,所有层都需要了解模型。所以我的架构现在看起来更像是

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

我在这里遗漏了一些东西还是我以错误的方式思考这个问题?

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我很OK 2024-12-17 19:27:51

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

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

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

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

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

它看起来像这样:

瘦控制器:

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

我的存储库“属性”是从我的 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 不关心,只知道接口)

  • ViewModels 是视图的输入(ViewModel 可以直接是您的业务模型,或者您可以使用 AutoMapper 来创建“纯”ViewModels)

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)

梦里的微风 2024-12-17 19:27:51

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

You can think of your EF entities as data objects, and have separate view-models that are passed into the views. Data from your EF objects can be used to populate the view models (libraries like AutoMapper are useful here). This way, your views never have a direct dependency on EF objects, only on your view-models.

眼眸里的那抹悲凉 2024-12-17 19:27:51

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

可以通过以下地址下载本书:

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

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

http://microsoftnlayerapp.codeplex.com/< /a>

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

书中还解释了应用程序应该分为更多层,他们解释了表示层、应用程序层、域层、基础设施层(主要是数据持久性层)、横切层和分布式服务层。

I can recommend you really good (I think) book about domain driven architecture design on .NET platform. Book si called N-layered domain driven architecture guid with .NET 4.0. In book is explained how to create good architecture with EF and MVC (and many other stuff like Silverlight, IoC with Unity etc.).

Book can be downloaded on this address:

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

Also sample application is very interesting:

http://microsoftnlayerapp.codeplex.com/

Best way how to create entities for EF is creating POCO classes independent on persistent layer. These domain entities are included in Domain (Business) logic layer.

In book is also explained that application should be devided into more layers, they explaining Presentation, Appliaction, Domain, Infrastructure (data persistence mostly), Cross-cutting and Distributed services layers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文