diff --git a/src/Volo.Abp/Volo/Abp/Domain/Repositories/IQueryableRepository.cs b/src/Volo.Abp/Volo/Abp/Domain/Repositories/IQueryableRepository.cs new file mode 100644 index 0000000000..4a802d5505 --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/Domain/Repositories/IQueryableRepository.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.Domain.Repositories +{ + public interface IQueryableRepository : IRepository + where TEntity : class, IEntity + { + /// + /// Used to get a IQueryable that is used to retrieve entities from entire table. + /// + /// IQueryable to be used to select entities from database + IQueryable GetAll(); + + /// + /// Used to get all entities based on given . + /// + /// A condition to filter entities + /// List of all entities + List GetAllList(Expression> predicate); + + /// + /// Used to get all entities based on given . + /// + /// A condition to filter entities + /// List of all entities + Task> GetAllListAsync(Expression> predicate); + + /// + /// Gets an entity with given given predicate or null if not found. + /// + /// Predicate to filter entities + TEntity FirstOrDefault(Expression> predicate); + + /// + /// Gets an entity with given given predicate or null if not found. + /// + /// Predicate to filter entities + Task FirstOrDefaultAsync(Expression> predicate); + + /// + /// Deletes many entities by function. + /// Notice that: All entities fits to given predicate are retrieved and deleted. + /// This may cause major performance problems if there are too many entities with + /// given predicate. + /// + /// A condition to filter entities + void Delete(Expression> predicate); + + /// + /// Deletes many entities by function. + /// Notice that: All entities fits to given predicate are retrieved and deleted. + /// This may cause major performance problems if there are too many entities with + /// given predicate. + /// + /// A condition to filter entities + Task DeleteAsync(Expression> predicate); + + /// + /// Gets count of all entities in this repository based on given . + /// + /// A method to filter count + /// Count of entities + int Count(Expression> predicate); + + /// + /// Gets count of all entities in this repository based on given . + /// + /// A method to filter count + /// Count of entities + Task CountAsync(Expression> predicate); + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepository.cs b/src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepository.cs new file mode 100644 index 0000000000..580e1551b9 --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepository.cs @@ -0,0 +1,129 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.Domain.Repositories +{ + //TODO: Didn't get all members from ABP 1.x + + public interface IRepository : IRepositoryMarker where TEntity : class, IEntity + { + /// + /// Used to get all entities. + /// + /// List of all entities + List GetAllList(); + + /// + /// Used to get all entities. + /// + /// List of all entities + Task> GetAllListAsync(); + + /// + /// Gets an entity with given primary key. + /// + /// Primary key of the entity to get + /// Entity + TEntity Get(TPrimaryKey id); + + /// + /// Gets an entity with given primary key. + /// + /// Primary key of the entity to get + /// Entity + Task GetAsync(TPrimaryKey id); + + /// + /// Gets an entity with given primary key or null if not found. + /// + /// Primary key of the entity to get + /// Entity or null + TEntity FirstOrDefault(TPrimaryKey id); + + /// + /// Gets an entity with given primary key or null if not found. + /// + /// Primary key of the entity to get + /// Entity or null + Task FirstOrDefaultAsync(TPrimaryKey id); + + /// + /// Inserts a new entity. + /// + /// Inserted entity + TEntity Insert(TEntity entity); + + /// + /// Inserts a new entity. + /// + /// Inserted entity + Task InsertAsync(TEntity entity); + + /// + /// Inserts a new entity and gets it's Id. + /// It may require to save current unit of work + /// to be able to retrieve id. + /// + /// Entity + /// Id of the entity + TPrimaryKey InsertAndGetId(TEntity entity); + + /// + /// Inserts a new entity and gets it's Id. + /// It may require to save current unit of work + /// to be able to retrieve id. + /// + /// Entity + /// Id of the entity + Task InsertAndGetIdAsync(TEntity entity); + + /// + /// Updates an existing entity. + /// + /// Entity + TEntity Update(TEntity entity); + + /// + /// Updates an existing entity. + /// + /// Entity + Task UpdateAsync(TEntity entity); + + /// + /// Deletes an entity. + /// + /// Entity to be deleted + void Delete(TEntity entity); + + /// + /// Deletes an entity. + /// + /// Entity to be deleted + Task DeleteAsync(TEntity entity); + + /// + /// Deletes an entity by primary key. + /// + /// Primary key of the entity + void Delete(TPrimaryKey id); + + /// + /// Deletes an entity by primary key. + /// + /// Primary key of the entity + Task DeleteAsync(TPrimaryKey id); + + /// + /// Gets count of all entities in this repository. + /// + /// Count of entities + int Count(); + + /// + /// Gets count of all entities in this repository. + /// + /// Count of entities + Task CountAsync(); + } +} diff --git a/src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepositoryMarker.cs b/src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepositoryMarker.cs new file mode 100644 index 0000000000..31805807b0 --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/Domain/Repositories/IRepositoryMarker.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Domain.Repositories +{ + public interface IRepositoryMarker + { + + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/Threading/AsyncHelper.cs b/src/Volo.Abp/Volo/Abp/Threading/AsyncHelper.cs new file mode 100644 index 0000000000..7ce2e52109 --- /dev/null +++ b/src/Volo.Abp/Volo/Abp/Threading/AsyncHelper.cs @@ -0,0 +1,43 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using Nito.AsyncEx; + +namespace Volo.Abp.Threading +{ + /// + /// Provides some helper methods to work with async methods. + /// + public static class AsyncHelper + { + /// + /// Checks if given method is an async method. + /// + /// A method to check + public static bool IsAsyncMethod(MethodInfo method) + { + return method.ReturnType == typeof(Task) || + (method.ReturnType.GetTypeInfo().IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)); + } + + /// + /// Runs a async method synchronously. + /// + /// A function that returns a result + /// Result type + /// Result of the async operation + public static TResult RunSync(Func> func) + { + return AsyncContext.Run(func); + } + + /// + /// Runs a async method synchronously. + /// + /// An async action + public static void RunSync(Func action) + { + AsyncContext.Run(action); + } + } +} diff --git a/src/Volo.Abp/project.json b/src/Volo.Abp/project.json index 98e162e1d4..de63af7468 100644 --- a/src/Volo.Abp/project.json +++ b/src/Volo.Abp/project.json @@ -6,7 +6,8 @@ "Volo.DependencyInjection": "1.0.0-*", "System.Collections.Immutable": "1.3.0", "Volo.ExtensionMethods": "1.0.0-*", - "Newtonsoft.Json": "9.0.1" + "Newtonsoft.Json": "9.0.1", + "Nito.AsyncEx.Context": "1.1.0" }, "frameworks": { diff --git a/test/Volo.Abp.Tests/Volo/Abp/Threading/AsyncHelper_Tests.cs b/test/Volo.Abp.Tests/Volo/Abp/Threading/AsyncHelper_Tests.cs new file mode 100644 index 0000000000..69ec91a0cc --- /dev/null +++ b/test/Volo.Abp.Tests/Volo/Abp/Threading/AsyncHelper_Tests.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.Threading +{ + public class AsyncHelper_Tests + { + [Fact] + public void RunSync_Test_Without_Return_Value() + { + AsyncHelper.RunSync(MyTaskWithoutReturnValue); + } + + [Fact] + public void RunSync_Test_With_Return_Value() + { + AsyncHelper.RunSync(() => MyTaskWithReturnValue(42)).ShouldBe(42); + } + + private static async Task MyTaskWithoutReturnValue() + { + await Task.Delay(1); + } + + private static async Task MyTaskWithReturnValue(int aNumber) + { + await Task.Delay(1); + return aNumber; + } + } +}