diff --git a/src/Volo.Abp/Volo.Abp.csproj b/src/Volo.Abp/Volo.Abp.csproj
index 68b4e781b4..d02cb6b1b3 100644
--- a/src/Volo.Abp/Volo.Abp.csproj
+++ b/src/Volo.Abp/Volo.Abp.csproj
@@ -16,8 +16,10 @@
+
+
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/AsyncCrudAppService.cs b/src/Volo.Abp/Volo/Abp/Application/Services/AsyncCrudAppService.cs
new file mode 100644
index 0000000000..7e66355119
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/AsyncCrudAppService.cs
@@ -0,0 +1,168 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services.Dtos;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Linq;
+
+namespace Abp.Application.Services
+{
+ public abstract class AsyncCrudAppService
+ : AsyncCrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ protected AsyncCrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class AsyncCrudAppService
+ : AsyncCrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ protected AsyncCrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class AsyncCrudAppService
+ : AsyncCrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ protected AsyncCrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class AsyncCrudAppService
+ : AsyncCrudAppService
+ where TGetAllInput : IPagedAndSortedResultRequest
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TCreateInput : IEntityDto
+ {
+ protected AsyncCrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class AsyncCrudAppService
+ : AsyncCrudAppService>
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ {
+ protected AsyncCrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class AsyncCrudAppService
+ : AsyncCrudAppService>
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ {
+ protected AsyncCrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class AsyncCrudAppService
+ : CrudAppServiceBase,
+ IAsyncCrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ where TDeleteInput : IEntityDto
+ {
+ public IAsyncQueryableExecuter AsyncQueryableExecuter { get; set; }
+
+ protected AsyncCrudAppService(IRepository repository)
+ :base(repository)
+ {
+ AsyncQueryableExecuter = DefaultAsyncQueryableExecuter.Instance;
+ }
+
+ public virtual async Task Get(TGetInput input)
+ {
+ CheckGetPermission();
+
+ var entity = await GetEntityByIdAsync(input.Id);
+ return MapToEntityDto(entity);
+ }
+
+ public virtual async Task> GetAll(TGetAllInput input)
+ {
+ CheckGetAllPermission();
+
+ var query = CreateFilteredQuery(input);
+
+ var totalCount = await AsyncQueryableExecuter.CountAsync(query);
+
+ query = ApplySorting(query, input);
+ query = ApplyPaging(query, input);
+
+ var entities = await AsyncQueryableExecuter.ToListAsync(query);
+
+ return new PagedResultDto(
+ totalCount,
+ entities.Select(MapToEntityDto).ToList()
+ );
+ }
+
+ public virtual async Task Create(TCreateInput input)
+ {
+ CheckCreatePermission();
+
+ var entity = MapToEntity(input);
+
+ await Repository.InsertAsync(entity);
+ await CurrentUnitOfWork.SaveChangesAsync();
+
+ return MapToEntityDto(entity);
+ }
+
+ public virtual async Task Update(TUpdateInput input)
+ {
+ CheckUpdatePermission();
+
+ var entity = await GetEntityByIdAsync(input.Id);
+
+ MapToEntity(input, entity);
+ await CurrentUnitOfWork.SaveChangesAsync();
+
+ return MapToEntityDto(entity);
+ }
+
+ public virtual Task Delete(TDeleteInput input)
+ {
+ CheckDeletePermission();
+
+ return Repository.DeleteAsync(input.Id);
+ }
+
+ protected virtual Task GetEntityByIdAsync(TPrimaryKey id)
+ {
+ return Repository.GetAsync(id);
+ }
+ }
+}
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppService.cs b/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppService.cs
new file mode 100644
index 0000000000..e3120f2d22
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppService.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Linq;
+using Volo.Abp.Application.Services.Dtos;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Repositories;
+
+namespace Abp.Application.Services
+{
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ protected CrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ protected CrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ protected CrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TCreateInput : IEntityDto
+ {
+ protected CrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class CrudAppService
+ : CrudAppService>
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ {
+ protected CrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class CrudAppService
+ : CrudAppService>
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ {
+ protected CrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+ }
+
+ public abstract class CrudAppService
+ : CrudAppServiceBase,
+ ICrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ where TDeleteInput : IEntityDto
+ {
+ protected CrudAppService(IRepository repository)
+ : base(repository)
+ {
+
+ }
+
+ public virtual TEntityDto Get(TGetInput input)
+ {
+ CheckGetPermission();
+
+ var entity = GetEntityById(input.Id);
+ return MapToEntityDto(entity);
+ }
+
+ public virtual PagedResultDto GetAll(TGetAllInput input)
+ {
+ CheckGetAllPermission();
+
+ var query = CreateFilteredQuery(input);
+
+ var totalCount = query.Count();
+
+ query = ApplySorting(query, input);
+ query = ApplyPaging(query, input);
+
+ var entities = query.ToList();
+
+ return new PagedResultDto(
+ totalCount,
+ entities.Select(MapToEntityDto).ToList()
+ );
+ }
+
+ public virtual TEntityDto Create(TCreateInput input)
+ {
+ CheckCreatePermission();
+
+ var entity = MapToEntity(input);
+
+ Repository.Insert(entity);
+ CurrentUnitOfWork.SaveChanges();
+
+ return MapToEntityDto(entity);
+ }
+
+ public virtual TEntityDto Update(TUpdateInput input)
+ {
+ CheckUpdatePermission();
+
+ var entity = GetEntityById(input.Id);
+
+ MapToEntity(input, entity);
+ CurrentUnitOfWork.SaveChanges();
+
+ return MapToEntityDto(entity);
+ }
+
+ public virtual void Delete(TDeleteInput input)
+ {
+ CheckDeletePermission();
+
+ Repository.Delete(input.Id);
+ }
+
+ protected virtual TEntity GetEntityById(TPrimaryKey id)
+ {
+ return Repository.Get(id);
+ }
+ }
+}
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppServiceBase.cs b/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppServiceBase.cs
new file mode 100644
index 0000000000..02a66138f2
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppServiceBase.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Linq;
+using System.Linq.Dynamic.Core;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Application.Services.Dtos;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Linq.Extensions;
+
+namespace Abp.Application.Services
+{
+ ///
+ /// This is a common base class for CrudAppService and AsyncCrudAppService classes.
+ /// Inherit either from CrudAppService or AsyncCrudAppService, not from this class.
+ ///
+ public abstract class CrudAppServiceBase : ApplicationService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ {
+ protected IRepository Repository { get; }
+
+ protected virtual string GetPermissionName { get; set; }
+
+ protected virtual string GetAllPermissionName { get; set; }
+
+ protected virtual string CreatePermissionName { get; set; }
+
+ protected virtual string UpdatePermissionName { get; set; }
+
+ protected virtual string DeletePermissionName { get; set; }
+
+ protected CrudAppServiceBase(IRepository repository)
+ {
+ Repository = repository;
+ }
+
+ ///
+ /// Should apply sorting if needed.
+ ///
+ /// The query.
+ /// The input.
+ protected virtual IQueryable ApplySorting(IQueryable query, TGetAllInput input)
+ {
+ //Try to sort query if available
+ var sortInput = input as ISortedResultRequest;
+ if (sortInput != null)
+ {
+ if (!sortInput.Sorting.IsNullOrWhiteSpace())
+ {
+ return query.OrderBy(sortInput.Sorting);
+ }
+ }
+
+ //IQueryable.Task requires sorting, so we should sort if Take will be used.
+ if (input is ILimitedResultRequest)
+ {
+ return query.OrderByDescending(e => e.Id);
+ }
+
+ //No sorting
+ return query;
+ }
+
+ ///
+ /// Should apply paging if needed.
+ ///
+ /// The query.
+ /// The input.
+ protected virtual IQueryable ApplyPaging(IQueryable query, TGetAllInput input)
+ {
+ //Try to use paging if available
+ var pagedInput = input as IPagedResultRequest;
+ if (pagedInput != null)
+ {
+ return query.PageBy(pagedInput);
+ }
+
+ //Try to limit query result if available
+ var limitedInput = input as ILimitedResultRequest;
+ if (limitedInput != null)
+ {
+ return query.Take(limitedInput.MaxResultCount);
+ }
+
+ //No paging
+ return query;
+ }
+
+ ///
+ /// This method should create based on given input.
+ /// It should filter query if needed, but should not do sorting or paging.
+ /// Sorting should be done in and paging should be done in
+ /// methods.
+ ///
+ /// The input.
+ protected virtual IQueryable CreateFilteredQuery(TGetAllInput input)
+ {
+ var queryableRepository = Repository as IQueryableRepository;
+ if (queryableRepository == null)
+ {
+ throw new AbpException("Repository should be IQueryableRepository in order to call CreateFilteredQuery, but it's not. It's type: " + Repository.GetType().AssemblyQualifiedName);
+ }
+
+ return queryableRepository;
+ }
+
+ ///
+ /// Maps to .
+ /// It uses by default.
+ /// It can be overrided for custom mapping.
+ ///
+ protected virtual TEntityDto MapToEntityDto(TEntity entity)
+ {
+ return ObjectMapper.Map(entity);
+ }
+
+ ///
+ /// Maps to to create a new entity.
+ /// It uses by default.
+ /// It can be overrided for custom mapping.
+ ///
+ protected virtual TEntity MapToEntity(TCreateInput createInput)
+ {
+ return ObjectMapper.Map(createInput);
+ }
+
+ ///
+ /// Maps to to update the entity.
+ /// It uses by default.
+ /// It can be overrided for custom mapping.
+ ///
+ protected virtual void MapToEntity(TUpdateInput updateInput, TEntity entity)
+ {
+ ObjectMapper.Map(updateInput, entity);
+ }
+
+ protected virtual void CheckPermission(string permissionName)
+ {
+ if (!string.IsNullOrEmpty(permissionName))
+ {
+ //TODO: PermissionChecker.Authorize(permissionName); //Will be implemented when PermissionChecker is available
+ }
+ }
+
+ protected virtual void CheckGetPermission()
+ {
+ CheckPermission(GetPermissionName);
+ }
+
+ protected virtual void CheckGetAllPermission()
+ {
+ CheckPermission(GetAllPermissionName);
+ }
+
+ protected virtual void CheckCreatePermission()
+ {
+ CheckPermission(CreatePermissionName);
+ }
+
+ protected virtual void CheckUpdatePermission()
+ {
+ CheckPermission(UpdatePermissionName);
+ }
+
+ protected virtual void CheckDeletePermission()
+ {
+ CheckPermission(DeletePermissionName);
+ }
+ }
+}
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IHasLongTotalCount.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IHasLongTotalCount.cs
new file mode 100644
index 0000000000..2e578bf611
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IHasLongTotalCount.cs
@@ -0,0 +1,13 @@
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// This interface is defined to standardize to set "Total Count of Items" to a DTO for long type.
+ ///
+ public interface IHasLongTotalCount
+ {
+ ///
+ /// Total count of Items.
+ ///
+ long TotalCount { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IHasTotalCount.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IHasTotalCount.cs
new file mode 100644
index 0000000000..1508cde4a7
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IHasTotalCount.cs
@@ -0,0 +1,13 @@
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// This interface is defined to standardize to set "Total Count of Items" to a DTO.
+ ///
+ public interface IHasTotalCount
+ {
+ ///
+ /// Total count of Items.
+ ///
+ int TotalCount { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IListResult.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IListResult.cs
new file mode 100644
index 0000000000..831e71dec4
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IListResult.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// This interface is defined to standardize to return a list of items to clients.
+ ///
+ /// Type of the items in the list
+ public interface IListResult
+ {
+ ///
+ /// List of items.
+ ///
+ IReadOnlyList Items { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IPagedAndSortedResultRequest.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IPagedAndSortedResultRequest.cs
new file mode 100644
index 0000000000..ede0990f95
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IPagedAndSortedResultRequest.cs
@@ -0,0 +1,10 @@
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// This interface is defined to standardize to request a paged and sorted result.
+ ///
+ public interface IPagedAndSortedResultRequest : IPagedResultRequest, ISortedResultRequest
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IPagedResult.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IPagedResult.cs
new file mode 100644
index 0000000000..86034be354
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/IPagedResult.cs
@@ -0,0 +1,11 @@
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// This interface is defined to standardize to return a page of items to clients.
+ ///
+ /// Type of the items in the list
+ public interface IPagedResult : IListResult, IHasTotalCount
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/ISortedResultRequest.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/ISortedResultRequest.cs
new file mode 100644
index 0000000000..61720c07c0
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/ISortedResultRequest.cs
@@ -0,0 +1,21 @@
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// This interface is defined to standardize to request a sorted result.
+ ///
+ public interface ISortedResultRequest
+ {
+ ///
+ /// Sorting information.
+ /// Should include sorting field and optionally a direction (ASC or DESC)
+ /// Can contain more than one field separated by comma (,).
+ ///
+ ///
+ /// Examples:
+ /// "Name"
+ /// "Name DESC"
+ /// "Name ASC, Age DESC"
+ ///
+ string Sorting { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/LimitedResultRequestDto.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/LimitedResultRequestDto.cs
new file mode 100644
index 0000000000..e01ed6c4de
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/LimitedResultRequestDto.cs
@@ -0,0 +1,13 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// Simply implements .
+ ///
+ public class LimitedResultRequestDto : ILimitedResultRequest
+ {
+ [Range(1, int.MaxValue)]
+ public virtual int MaxResultCount { get; set; } = 10;
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedAndSortedResultRequestDto.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedAndSortedResultRequestDto.cs
new file mode 100644
index 0000000000..4cfd95dec2
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedAndSortedResultRequestDto.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// Simply implements .
+ ///
+ [Serializable]
+ public class PagedAndSortedResultRequestDto : PagedResultRequestDto, IPagedAndSortedResultRequest
+ {
+ public virtual string Sorting { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedResultDto.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedResultDto.cs
new file mode 100644
index 0000000000..b81debda37
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedResultDto.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// Implements .
+ ///
+ /// Type of the items in the list
+ [Serializable]
+ public class PagedResultDto : ListResultDto, IPagedResult
+ {
+ ///
+ /// Total count of Items.
+ ///
+ public int TotalCount { get; set; }
+
+ ///
+ /// Creates a new object.
+ ///
+ public PagedResultDto()
+ {
+
+ }
+
+ ///
+ /// Creates a new object.
+ ///
+ /// Total count of Items
+ /// List of items in current page
+ public PagedResultDto(int totalCount, IReadOnlyList items)
+ : base(items)
+ {
+ TotalCount = totalCount;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedResultRequestDto.cs b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedResultRequestDto.cs
new file mode 100644
index 0000000000..adeaac9df3
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/Dtos/PagedResultRequestDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Volo.Abp.Application.Services.Dtos
+{
+ ///
+ /// Simply implements .
+ ///
+ [Serializable]
+ public class PagedResultRequestDto : LimitedResultRequestDto, IPagedResultRequest
+ {
+ [Range(0, int.MaxValue)]
+ public virtual int SkipCount { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/IAsyncCrudAppService.cs b/src/Volo.Abp/Volo/Abp/Application/Services/IAsyncCrudAppService.cs
new file mode 100644
index 0000000000..5d3f2905c1
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/IAsyncCrudAppService.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Application.Services.Dtos;
+
+namespace Abp.Application.Services
+{
+ public interface IAsyncCrudAppService
+ : IAsyncCrudAppService
+ where TEntityDto : IEntityDto
+ {
+
+ }
+
+ public interface IAsyncCrudAppService
+ : IAsyncCrudAppService
+ where TEntityDto : IEntityDto
+ {
+
+ }
+
+ public interface IAsyncCrudAppService
+ : IAsyncCrudAppService
+ where TEntityDto : IEntityDto
+ {
+
+ }
+
+ public interface IAsyncCrudAppService
+ : IAsyncCrudAppService
+ where TEntityDto : IEntityDto
+ where TCreateInput : IEntityDto
+ {
+
+ }
+
+ public interface IAsyncCrudAppService
+ : IAsyncCrudAppService>
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ {
+
+ }
+
+ public interface IAsyncCrudAppService
+ : IAsyncCrudAppService>
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ {
+
+ }
+
+ public interface IAsyncCrudAppService
+ : IApplicationService
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ where TDeleteInput : IEntityDto
+ {
+ Task Get(TGetInput input);
+
+ Task> GetAll(TGetAllInput input);
+
+ Task Create(TCreateInput input);
+
+ Task Update(TUpdateInput input);
+
+ Task Delete(TDeleteInput input);
+ }
+}
diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/ICrudAppService.cs b/src/Volo.Abp/Volo/Abp/Application/Services/ICrudAppService.cs
new file mode 100644
index 0000000000..268651dbe3
--- /dev/null
+++ b/src/Volo.Abp/Volo/Abp/Application/Services/ICrudAppService.cs
@@ -0,0 +1,70 @@
+using System;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Application.Services.Dtos;
+
+namespace Abp.Application.Services
+{
+ public interface ICrudAppService
+ : ICrudAppService
+ where TEntityDto : IEntityDto
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService
+ where TEntityDto : IEntityDto
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService
+ where TEntityDto : IEntityDto
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService
+ where TEntityDto : IEntityDto
+ where TCreateInput : IEntityDto
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService>
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService>
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ {
+
+ }
+
+ public interface ICrudAppService
+ : IApplicationService
+ where TEntityDto : IEntityDto
+ where TUpdateInput : IEntityDto
+ where TGetInput : IEntityDto
+ where TDeleteInput : IEntityDto
+ {
+ TEntityDto Get(TGetInput input);
+
+ PagedResultDto GetAll(TGetAllInput input);
+
+ TEntityDto Create(TCreateInput input);
+
+ TEntityDto Update(TUpdateInput input);
+
+ void Delete(TDeleteInput input);
+ }
+}
diff --git a/src/Volo.Abp/Volo/Abp/Linq/DefaultAsyncQueryableExecuter.cs b/src/Volo.Abp/Volo/Abp/Linq/DefaultAsyncQueryableExecuter.cs
index 45542d3bae..8018bf7e87 100644
--- a/src/Volo.Abp/Volo/Abp/Linq/DefaultAsyncQueryableExecuter.cs
+++ b/src/Volo.Abp/Volo/Abp/Linq/DefaultAsyncQueryableExecuter.cs
@@ -6,8 +6,10 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Linq
{
- public class DefaultAsyncQueryableExecuter : IAsyncQueryableExecuter, ITransientDependency
+ public class DefaultAsyncQueryableExecuter : IAsyncQueryableExecuter, ISingletonDependency
{
+ public static DefaultAsyncQueryableExecuter Instance { get; } = new DefaultAsyncQueryableExecuter();
+
public Task CountAsync(IQueryable queryable)
{
return Task.FromResult(queryable.Count());