【ABP雜燴】Extensions後綴擴展方法

1.Extensions介紹

擴展方法使你可以向現有類型「添加」方法,而無需建立新的派生類型、從新編譯或以其餘方式修改原始類型。 擴展方法是一種特殊的靜態方法,但能夠像擴展類型上的實例方法同樣進行調用。 對於用 C#、F# 和 Visual Basic 編寫的客戶端代碼,調用擴展方法與調用在類型中實際定義的方法沒有明顯區別。編程

詳細見官方文檔:擴展方法(C# 編程指南)app

2.語法介紹

* 須要寫在一個靜態類中 
* 必須是一個靜態方法 
* 經過第一個參數和this關鍵字指定擴展的目標類型 
* 不一樣類型的擴展方法不必定要寫在同一個類中框架

3.事例介紹

 在ABP框架原中會發如今不少地方帶有Extensions的類,其主要做用是在不改變原有接口或類的基礎上擴展自定義的方法,從而方便使用,如QueryableExtensions類是對IQueryable進行擴展,裏面添加了分頁PageBy、條件判斷WhereIf方法,代碼以下:async

​
using System;
using System.Linq;
using System.Linq.Expressions;
using Abp.Application.Services.Dto;

namespace Abp.Linq.Extensions
{
    /// <summary>
    /// Some useful extension methods for <see cref="IQueryable{T}"/>.
    /// </summary>
    public static class QueryableExtensions
    {
        /// <summary>
        /// Used for paging. Can be used as an alternative to Skip(...).Take(...) chaining.
        /// </summary>
        public static IQueryable<T> PageBy<T>(this IQueryable<T> query, int skipCount, int maxResultCount)
        {
            if (query == null)
            {
                throw new ArgumentNullException("query");
            }

            return query.Skip(skipCount).Take(maxResultCount);
        }

        /// <summary>
        /// Used for paging with an <see cref="IPagedResultRequest"/> object.
        /// </summary>
        /// <param name="query">Queryable to apply paging</param>
        /// <param name="pagedResultRequest">An object implements <see cref="IPagedResultRequest"/> interface</param>
        public static IQueryable<T> PageBy<T>(this IQueryable<T> query, IPagedResultRequest pagedResultRequest)
        {
            return query.PageBy(pagedResultRequest.SkipCount, pagedResultRequest.MaxResultCount);
        }

        /// <summary>
        /// Filters a <see cref="IQueryable{T}"/> by given predicate if given condition is true.
        /// </summary>
        /// <param name="query">Queryable to apply filtering</param>
        /// <param name="condition">A boolean value</param>
        /// <param name="predicate">Predicate to filter the query</param>
        /// <returns>Filtered or not filtered query based on <paramref name="condition"/></returns>
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
        {
            return condition
                ? query.Where(predicate)
                : query;
        }

        /// <summary>
        /// Filters a <see cref="IQueryable{T}"/> by given predicate if given condition is true.
        /// </summary>
        /// <param name="query">Queryable to apply filtering</param>
        /// <param name="condition">A boolean value</param>
        /// <param name="predicate">Predicate to filter the query</param>
        /// <returns>Filtered or not filtered query based on <paramref name="condition"/></returns>
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, int, bool>> predicate)
        {
            return condition
                ? query.Where(predicate)
                : query;
        }
    }
}

​

 

如上所述,對IQueryable擴展後,能夠像調用原生方法同樣,使上層的調用感覺不到區別和不用作過多的操做,方便對第三方的庫進行擴展,從而增長自定義需求,有效提升項目的開發效率。調用代碼以下:ide

 public async Task<PagedResultDto<ProjectListDto>> GetProjects(GetProjectsInput input)
        {
            var query = _projectRepository.GetAll();
            query = query
                .WhereIf(!input.Name.IsNullOrWhiteSpace(), item => item.Name.Contains(input.Name))
                .WhereIf(!input.Address.IsNullOrWhiteSpace(), item => item.Address.Contains(input.Address))
                .WhereIf(!input.ResponbleDepart.IsNullOrWhiteSpace(), item => item.ResponbleDepart.Contains(input.ResponbleDepart))
                .WhereIf(!input.Type.IsNullOrWhiteSpace(), item => item.Type.Contains(input.Type))
                .WhereIf(input.ProjectDateStart.HasValue, item => item.StartTime >= input.ProjectDateStart)
                .WhereIf(input.ProjectDateEnd.HasValue, item => item.EndTime <= input.ProjectDateEnd)
                .WhereIf(input.ReportDateStart.HasValue, item => item.ReportTime >= input.ReportDateStart)
                .WhereIf(input.ReportDateEnd.HasValue, item => item.ReportTime <= input.ReportDateEnd);


            var projectCount = await query.CountAsync();

            var projects = await query.OrderBy(input.Sorting).PageBy(input).ToListAsync();

            var projectListDtos = ObjectMapper.Map<List<ProjectListDto>>(projects);

            return new PagedResultDto<ProjectListDto>(
                projectCount,
                projectListDtos
                );
        }

  

相關文章
相關標籤/搜索