(精华)2020年8月22日 ABP vNext 应用层的使用

ABP vNext微服务框架 专栏收录该内容
12 篇文章 5 订阅

现在我们来创建应用层,这样客户端只与应用层打交道就可以了。
与前面创建领域层模块和数据访问EF模块一样,我们在解决方案中增加.Net Core类库项目,作为服务层模块,将项目命名为ZL.AbpNext.Poem.Application,我们需要使用Nuget管理器,为项目增加必要的依赖项,如下:
在这里插入图片描述
然后,增加一个Abp模块,名称为PoemApplicationModule,这个模块依赖于PoemCoreModule。
接下来,创建一个目录Poems,在这个目录中增加一个Dto类PoetDto:

namespace ZL.AbpNext.Poem.Application.Poems
{
    public class PoetDto:EntityDto<int>
    {
        public string Name { get; set; }

        public string Description { get; set; }
    }
}

DTO的目的是隔离客户端与领域模型,但很多情况下,DTO与领域模型基本上是相同的,ABP使用AutoMapper实现DTO到领域实体的映射。这需要创建一个映射Profile:

using ZL.AbpNext.Poem.Core.Poems;

namespace ZL.AbpNext.Poem.Application.Poems
{
    public class PoemAppAutoMapperProfile : Profile
    {
        public PoemAppAutoMapperProfile()
        {
            CreateMap<Poet, PoetDto>();
        }
    }
}

还需要在模块中进行声明:

using System;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using ZL.AbpNext.Poem.Application.Poems;
using ZL.AbpNext.Poem.Core;

namespace ZL.AbpNext.Poem.Application
{
    [DependsOn(
        typeof(PoemCoreModule), 
        typeof(AbpAutoMapperModule))]
    public class PoemApplicationModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Configure<AbpAutoMapperOptions>(options =>
            {
                options.AddProfile<PoemAppAutoMapperProfile>(validate: true);
            });
        }
    }
}

现在创建IPoemAppService接口:

using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;

namespace ZL.AbpNext.Poem.Application.Poems
{
    public interface IPoemAppService:IApplicationService
    {
        /// <summary>
        /// 获取诗人分页
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        PagedResultDto<PoetDto> GetPagedPoets(PagedResultRequestDto dto);
    }
}

我们先只增加一个函数,获取分页的诗人。然后我们创建PoemAppService:

using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using ZL.AbpNext.Poem.Core.Poems;

namespace ZL.AbpNext.Poem.Application.Poems
{
    public class PoemAppService : ApplicationService, IPoemAppService
    {
        private readonly IRepository<Poet> _poetRepository;
        public PoemAppService(IRepository<Poet> poetRepository)
        {
            _poetRepository = poetRepository;
        }
        public PagedResultDto<PoetDto> GetPagedPoets(PagedResultRequestDto dto)
        {
           using (var uow = UnitOfWorkManager.Begin(new AbpUnitOfWorkOptions()))
            {
                var count = _poetRepository.Count();
                var lst = _poetRepository.OrderBy(o => o.Id).PageBy(dto).ToList();
                var items = new List<PoetDto>();
                
                return new PagedResultDto<PoetDto>
                {
                    TotalCount = count,
                    Items = ObjectMapper.Map<List<Poet>, List<PoetDto>>(lst)
                };
            }
            
        }
    }
}

另外中直接创建crud服务,不推荐使用:

public interface IShoppingCartAppService:ICrudAppService<ShoppingCartDto, int, PagedAndSortedResultRequestDto, ShoppingCartInputDto, ShoppingCartUpdateDto>//IApplicationService
    {
         ShoppingCartDto Create(ShoppingCartInputDto input);
        //Task CreateAsync(ShoppingCartInputDto sci);
    }
--------------------------------------
public class ShoppingCartAppService : CrudAppService<ShoppingCarts,ShoppingCartDto,int,PagedAndSortedResultRequestDto, ShoppingCartInputDto, ShoppingCartUpdateDto>, IShoppingCartAppService//ApplicationService, IShoppingCartAppService
    {


        public ShoppingCartAppService(IRepository<ShoppingCarts,int> repositoryShoppingCarts):base(repositoryShoppingCarts)
        {
            _repositoryShoppingCarts = repositoryShoppingCarts;
        }



        private readonly IRepository<ShoppingCarts,int> _repositoryShoppingCarts;

        //public ShoppingCartAppService(IRepository<ShoppingCarts> repositoryShoppingCarts)
        //{
        //    this._repositoryShoppingCarts = repositoryShoppingCarts;
        //}
        public override ShoppingCartDto Create(ShoppingCartInputDto input)
        {
            var shoppingCart = ObjectMapper.Map<ShoppingCarts>(input);
            _repositoryShoppingCarts.Insert(shoppingCart);
            return ObjectMapper.Map<ShoppingCartDto>(shoppingCart);
        }
        //public override async Task CreateAsync(ShoppingCartInputDto sci)
        //{
        //    var shoppingCart = ObjectMapper.Map<ShoppingCarts>(sci);
        //    await _repositoryShoppingCarts.InsertAsync(shoppingCart);
        //}
    }

到这里,应用层编写完成,下面使用Client调用应用层。
首先,在PoemConsoleClientModule中增加PoemApplicationModule依赖:

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

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

    }
}

然后,改造Service,使用服务层访问数据:

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

namespace ZL.AbpNext.Poem.ConsoleClient
{
    public class Service : ITransientDependency
    {
        //IRepository<Poet> repository;
        //IUnitOfWorkManager uowManager;
        IPoemAppService appService;
        //public Service(IRepository<Poet> repository, IUnitOfWorkManager uowManager)
        //{
        //    this.repository = repository;
        //    this.uowManager = uowManager;
        //}
        public Service(IPoemAppService appService)
        {
            this.appService = appService;
        }
        public void Run()
        {
            //Console.WriteLine("你好");
            //using (var uow = uowManager.Begin(new AbpUnitOfWorkOptions()))
            //{
            //    //获取第一个诗人
            //    //var poet = repository.FirstOrDefault();
            //    var poet = repository.AsQueryable().Include(p => p.Poems).FirstOrDefault();
            //    Console.WriteLine(poet.Name);
            //    Console.WriteLine(poet.Poems.Count());
            //    Console.WriteLine(poet.Poems.ToList()[0].Author.Name);
            //}
            var res=appService.GetPagedPoets(new Volo.Abp.Application.Dtos.PagedResultRequestDto { MaxResultCount = 10, SkipCount = 0 });
            Console.WriteLine(res.TotalCount);
            foreach(var dto in res.Items)
            {
                Console.WriteLine(dto.Name);
            }
        }
    }
}

运行如下:

在这里插入图片描述

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
<p> <span style="font-size:14px;color:#337FE5;">【为什么学爬虫?】</span> </p> <p> <span style="font-size:14px;">       1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到!</span> </p> <p> <span style="font-size:14px;">       2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站</span> </p> <p> <br /> </p> <span style="font-size:14px;color:#337FE5;">【课程设计】</span> <p class="ql-long-10663260"> <span> </span> </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 网络请求:模拟浏览器的行为从网上抓取数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 </li> <li class="" style="font-size:11pt;color:#494949;"> Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。 </p> <p style="font-size:11pt;color:#494949;">   </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> <br /> </p> <p> <br /> </p> <p> <span style="font-size:14px;background-color:#FFFFFF;color:#337FE5;">【课程服务】</span> </p> <p> <span style="font-size:14px;">专属付费社群+定期答疑</span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"><br /> </span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"></span> </p>
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值