從零開始學習ABP vNext開發(fā) (二) 領(lǐng)域?qū)?/h2>

我們?nèi)匀皇褂谩稄牧汩_始進行ABP項目開發(fā)》系列中的項目需求。

Poem需求描述

我們使用一個簡單的項目來說明問題,這是一款針對全唐詩的小應(yīng)用,可以對唐詩和作者進行簡單的查詢,可以對唐詩進行自定義的分類,還有一些簡單的小游戲,比如可以將一句唐詩的順序打亂,用戶進行正確的排序等。數(shù)據(jù)庫已經(jīng)有了,在Sql Server中,將來可能需要支持Sqlite。數(shù)據(jù)模型如下:

image

相關(guān)的數(shù)據(jù)庫腳本發(fā)布在這里:Poem相關(guān)數(shù)據(jù)庫表的Sql語句

增加領(lǐng)域?qū)?/h2>

在解決方案中增加一個新的.Net Core類庫項目作為領(lǐng)域?qū)?,命名命名為ZL.AbpNext.Poem.Core:


圖片.png

按照[從零開始學習ABP vNext開發(fā) (一)——從控制臺項目入手]中“創(chuàng)建Abp模塊”的描述,創(chuàng)建新的模塊,名稱為PoemCoreModule:

using Volo.Abp.Modularity;

namespace ZL.AbpNext.Poem.Core
{
    public class PoemCoreModule:AbpModule
    {
    }
}

然后創(chuàng)建一個子目錄,名稱為Poems,在這個目錄中創(chuàng)建第一個實體,名稱為Poet:

using Volo.Abp.Domain.Entities;

namespace ZL.AbpNext.Poem.Core.Poems
{
    /// <summary>
    /// 詩人,從ABP Entity派生
    /// </summary>
    public class Poet : Entity<int>
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public virtual string Name { get; set; }

        /// <summary>
        /// 介紹
        /// </summary>
        public virtual string Description { get; set; }
        
    }
}

使用EF連接數(shù)據(jù)庫

下面,創(chuàng)建數(shù)據(jù)訪問層,使用EF從數(shù)據(jù)庫中獲取數(shù)據(jù)。在解決方案中增加另一個類庫項目,命名為ZL.AbpNext.Poem.EF,使用Nuget程序包管理器,安裝如下程序包:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Volo.Abp.EntityFrameworkCore
  • Volo.Abp.EntityFrameworkCore.SqlServer

然后,可以創(chuàng)建需要的DbContext,這里,Abp vNext與前一代Abp有很大的區(qū)別。
首先,需要為DbContext創(chuàng)建一個接口:

using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using ZL.AbpNext.Poem.Core.Poems;

namespace ZL.AbpNext.Poem.EF.EntityFramework
{
    [ConnectionStringName("Poem")]
    public interface IPoemDbContext : IEfCoreDbContext
    {
        DbSet<Poet> Poets { get; set; }
    }
}

接下來創(chuàng)建DbContext類:

using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using ZL.AbpNext.Poem.Core.Poems;

namespace ZL.AbpNext.Poem.EF.EntityFramework
{
    [ConnectionStringName("Poem")]
    public class PoemDbContext : AbpDbContext<PoemDbContext>,IPoemDbContext
    {
        public virtual DbSet<Poet> Poets { get; set; }

        public PoemDbContext(DbContextOptions<PoemDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            //映射Poet到數(shù)據(jù)庫表
            modelBuilder.Entity<Poet>(b =>
            {
                b.ToTable("Poet");
                
                //映射實體與數(shù)據(jù)庫中的字段,將Id映射到數(shù)據(jù)庫表的PoetID字段
                b.Property(p => p.Id)
                        .HasColumnName("PoetID");
                b.ConfigureByConvention();
            });
        }
    }
}

我們已經(jīng)看到了Abp vNext在DbContext上進行的改進:1)增加了ConnectionStringName標記,可以自動從配置文件讀取連接字符串信息。2)增加了DbContext的接口。

這里需要注意的是:Abp的實體都是從Entity中繼承的,使用Id作為關(guān)鍵字標識,而我們已經(jīng)存在的數(shù)據(jù)庫表的關(guān)鍵字字段名是PoetID,這就需要在OnModelCreating中進行映射。

接下來我們創(chuàng)建數(shù)據(jù)模塊PoemDataModule:

using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
using ZL.AbpNext.Poem.Core;
using ZL.AbpNext.Poem.EF.EntityFramework;

namespace ZL.AbpNext.Poem.EF
{
    [DependsOn(
    typeof(PoemCoreModule),
    typeof(AbpEntityFrameworkCoreModule)
    )]
    public class PoemDataModule:AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddAbpDbContext<PoemDbContext>(options =>
            {
                options.AddDefaultRepositories(includeAllEntities: true);
            });

            Configure<AbpDbContextOptions>(options =>
            {
                /* The main point to change your DBMS.
                 * See also BookStoreMigrationsDbContextFactory for EF Core tooling. */
                options.UseSqlServer();
            });
        }
    }
}

這里也有很大的改進,很多初始化的工作不需要在PreInitializes中進行處理,在ConfigureServices中,以更符合.Net Core的方式進行處理。這段代碼為所有實體生成缺省的Repository:

            context.Services.AddAbpDbContext<PoemDbContext>(options =>
            {
                options.AddDefaultRepositories(includeAllEntities: true);
            });

對于通用的增刪改等操作,不需要再編寫重復的代碼。

改造控制臺客戶端訪問數(shù)據(jù)庫

現(xiàn)在我們改造客戶端,使它可以調(diào)用我們新編寫的模塊,訪問數(shù)據(jù)庫中的詩人數(shù)據(jù)。
首先,增加項目依賴項,項目結(jié)構(gòu)如下:


圖片.png

還需要在項目中增加appsettings.json,在配置文件中設(shè)置數(shù)據(jù)庫鏈接字符串:

{
  "ConnectionStrings": {
    "Poem": "Server=localhost;Database=PoemNew;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "exclude": [
    "**/bin",
    "**/bower_components",
    "**/jspm_packages",
    "**/node_modules",
    "**/obj",
    "**/platforms"
  ]
}

注意:這個文件需要設(shè)置為“如果較新則復制”


圖片.png

然后,在PoemConsoleClientModel中增加對PoemCoreModule和PoemDataModule的依賴:

using Volo.Abp.Modularity;
using ZL.AbpNext.Poem.Core;
using ZL.AbpNext.Poem.EF;

namespace ZL.AbpNext.Poem.ConsoleClient
{
    [DependsOn(
    typeof(PoemCoreModule),
    typeof(PoemDataModule))]
    public class PoemConsoleClientModule:AbpModule
    {

    }
}

接下來,我們改造Service:

using System;
using System.Linq;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using ZL.AbpNext.Poem.Core.Poems;

namespace ZL.AbpNext.Poem.ConsoleClient
{
    public class Service : ITransientDependency
    {
        IRepository<Poet> repository;
        IUnitOfWorkManager uowManager;
        public Service(IRepository<Poet> repository, IUnitOfWorkManager uowManager)
        {
            this.repository = repository;
            this.uowManager = uowManager;
        }
        public void Run()
        {
            //Console.WriteLine("你好");
            using (var uow = uowManager.Begin(new AbpUnitOfWorkOptions()))
            {
                //獲取第一個詩人
                var poet = repository.FirstOrDefault();

                Console.WriteLine(poet.Name);
            }
        }
    }
}

由于框架支持依賴注入,所以,我們只需要在構(gòu)造函數(shù)中增加需要的服務(wù)就可以了,不需要關(guān)心如何獲取這些服務(wù)。這里我們需要Poet的repository,和執(zhí)行執(zhí)行工作單元的管理器,所以在構(gòu)造函數(shù)中增加這兩個參數(shù)。在執(zhí)行方法中,就可以使用repository獲取數(shù)據(jù)了。
到這里改造就完成了,主程序Program不需要修改。運行結(jié)果如下:


圖片.png

小結(jié)

  • 解決方案中的每個項目都是一個ABP模塊,在模塊中定義模塊之間的依賴關(guān)系。
  • 使用AbpApplicationFactory創(chuàng)建需要的模塊,并調(diào)用Initialize進行模塊初始化。
  • 可以使用ServiceProvider.GetService獲取需要使用的對象。
  • 在模塊的ConfigureServices方法中進行參數(shù)設(shè)置。

下一步工作

下一步,我們需要增加其它幾個實體到Poem.Core中,并增加應(yīng)用層(Application)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容