通过业务层在表示层初始化数据库上下文(域层)

时间:2018-07-05 12:32:57

标签: asp.net-core domain-driven-design entity-framework-core

我是一个相当新的程序员,并且拥有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:我还为业务层中的存储库创建了服务,因为存储库位于域层。

1 个答案:

答案 0 :(得分:1)

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

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

您需要认识到这里没有真正的分离。您的Web应用程序(您指的是表示层)需要数据库连接。结果,这里有一个严格的依赖性。您最希望得到的是抽象访问数据库的大多数代码,但是您仍然需要依靠控制器中使用的某些东西来获取数据。这里的典型方法是实现工作模式的存储库/单元。这样便成为您的数据层。但是,大多数人会错过的是,如果您使用的是EF,则那个是您的数据层。数据访问已被抽象,因此您的应用仅对EF有依赖,而不是您创建的某些自定义类库。 EF是一个ORM,因此已经已经实现了工作模式的存储库/单元。

总之,请在您的Web应用程序中直接使用EF上下文。如果您的应用程序最终变得足够大/复杂,以至于需要将其抽象化,则应考虑使用微服务或CQRS模式。但是,两者都不是简单的,对于一个简单的应用程序来说,它们很容易过大。

我能给您的最好建议是仅构建您的应用程序。不用担心模式或别人怎么说。您的应用程序决定应采用哪种模式或建筑风格,而不是相反。当您因为“应该”开始做某事时,那就是您的应用脱离正常工作的时候。所有这一切的目标是提供干净,文档化,易于维护的代码。如果只有一层,那么您就不需要其他任何东西了。