• ABP学习入门系列(四)(创建Service)


    一,一些相关解释

    Service 在应用服务层也就是application层。应用服务用于将领域(业务)逻辑暴露给展现层。展现层通过传入DTO(数据传输对象)参数来调用应用服务,而应用服务通过领域对象来执行相应的业务逻辑并且将DTO返回给展现层。

    也就是这样避免了应用服务层和展现层的,直接数据交互,而是通过dto实现了数据过滤,这样就可以较好的避免非法数据的传入传出。另外大头还要实现数据隐藏,方便扩展等好处。

    创建应用服务时需要注意:

    1.service 要实现IApplicationService接口。

    2,ABP为IApplicationService提供默认实现ApplicationService

    3,ABP中,一个应用服务方法默认是一个工作单元(Unit of Work)。ABP针对UOW模式自动进行数据库的连接及事务管理,且会自动保存数据修改。

    二,XXService和IXXService

    1,如下TaskAppService 继承了LearningMpaAbpAppServiceBase,并实现了ITaskAppService接口

    using Abp.Application.Services.Dto;
    using Abp.Authorization;
    using Abp.AutoMapper;
    using Abp.Domain.Repositories;
    using Abp.Events.Bus;
    using Abp.Extensions;
    using Abp.Linq.Extensions;
    using Abp.Net.Mail.Smtp;
    using Abp.Notifications;
    using Abp.Runtime.Session;
    using AutoMapper;
    using LearningMpaAbp.Authorization;
    using LearningMpaAbp.Authorization.Users;
    using LearningMpaAbp.Tasks.Dtos;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Dynamic.Core;
    using System.Threading.Tasks;
    
    namespace LearningMpaAbp.Tasks
    {
        /// <summary>
        ///     Implements <see cref="ITaskAppService" /> to perform task related application functionality.
        ///     Inherits from <see cref="ApplicationService" />.
        ///     <see cref="ApplicationService" /> contains some basic functionality common for application services (such as
        ///     logging and localization).
        /// </summary>
        public class TaskAppService : LearningMpaAbpAppServiceBase, ITaskAppService
        {
            private readonly INotificationPublisher _notificationPublisher;
            private readonly ISmtpEmailSender _smtpEmailSender;
            //These members set in constructor using constructor injection.
    
            private readonly IRepository<Task> _taskRepository;
            private readonly IRepository<User, long> _userRepository;
            private readonly ITaskManager _taskManager;
            private readonly ITaskCache _taskCache;
            private readonly IEventBus _eventBus;
    
            /// <summary>
            ///     In constructor, we can get needed classes/interfaces.
            ///     They are sent here by dependency injection system automatically.
            /// </summary>
            public TaskAppService(
                IRepository<Task> taskRepository,
                IRepository<User, long> userRepository,
                ISmtpEmailSender smtpEmailSender,
                INotificationPublisher notificationPublisher,
                ITaskCache taskCache,
                ITaskManager taskManager,
                IEventBus eventBus)
            {
                _taskRepository = taskRepository;
                _userRepository = userRepository;
                _smtpEmailSender = smtpEmailSender;
                _notificationPublisher = notificationPublisher;
                _taskCache = taskCache;
                _taskManager = taskManager;
                _eventBus = eventBus;
            }
    
            public TaskCacheItem GetTaskFromCacheById(int taskId)
            {
                return _taskCache[taskId];
            }
    
            public IList<TaskDto> GetAllTasks()
            {
                var tasks = _taskRepository.GetAll().OrderByDescending(t => t.CreationTime).ToList();
                return Mapper.Map<IList<TaskDto>>(tasks);
            }
    
            public GetTasksOutput GetTasks(GetTasksInput input)
            {
                var query = _taskRepository.GetAllIncluding(t => t.AssignedPerson)
                    .WhereIf(input.State.HasValue, t => t.State == input.State.Value)
                    .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter))
                    .WhereIf(input.AssignedPersonId.HasValue, t => t.AssignedPersonId == input.AssignedPersonId.Value);
    
                //排序
                if (!string.IsNullOrEmpty(input.Sorting))
                    query = query.OrderBy(input.Sorting);
                else
                    query = query.OrderByDescending(t => t.CreationTime);
    
                var taskList = query.ToList();
    
                //Used AutoMapper to automatically convert List<Task> to List<TaskDto>.
                return new GetTasksOutput
                {
                    Tasks = Mapper.Map<List<TaskDto>>(taskList)
                };
            }
    
    
            public PagedResultDto<TaskDto> GetPagedTasks(GetTasksInput input)
            {
                //初步过滤
                var query = _taskRepository.GetAllIncluding(t => t.AssignedPerson)
                    .WhereIf(input.State.HasValue, t => t.State == input.State.Value)
                    .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter))
                    .WhereIf(input.AssignedPersonId.HasValue, t => t.AssignedPersonId == input.AssignedPersonId.Value);
    
                //排序
                query = !string.IsNullOrEmpty(input.Sorting) ? query.OrderBy(input.Sorting) : query.OrderByDescending(t => t.CreationTime);
    
                //获取总数
                var tasksCount = query.Count();
                //默认的分页方式
                //var taskList = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
    
                //ABP提供了扩展方法PageBy分页方式
                var taskList = query.PageBy(input).ToList();
    
                return new PagedResultDto<TaskDto>(tasksCount, taskList.MapTo<List<TaskDto>>());
            }
    
            public async Task<TaskDto> GetTaskByIdAsync(int taskId)
            {
                //Called specific GetAllWithPeople method of task repository.
                var task = await _taskRepository.GetAsync(taskId);
    
                //Used AutoMapper to automatically convert List<Task> to List<TaskDto>.
                return task.MapTo<TaskDto>();
            }
    
            public TaskDto GetTaskById(int taskId)
            {
                var task = _taskRepository.Get(taskId);
    
                return task.MapTo<TaskDto>();
            }
    
            public void UpdateTask(UpdateTaskInput input)
            {
                //We can use Logger, it's defined in ApplicationService base class.
                Logger.Info("Updating a task for input: " + input);
    
                //获取是否有权限
                bool canAssignTaskToOther = PermissionChecker.IsGranted(PermissionNames.Pages_Tasks_AssignPerson);
                //如果任务已经分配且未分配给自己,且不具有分配任务权限,则抛出异常
                if (input.AssignedPersonId.HasValue && input.AssignedPersonId.Value != AbpSession.GetUserId() &&
                    !canAssignTaskToOther)
                {
                    throw new AbpAuthorizationException("没有分配任务给他人的权限!");
                }
    
                var updateTask = Mapper.Map<Task>(input);
                var user = _userRepository.Get(input.AssignedPersonId.Value);
                //先执行分配任务
                _taskManager.AssignTaskToPerson(updateTask, user);
    
                //再更新其他字段
                _taskRepository.Update(updateTask);
    
            }
    
            public void AssignTaskToPerson(AssignTaskToPersonInput input)
            {
                var task = _taskRepository.Get(input.TaskId);
                var user = _userRepository.Get(input.UserId);
                _taskManager.AssignTaskToPerson(task, user);
                //这里有一个问题就是,当开发人员不知道有这个TaskManager时,依然可以通过直接修改Task的AssignedPersonId属性就行任务分配。
    
                //分配任务成功后,触发领域事件,发送邮件通知
                //_eventBus.Trigger(new TaskAssignedEventData(task, user));//由领域服务触发领域事件
    
            }
    
            public int CreateTask(CreateTaskInput input)
            {
                //We can use Logger, it's defined in ApplicationService class.
                Logger.Info("Creating a task for input: " + input);
    
                //判断用户是否有权限
                if (input.AssignedPersonId.HasValue && input.AssignedPersonId.Value != AbpSession.GetUserId())
                    PermissionChecker.Authorize(PermissionNames.Pages_Tasks_AssignPerson);
    
                var task = Mapper.Map<Task>(input);
    
                int result = _taskRepository.InsertAndGetId(task);
    
                //只有创建成功才发送邮件和通知
                if (result > 0)
                {
                    if (input.AssignedPersonId.HasValue)
                    {
                        var user = _userRepository.Load(input.AssignedPersonId.Value);
                        //task.AssignedPerson = user;
                        //var message = "You hava been assigned one task into your todo list.";
    
                        //使用领域事件触发发送通知操作
                        _eventBus.Trigger(new TaskAssignedEventData(task, user));
    
                        //TODO:需要重新配置QQ邮箱密码
                        //_smtpEmailSender.Send("ysjshengjie@qq.com", task.AssignedPerson.EmailAddress, "New Todo item", message);
    
                        //_notificationPublisher.Publish("NewTask", new MessageNotificationData(message), null,
                        //    NotificationSeverity.Info, new[] { task.AssignedPerson.ToUserIdentifier() });
                    }
                }
    
                return result;
            }
    
           
            public void Delete(int id)
            {
                var task = _taskRepository.Get(id);
                if (task != null)
                    _taskRepository.Delete(task);
            }
        }
    }
    

    2,ITaskAppService 继承IApplicationService

    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Dynamic;
    using System.Threading.Tasks;
    using Abp.Application.Services;
    using Abp.Application.Services.Dto;
    using Abp.Linq.Extensions;
    using LearningMpaAbp.Tasks.Dtos;
    
    namespace LearningMpaAbp.Tasks
    {
        public interface ITaskAppService : IApplicationService
        {
            GetTasksOutput GetTasks(GetTasksInput input);
    
            PagedResultDto<TaskDto> GetPagedTasks(GetTasksInput input);
    
            void UpdateTask(UpdateTaskInput input);
    
            int CreateTask(CreateTaskInput input);
    
            Task<TaskDto> GetTaskByIdAsync(int taskId);
    
            TaskDto GetTaskById(int taskId);
    
            void Delete(int taskId);
    
            TaskCacheItem GetTaskFromCacheById(int taskId);
    
            IList<TaskDto> GetAllTasks();
        }
    }
    

    三,Dto 数据传输对象(Data Transfer Objects)用于应用层和展现层的数据传输

    ABP 建议命名 input/ouput 对象类似于 MethodNameInput/MethodNameOutput,对于每个应用服务方法都需要将 Input Output 进行分开定义。甚至你的方法只接
    收或者返回一个值,也最好创建相应的 DTO 类型。 这样会使代码有更好的扩展性

    using System.Collections.Generic;
    
    namespace LearningMpaAbp.Tasks.Dtos
    {
        public class GetTasksOutput
        {
            public List<TaskDto> Tasks { get; set; }
        }
    }

     有一个问题怎么将task实体类转换为dto,这时就需要进行映射了AutoMapper 根据 Task实体创建了 taskDto,并根据命名约定来给
    PersonDto 的属性赋值 。

    以上。。

    参考:http://www.jianshu.com/p/da69ca7b27c6

    代码:https://github.com/tianxiangd/LearnAbp

  • 相关阅读:
    利用python求非线性方程
    迪士尼穷游攻略
    爬虫八之爬取京东商品信息
    爬虫七之分析Ajax请求并爬取今日头条
    爬虫五之Selenium
    爬虫4之pyquery
    前端传入 SQL 语句 到后端执行
    手写分页处理
    集合(Map,List)分组:多属性进行分组
    java 枚举类非常好的运用实例
  • 原文地址:https://www.cnblogs.com/tianjiaxiaobaicai/p/7833601.html
Copyright © 2020-2023  润新知