首页 > 解决方案 > 通过业务层在表示层初始化数据库上下文(域层)

问题描述

我是一个相当新的程序员并且有一个 ASP.NET Core Web 应用程序。一切都很好,直到我注意到我需要层(业务、域和演示),因为我知道这是一个最佳实践。由于这些层的创建,问题出现了。

在我的启动中,我有一个用于初始化数据库的配置方法。但是,由于 DishInfoContext 类现在位于 Domain 项目中,因此不应再直接从 Presentation 项目中访问它。

我尝试在业务层中创建一个类和方法来注入 DishInfoContext,但它不起作用。

Startup.cs中的配置方法:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        string connection = @"Server=(localdb)\mssqllocaldb;Database=DishesDB;Trusted_Connection=True;ConnectRetryCount=0";
        services.AddDbContext<DishInfoContext>(options => options.UseSqlServer(connection));

        // So, here I guess DishInfoContext should be replaced with something else?

        services.AddScoped<IDishService, DishService>();
    }

DishInfoContext 类:

namespace MyDishesApp.Domain.Entities
{
public class DishInfoContext : DbContext
{
    public DishInfoContext(DbContextOptions<DishInfoContext> options) : base(options)
    {
        Database.Migrate();
    }

    public DbSet<Dish> Dishes { get; set; }
    public DbSet<Ingredient> Ingredients { get; set; }
}
}

我应该怎么做才能通过业务层将 DishInfoContext 传递给表示层?还是我应该尝试另一种方法?

我希望我足够具体,感谢您的帮助!

PS:我还在业务层为我的存储库创建了服务,因为存储库位于域层中。

标签: asp.net-coredomain-driven-designentity-framework-core

解决方案


您陷入了遵循您不理解的“建议”的陷阱。这对于新开发人员来说很常见,因为天生就有“正确”做事的愿望,但您还不明白这意味着什么或需要什么。

首先,您在这里所做的称为 N-Tier,尽管几十年来它一直是软件开发的主要内容,但它并不总是正确的选择。特别是,如果您不习惯该模式并且您的应用程序实际上并不需要它,那么您最终可能会在您的应用程序中引入严重的问题和低效率。

你需要意识到这里没有真正的分离。您的 Web 应用程序(您所说的表示层)需要数据库连接。因此,这里有一个硬依赖。您最大的希望是抽象访问数据库的大部分代码,但您仍然需要依赖可以在控制器中使用的东西来获取数据。这里的典型方法是实现存储库/工作单元模式。这将成为您的数据层。但是,大多数人错过的是,如果您使用的是 EF,就是您的数据层。数据访问已经被抽象化了,所以你的应用只是依赖于 EF,而不是你创建的一些自定义类库。EF 是一个 ORM,因此已经实现存储库/工作单元模式。

总而言之,只需直接在您的 Web 应用程序中使用您的 EF 上下文。如果您的应用程序最终变得足够大/复杂到足以保证将其抽象出来,您应该考虑微服务或 CQRS 模式。然而,两者都不是微不足道的,对于一个简单的应用程序来说很容易过度杀伤。

我能给你的最好建议是简单地构建你的应用程序。不要担心模式或其他人所说的话。你的应用程序决定了应该采用什么模式或架构风格,而不是相反。当您因为“应该”而开始做某事时,那就是您的应用程序脱轨的时候。所有这些的目标是干净、有文档且易于维护的代码。如果你有一个单层,那么你不需要任何其他东西。


推荐阅读