Browse Source

Merge branch 'dev' of https://github.com/volosoft/abp into dev

pull/1467/head
Yunus Emre Kalkan 7 years ago
parent
commit
fcabb6c6e8
  1. 13
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClientExtensions.cs
  2. 8
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs
  3. 11
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs
  4. 4
      framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
  5. 41
      framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs
  6. 4
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs
  7. 17
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobManagerExtensions.cs
  8. 16
      framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs
  9. 2
      framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueueManager.cs
  10. 13
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs
  11. 34
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobStore.cs
  12. 36
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs
  13. 16
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs
  14. 4
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs
  15. 4
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs
  16. 18
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs
  17. 18
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs
  18. 14
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/HelpCommand.cs
  19. 4
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/IConsoleCommand.cs
  20. 20
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginCommand.cs
  21. 8
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LogoutCommand.cs
  22. 14
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
  23. 25
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs
  24. 18
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs
  25. 15
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs
  26. 168
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AsyncCrudAppService.cs
  27. 249
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs
  28. 191
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppServiceBase.cs
  29. 49
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IAsyncCrudAppService.cs
  30. 13
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ICrudAppService.cs
  31. 23
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs
  32. 3
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs
  33. 33
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderBase.cs
  34. 20
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/IEmailSender.cs
  35. 7
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/NullEmailSender.cs
  36. 8
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs
  37. 36
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusExtensions.cs
  38. 45
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureCheckerExtensions.cs
  39. 14
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs
  40. 2
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IRemoteServiceHttpClientAuthenticator.cs
  41. 13
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs
  42. 14
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  43. 14
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs
  44. 4
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs
  45. 3
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs
  46. 21
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantStoreExtensions.cs
  47. 10
      framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
  48. 25
      framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProviderExtensions.cs
  49. 11
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AbpTimer.cs
  50. 21
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/RunnableExtensions.cs
  51. 1
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs
  52. 5
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs
  53. 2
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs
  54. 2
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs
  55. 33
      modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/BackgroundJobStore.cs
  56. 2
      modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/IBackgroundJobRepository.cs
  57. 17
      modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs
  58. 17
      modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs
  59. 2
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs
  60. 2
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs
  61. 2
      modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/ITenantAppService.cs
  62. 5
      modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs
  63. 28
      modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs
  64. 11
      modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs
  65. 10
      modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs

13
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClientExtensions.cs

@ -1,13 +0,0 @@
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.Threading;
namespace Volo.Abp.AspNetCore.Mvc.Client
{
public static class CachedApplicationConfigurationClientExtensions
{
public static ApplicationConfigurationDto Get(this ICachedApplicationConfigurationClient client)
{
return AsyncHelper.RunSync(client.GetAsync);
}
}
}

8
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs

@ -4,6 +4,7 @@ using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Threading;
namespace Volo.Abp.AspNetCore.Mvc.Client namespace Volo.Abp.AspNetCore.Mvc.Client
{ {
@ -54,8 +55,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Client
private Dictionary<string, string> GetResourceOrNull() private Dictionary<string, string> GetResourceOrNull()
{ {
var resource = _applicationConfigurationClient var applicationConfigurationDto = AsyncHelper.RunSync(
.Get() () => _applicationConfigurationClient.GetAsync()
);
var resource = applicationConfigurationDto
.Localization.Values .Localization.Values
.GetOrDefault(_resource.ResourceName); .GetOrDefault(_resource.ResourceName);

11
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs

@ -10,22 +10,23 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Toolbars
{ {
public class BasicThemeMainTopToolbarContributor : IToolbarContributor public class BasicThemeMainTopToolbarContributor : IToolbarContributor
{ {
public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) public async Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
{ {
if (context.Toolbar.Name != StandardToolbars.Main) if (context.Toolbar.Name != StandardToolbars.Main)
{ {
return Task.CompletedTask; return;
} }
if (!(context.Theme is BasicTheme)) if (!(context.Theme is BasicTheme))
{ {
return Task.CompletedTask; return;
} }
var languageProvider = context.ServiceProvider.GetService<ILanguageProvider>(); var languageProvider = context.ServiceProvider.GetService<ILanguageProvider>();
//TODO: This duplicates GetLanguages() usage. Can we eleminate this? //TODO: This duplicates GetLanguages() usage. Can we eleminate this?
if (languageProvider.GetLanguages().Count > 1) var languages = await languageProvider.GetLanguagesAsync();
if (languages.Count > 1)
{ {
context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitchViewComponent))); context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitchViewComponent)));
} }
@ -34,8 +35,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Toolbars
{ {
context.Toolbar.Items.Add(new ToolbarItem(typeof(UserMenuViewComponent))); context.Toolbar.Items.Add(new ToolbarItem(typeof(UserMenuViewComponent)));
} }
return Task.CompletedTask;
} }
} }
} }

4
framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs

@ -56,10 +56,10 @@ namespace Microsoft.AspNetCore.Builder
using (var scope = app.ApplicationServices.CreateScope()) using (var scope = app.ApplicationServices.CreateScope())
{ {
var languageProvider = scope.ServiceProvider.GetRequiredService<ILanguageProvider>(); var languageProvider = scope.ServiceProvider.GetRequiredService<ILanguageProvider>();
languages = languageProvider.GetLanguages(); languages = AsyncHelper.RunSync(() => languageProvider.GetLanguagesAsync());
var settingProvider = scope.ServiceProvider.GetRequiredService<ISettingProvider>(); var settingProvider = scope.ServiceProvider.GetRequiredService<ISettingProvider>();
defaultLanguage = settingProvider.GetOrNull(LocalizationSettingNames.DefaultLanguage); defaultLanguage = AsyncHelper.RunSync(() => settingProvider.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage));
} }
var options = !languages.Any() var options = !languages.Any()

41
framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs

@ -1,25 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
using Volo.Abp.Threading;
namespace Microsoft.AspNetCore.Authorization namespace Microsoft.AspNetCore.Authorization
{ {
// TODO: Complete all Sync extension methods!
public static class AbpAuthorizationServiceExtensions public static class AbpAuthorizationServiceExtensions
{ {
public static AuthorizationResult Authorize(this IAuthorizationService authorizationService, ClaimsPrincipal user, object resource, string policyName)
{
return AsyncHelper.RunSync(() => authorizationService.AuthorizeAsync(user, resource, policyName));
}
public static AuthorizationResult Authorize(this IAuthorizationService authorizationService, ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements)
{
return AsyncHelper.RunSync(() => authorizationService.AuthorizeAsync(user, resource, requirements));
}
public static Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService authorizationService, string policyName) public static Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService authorizationService, string policyName)
{ {
return AuthorizeAsync( return AuthorizeAsync(
@ -29,15 +16,6 @@ namespace Microsoft.AspNetCore.Authorization
); );
} }
public static AuthorizationResult Authorize(this IAuthorizationService authorizationService, string policyName)
{
return Authorize(
authorizationService,
authorizationService.AsAbpAuthorizationService().CurrentPrincipal,
policyName
);
}
public static Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService authorizationService, object resource, IAuthorizationRequirement requirement) public static Task<AuthorizationResult> AuthorizeAsync(this IAuthorizationService authorizationService, object resource, IAuthorizationRequirement requirement)
{ {
return authorizationService.AuthorizeAsync( return authorizationService.AuthorizeAsync(
@ -81,25 +59,11 @@ namespace Microsoft.AspNetCore.Authorization
); );
} }
public static AuthorizationResult Authorize(this IAuthorizationService authorizationService, object resource, string policyName)
{
return authorizationService.Authorize(
authorizationService.AsAbpAuthorizationService().CurrentPrincipal,
resource,
policyName
);
}
public static async Task<bool> IsGrantedAsync(this IAuthorizationService authorizationService, string policyName) public static async Task<bool> IsGrantedAsync(this IAuthorizationService authorizationService, string policyName)
{ {
return (await authorizationService.AuthorizeAsync(policyName)).Succeeded; return (await authorizationService.AuthorizeAsync(policyName)).Succeeded;
} }
public static bool IsGranted(this IAuthorizationService authorizationService, string policyName)
{
return authorizationService.Authorize(policyName).Succeeded;
}
public static async Task<bool> IsGrantedAsync(this IAuthorizationService authorizationService, object resource, IAuthorizationRequirement requirement) public static async Task<bool> IsGrantedAsync(this IAuthorizationService authorizationService, object resource, IAuthorizationRequirement requirement)
{ {
return (await authorizationService.AuthorizeAsync(resource, requirement)).Succeeded; return (await authorizationService.AuthorizeAsync(resource, requirement)).Succeeded;
@ -133,11 +97,6 @@ namespace Microsoft.AspNetCore.Authorization
} }
} }
public static void Check(this IAuthorizationService authorizationService, string policyName)
{
AsyncHelper.RunSync(() => authorizationService.CheckAsync(policyName));
}
public static async Task CheckAsync(this IAuthorizationService authorizationService, object resource, IAuthorizationRequirement requirement) public static async Task CheckAsync(this IAuthorizationService authorizationService, object resource, IAuthorizationRequirement requirement)
{ {
if (!await authorizationService.IsGrantedAsync(resource, requirement)) if (!await authorizationService.IsGrantedAsync(resource, requirement))

4
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs

@ -39,9 +39,9 @@ namespace Volo.Abp.Authorization
await invocation.ProceedAsync(); await invocation.ProceedAsync();
} }
protected virtual Task AuthorizeAsync(IAbpMethodInvocation invocation) protected virtual async Task AuthorizeAsync(IAbpMethodInvocation invocation)
{ {
return _methodInvocationAuthorizationService.CheckAsync( await _methodInvocationAuthorizationService.CheckAsync(
new MethodInvocationAuthorizationContext( new MethodInvocationAuthorizationContext(
invocation.Method invocation.Method
) )

17
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobManagerExtensions.cs

@ -1,6 +1,4 @@
using System; using Volo.Abp.DynamicProxy;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.BackgroundJobs namespace Volo.Abp.BackgroundJobs
{ {
@ -9,19 +7,6 @@ namespace Volo.Abp.BackgroundJobs
/// </summary> /// </summary>
public static class BackgroundJobManagerExtensions public static class BackgroundJobManagerExtensions
{ {
/// <summary>
/// Enqueues a job to be executed.
/// </summary>
/// <typeparam name="TArgs">Type of the arguments of job.</typeparam>
/// <param name="backgroundJobManager">Background job manager reference</param>
/// <param name="args">Job arguments.</param>
/// <param name="priority">Job priority.</param>
/// <param name="delay">Job delay (wait duration before first try).</param>
public static string Enqueue<TArgs>(this IBackgroundJobManager backgroundJobManager, TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null)
{
return AsyncHelper.RunSync(() => backgroundJobManager.EnqueueAsync<TArgs>(args, priority, delay));
}
/// <summary> /// <summary>
/// Checks if background job system has a real implementation. /// Checks if background job system has a real implementation.
/// It returns false if the current implementation is <see cref="NullBackgroundJobManager"/>. /// It returns false if the current implementation is <see cref="NullBackgroundJobManager"/>.

16
framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs

@ -29,16 +29,20 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
private static void StartJobQueueManager(ApplicationInitializationContext context) private static void StartJobQueueManager(ApplicationInitializationContext context)
{ {
context.ServiceProvider AsyncHelper.RunSync(
.GetRequiredService<IJobQueueManager>() () => context.ServiceProvider
.Start(); .GetRequiredService<IJobQueueManager>()
.StartAsync()
);
} }
private static void StopJobQueueManager(ApplicationShutdownContext context) private static void StopJobQueueManager(ApplicationShutdownContext context)
{ {
context.ServiceProvider AsyncHelper.RunSync(
.GetRequiredService<IJobQueueManager>() () => context.ServiceProvider
.Stop(); .GetRequiredService<IJobQueueManager>()
.StopAsync()
);
} }
} }
} }

2
framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueueManager.cs

@ -61,7 +61,7 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
.GetRequiredService(typeof(IJobQueue<>) .GetRequiredService(typeof(IJobQueue<>)
.MakeGenericType(typeof(TArgs))); .MakeGenericType(typeof(TArgs)));
jobQueue.Start(); AsyncHelper.RunSync(() => jobQueue.StartAsync());
return jobQueue; return jobQueue;
}); });

13
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs

@ -36,9 +36,7 @@ namespace Volo.Abp.BackgroundJobs
{ {
var store = scope.ServiceProvider.GetRequiredService<IBackgroundJobStore>(); var store = scope.ServiceProvider.GetRequiredService<IBackgroundJobStore>();
var waitingJobs = AsyncHelper.RunSync( var waitingJobs = store.GetWaitingJobs(WorkerOptions.MaxJobFetchCount);
() => store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount)
);
if (!waitingJobs.Any()) if (!waitingJobs.Any())
{ {
@ -64,7 +62,7 @@ namespace Volo.Abp.BackgroundJobs
{ {
jobExecuter.Execute(context); jobExecuter.Execute(context);
AsyncHelper.RunSync(() => store.DeleteAsync(jobInfo.Id)); store.Delete(jobInfo.Id);
} }
catch (BackgroundJobExecutionException) catch (BackgroundJobExecutionException)
{ {
@ -96,7 +94,7 @@ namespace Volo.Abp.BackgroundJobs
{ {
try try
{ {
store.UpdateAsync(jobInfo); store.Update(jobInfo);
} }
catch (Exception updateEx) catch (Exception updateEx)
{ {
@ -107,9 +105,8 @@ namespace Volo.Abp.BackgroundJobs
protected virtual DateTime? CalculateNextTryTime(BackgroundJobInfo jobInfo, IClock clock) protected virtual DateTime? CalculateNextTryTime(BackgroundJobInfo jobInfo, IClock clock)
{ {
var nextWaitDuration = WorkerOptions.DefaultFirstWaitDuration * (Math.Pow(WorkerOptions.DefaultWaitFactor, jobInfo.TryCount - 1)); var nextWaitDuration = WorkerOptions.DefaultFirstWaitDuration * (Math.Pow(WorkerOptions.DefaultWaitFactor, jobInfo.TryCount - 1));
var nextTryDate = jobInfo.LastTryTime.HasValue var nextTryDate = jobInfo.LastTryTime?.AddSeconds(nextWaitDuration) ??
? jobInfo.LastTryTime.Value.AddSeconds(nextWaitDuration) clock.Now.AddSeconds(nextWaitDuration);
: clock.Now.AddSeconds(nextWaitDuration);
if (nextTryDate.Subtract(jobInfo.CreationTime).TotalSeconds > WorkerOptions.DefaultTimeout) if (nextTryDate.Subtract(jobInfo.CreationTime).TotalSeconds > WorkerOptions.DefaultTimeout)
{ {

34
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobStore.cs

@ -9,6 +9,13 @@ namespace Volo.Abp.BackgroundJobs
/// </summary> /// </summary>
public interface IBackgroundJobStore public interface IBackgroundJobStore
{ {
/// <summary>
/// Gets a BackgroundJobInfo based on the given jobId.
/// </summary>
/// <param name="jobId">The Job Unique Identifier.</param>
/// <returns>The BackgroundJobInfo object.</returns>
BackgroundJobInfo Find(Guid jobId);
/// <summary> /// <summary>
/// Gets a BackgroundJobInfo based on the given jobId. /// Gets a BackgroundJobInfo based on the given jobId.
/// </summary> /// </summary>
@ -16,12 +23,27 @@ namespace Volo.Abp.BackgroundJobs
/// <returns>The BackgroundJobInfo object.</returns> /// <returns>The BackgroundJobInfo object.</returns>
Task<BackgroundJobInfo> FindAsync(Guid jobId); Task<BackgroundJobInfo> FindAsync(Guid jobId);
/// <summary>
/// Inserts a background job.
/// </summary>
/// <param name="jobInfo">Job information.</param>
void Insert(BackgroundJobInfo jobInfo);
/// <summary> /// <summary>
/// Inserts a background job. /// Inserts a background job.
/// </summary> /// </summary>
/// <param name="jobInfo">Job information.</param> /// <param name="jobInfo">Job information.</param>
Task InsertAsync(BackgroundJobInfo jobInfo); Task InsertAsync(BackgroundJobInfo jobInfo);
/// <summary>
/// Gets waiting jobs. It should get jobs based on these:
/// Conditions: !IsAbandoned And NextTryTime &lt;= Clock.Now.
/// Order by: Priority DESC, TryCount ASC, NextTryTime ASC.
/// Maximum result: <paramref name="maxResultCount"/>.
/// </summary>
/// <param name="maxResultCount">Maximum result count.</param>
List<BackgroundJobInfo> GetWaitingJobs(int maxResultCount);
/// <summary> /// <summary>
/// Gets waiting jobs. It should get jobs based on these: /// Gets waiting jobs. It should get jobs based on these:
/// Conditions: !IsAbandoned And NextTryTime &lt;= Clock.Now. /// Conditions: !IsAbandoned And NextTryTime &lt;= Clock.Now.
@ -31,12 +53,24 @@ namespace Volo.Abp.BackgroundJobs
/// <param name="maxResultCount">Maximum result count.</param> /// <param name="maxResultCount">Maximum result count.</param>
Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount); Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount);
/// <summary>
/// Deletes a job.
/// </summary>
/// <param name="jobId">The Job Unique Identifier.</param>
void Delete(Guid jobId);
/// <summary> /// <summary>
/// Deletes a job. /// Deletes a job.
/// </summary> /// </summary>
/// <param name="jobId">The Job Unique Identifier.</param> /// <param name="jobId">The Job Unique Identifier.</param>
Task DeleteAsync(Guid jobId); Task DeleteAsync(Guid jobId);
/// <summary>
/// Updates a job.
/// </summary>
/// <param name="jobInfo">Job information.</param>
void Update(BackgroundJobInfo jobInfo);
/// <summary> /// <summary>
/// Updates a job. /// Updates a job.
/// </summary> /// </summary>

36
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs

@ -23,11 +23,21 @@ namespace Volo.Abp.BackgroundJobs
_jobs = new ConcurrentDictionary<Guid, BackgroundJobInfo>(); _jobs = new ConcurrentDictionary<Guid, BackgroundJobInfo>();
} }
public BackgroundJobInfo Find(Guid jobId)
{
return _jobs.GetOrDefault(jobId);
}
public virtual Task<BackgroundJobInfo> FindAsync(Guid jobId) public virtual Task<BackgroundJobInfo> FindAsync(Guid jobId)
{ {
return Task.FromResult(_jobs.GetOrDefault(jobId)); return Task.FromResult(_jobs.GetOrDefault(jobId));
} }
public void Insert(BackgroundJobInfo jobInfo)
{
_jobs[jobInfo.Id] = jobInfo;
}
public virtual Task InsertAsync(BackgroundJobInfo jobInfo) public virtual Task InsertAsync(BackgroundJobInfo jobInfo)
{ {
_jobs[jobInfo.Id] = jobInfo; _jobs[jobInfo.Id] = jobInfo;
@ -35,6 +45,17 @@ namespace Volo.Abp.BackgroundJobs
return Task.FromResult(0); return Task.FromResult(0);
} }
public List<BackgroundJobInfo> GetWaitingJobs(int maxResultCount)
{
return _jobs.Values
.Where(t => !t.IsAbandoned && t.NextTryTime <= Clock.Now)
.OrderByDescending(t => t.Priority)
.ThenBy(t => t.TryCount)
.ThenBy(t => t.NextTryTime)
.Take(maxResultCount)
.ToList();
}
public virtual Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount) public virtual Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount)
{ {
var waitingJobs = _jobs.Values var waitingJobs = _jobs.Values
@ -48,6 +69,11 @@ namespace Volo.Abp.BackgroundJobs
return Task.FromResult(waitingJobs); return Task.FromResult(waitingJobs);
} }
public void Delete(Guid jobId)
{
_jobs.TryRemove(jobId, out _);
}
public virtual Task DeleteAsync(Guid jobId) public virtual Task DeleteAsync(Guid jobId)
{ {
_jobs.TryRemove(jobId, out _); _jobs.TryRemove(jobId, out _);
@ -55,6 +81,14 @@ namespace Volo.Abp.BackgroundJobs
return Task.FromResult(0); return Task.FromResult(0);
} }
public void Update(BackgroundJobInfo jobInfo)
{
if (jobInfo.IsAbandoned)
{
DeleteAsync(jobInfo.Id);
}
}
public virtual Task UpdateAsync(BackgroundJobInfo jobInfo) public virtual Task UpdateAsync(BackgroundJobInfo jobInfo)
{ {
if (jobInfo.IsAbandoned) if (jobInfo.IsAbandoned)

16
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs

@ -15,9 +15,11 @@ namespace Volo.Abp.BackgroundWorkers
var options = context.ServiceProvider.GetRequiredService<IOptions<BackgroundWorkerOptions>>().Value; var options = context.ServiceProvider.GetRequiredService<IOptions<BackgroundWorkerOptions>>().Value;
if (options.IsEnabled) if (options.IsEnabled)
{ {
context.ServiceProvider AsyncHelper.RunSync(
.GetRequiredService<IBackgroundWorkerManager>() () => context.ServiceProvider
.Start(); .GetRequiredService<IBackgroundWorkerManager>()
.StartAsync()
);
} }
} }
@ -26,9 +28,11 @@ namespace Volo.Abp.BackgroundWorkers
var options = context.ServiceProvider.GetRequiredService<IOptions<BackgroundWorkerOptions>>().Value; var options = context.ServiceProvider.GetRequiredService<IOptions<BackgroundWorkerOptions>>().Value;
if (options.IsEnabled) if (options.IsEnabled)
{ {
context.ServiceProvider AsyncHelper.RunSync(
.GetRequiredService<IBackgroundWorkerManager>() () => context.ServiceProvider
.Stop(); .GetRequiredService<IBackgroundWorkerManager>()
.StopAsync()
);
} }
} }
} }

4
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs

@ -32,7 +32,9 @@ namespace Volo.Abp.BackgroundWorkers
if (IsRunning) if (IsRunning)
{ {
worker.Start(); AsyncHelper.RunSync(
() => worker.StartAsync()
);
} }
} }

4
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs

@ -26,12 +26,12 @@ namespace Volo.Abp.BackgroundWorkers
public override async Task StartAsync(CancellationToken cancellationToken = default) public override async Task StartAsync(CancellationToken cancellationToken = default)
{ {
await base.StartAsync(cancellationToken); await base.StartAsync(cancellationToken);
await Timer.StartAsync(cancellationToken); Timer.Start(cancellationToken);
} }
public override async Task StopAsync(CancellationToken cancellationToken = default) public override async Task StopAsync(CancellationToken cancellationToken = default)
{ {
await Timer.StopAsync(cancellationToken); Timer.Stop(cancellationToken);
await base.StopAsync(cancellationToken); await base.StopAsync(cancellationToken);
} }

18
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs

@ -27,7 +27,11 @@ namespace Volo.Abp.Cli.Commands
{ {
if (commandLineArgs.Target == null) if (commandLineArgs.Target == null)
{ {
throw new CliUsageException("Module name is missing!" + Environment.NewLine + Environment.NewLine + await GetUsageInfo()); throw new CliUsageException(
"Module name is missing!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
} }
var skipDbMigrations = Convert.ToBoolean( var skipDbMigrations = Convert.ToBoolean(
@ -40,7 +44,7 @@ namespace Volo.Abp.Cli.Commands
); );
} }
public Task<string> GetUsageInfo() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -61,14 +65,14 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(" abp add-module Volo.Blogging -s Acme.BookStore --skip-db-migrations false Adds the module to the given solution but doesn't create a database migration."); sb.AppendLine(" abp add-module Volo.Blogging -s Acme.BookStore --skip-db-migrations false Adds the module to the given solution but doesn't create a database migration.");
sb.AppendLine(""); sb.AppendLine("");
return Task.FromResult(sb.ToString()); return sb.ToString();
} }
public Task<string> GetShortDescriptionAsync() public string GetShortDescription()
{ {
return Task.FromResult("Adds a multi-package module to a solution by finding all packages of the module, " + return "Adds a multi-package module to a solution by finding all packages of the module, " +
"finding related projects in the solution and adding each package to the" + "finding related projects in the solution and adding each package to the" +
" corresponding project in the solution."); " corresponding project in the solution.";
} }
protected virtual string GetSolutionFile(CommandLineArgs commandLineArgs) protected virtual string GetSolutionFile(CommandLineArgs commandLineArgs)

18
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs

@ -27,7 +27,11 @@ namespace Volo.Abp.Cli.Commands
{ {
if (commandLineArgs.Target == null) if (commandLineArgs.Target == null)
{ {
throw new CliUsageException("Package name is missing!" + Environment.NewLine + Environment.NewLine + await GetUsageInfo()); throw new CliUsageException(
"Package name is missing!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
} }
await ProjectNugetPackageAdder.AddAsync( await ProjectNugetPackageAdder.AddAsync(
@ -36,7 +40,7 @@ namespace Volo.Abp.Cli.Commands
); );
} }
public Task<string> GetUsageInfo() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -55,14 +59,14 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(" abp add-package Volo.Abp.FluentValidation -p Acme.BookStore.Application Adds the package to the given project."); sb.AppendLine(" abp add-package Volo.Abp.FluentValidation -p Acme.BookStore.Application Adds the package to the given project.");
sb.AppendLine(""); sb.AppendLine("");
return Task.FromResult(sb.ToString()); return sb.ToString();
} }
public Task<string> GetShortDescriptionAsync() public string GetShortDescription()
{ {
return Task.FromResult("Adds a new ABP package to a project by adding related nuget package" + return "Adds a new ABP package to a project by adding related nuget package" +
" as a dependency to the project and adding [DependsOn(...)] attribute to" + " as a dependency to the project and adding [DependsOn(...)] attribute to" +
" the module class in the project."); " the module class in the project.";
} }
protected virtual string GetProjectFile(CommandLineArgs commandLineArgs) protected virtual string GetProjectFile(CommandLineArgs commandLineArgs)

14
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/HelpCommand.cs

@ -28,7 +28,7 @@ namespace Volo.Abp.Cli.Commands
{ {
if (string.IsNullOrWhiteSpace(commandLineArgs.Target)) if (string.IsNullOrWhiteSpace(commandLineArgs.Target))
{ {
Logger.LogInformation(await GetUsageInfo()); Logger.LogInformation(GetUsageInfo());
return; return;
} }
@ -37,11 +37,11 @@ namespace Volo.Abp.Cli.Commands
using (var scope = ServiceScopeFactory.CreateScope()) using (var scope = ServiceScopeFactory.CreateScope())
{ {
var command = (IConsoleCommand) scope.ServiceProvider.GetRequiredService(commandType); var command = (IConsoleCommand) scope.ServiceProvider.GetRequiredService(commandType);
Logger.LogInformation(await command.GetUsageInfo()); Logger.LogInformation(command.GetUsageInfo());
} }
} }
public async Task<string> GetUsageInfo() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -58,8 +58,8 @@ namespace Volo.Abp.Cli.Commands
using (var scope = ServiceScopeFactory.CreateScope()) using (var scope = ServiceScopeFactory.CreateScope())
{ {
shortDescription = await ((IConsoleCommand)scope.ServiceProvider.GetRequiredService(command.Value)) shortDescription = ((IConsoleCommand) scope.ServiceProvider
.GetShortDescriptionAsync(); .GetRequiredService(command.Value)).GetShortDescription();
} }
sb.Append(" >"); sb.Append(" >");
@ -74,9 +74,9 @@ namespace Volo.Abp.Cli.Commands
return sb.ToString(); return sb.ToString();
} }
public Task<string> GetShortDescriptionAsync() public string GetShortDescription()
{ {
return Task.FromResult(""); return string.Empty;
} }
} }
} }

4
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/IConsoleCommand.cs

@ -7,8 +7,8 @@ namespace Volo.Abp.Cli.Commands
{ {
Task ExecuteAsync(CommandLineArgs commandLineArgs); Task ExecuteAsync(CommandLineArgs commandLineArgs);
Task<string> GetUsageInfo(); string GetUsageInfo();
Task<string> GetShortDescriptionAsync(); string GetShortDescription();
} }
} }

20
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LoginCommand.cs

@ -26,14 +26,22 @@ namespace Volo.Abp.Cli.Commands
{ {
if (commandLineArgs.Target.IsNullOrEmpty()) if (commandLineArgs.Target.IsNullOrEmpty())
{ {
throw new CliUsageException("Username name is missing!" + Environment.NewLine + Environment.NewLine + await GetUsageInfo()); throw new CliUsageException(
"Username name is missing!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
} }
Console.Write("Password: "); Console.Write("Password: ");
var password = ConsoleHelper.ReadSecret(); var password = ConsoleHelper.ReadSecret();
if (password.IsNullOrWhiteSpace()) if (password.IsNullOrWhiteSpace())
{ {
throw new CliUsageException("Password name is missing!" + Environment.NewLine + Environment.NewLine + await GetUsageInfo()); throw new CliUsageException(
"Password name is missing!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
} }
await AuthService.LoginAsync(commandLineArgs.Target, password); await AuthService.LoginAsync(commandLineArgs.Target, password);
@ -41,7 +49,7 @@ namespace Volo.Abp.Cli.Commands
Logger.LogInformation($"Successfully logged in as '{commandLineArgs.Target}'"); Logger.LogInformation($"Successfully logged in as '{commandLineArgs.Target}'");
} }
public Task<string> GetUsageInfo() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -52,12 +60,12 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine("Example:"); sb.AppendLine("Example:");
sb.AppendLine(" abp login john"); sb.AppendLine(" abp login john");
return Task.FromResult(sb.ToString()); return sb.ToString();
} }
public Task<string> GetShortDescriptionAsync() public string GetShortDescription()
{ {
return Task.FromResult(""); return string.Empty;
} }
} }
} }

8
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/LogoutCommand.cs

@ -24,14 +24,14 @@ namespace Volo.Abp.Cli.Commands
return AuthService.LogoutAsync(); return AuthService.LogoutAsync();
} }
public Task<string> GetUsageInfo() public string GetUsageInfo()
{ {
return Task.FromResult(""); return string.Empty;
} }
public Task<string> GetShortDescriptionAsync() public string GetShortDescription()
{ {
return Task.FromResult(""); return string.Empty;
} }
} }
} }

14
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs

@ -30,7 +30,11 @@ namespace Volo.Abp.Cli.Commands
{ {
if (commandLineArgs.Target == null) if (commandLineArgs.Target == null)
{ {
throw new CliUsageException("Project name is missing!" + Environment.NewLine + Environment.NewLine + await GetUsageInfo()); throw new CliUsageException(
"Project name is missing!" +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
} }
Logger.LogInformation("Creating a new project..."); Logger.LogInformation("Creating a new project...");
@ -98,7 +102,7 @@ namespace Volo.Abp.Cli.Commands
Logger.LogInformation($"The output folder is: '{outputFolder}'"); Logger.LogInformation($"The output folder is: '{outputFolder}'");
} }
public Task<string> GetUsageInfo() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -124,12 +128,12 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("See the documentation for more info."); sb.AppendLine("See the documentation for more info.");
return Task.FromResult(sb.ToString()); return sb.ToString();
} }
public Task<string> GetShortDescriptionAsync() public string GetShortDescription()
{ {
return Task.FromResult("Generates a new solution based on the ABP startup templates."); return "Generates a new solution based on the ABP startup templates.";
} }
protected virtual DatabaseProvider GetDatabaseProviderOrNull(CommandLineArgs commandLineArgs) protected virtual DatabaseProvider GetDatabaseProviderOrNull(CommandLineArgs commandLineArgs)

25
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs

@ -43,7 +43,7 @@ namespace Volo.Abp.Cli.Commands
public async Task ExecuteAsync(CommandLineArgs commandLineArgs) public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
{ {
UpdateNugetPackages(commandLineArgs); await UpdateNugetPackages(commandLineArgs);
UpdateNpmPackages(); UpdateNpmPackages();
var options = commandLineArgs.Options var options = commandLineArgs.Options
@ -61,7 +61,7 @@ namespace Volo.Abp.Cli.Commands
_npmPackagesUpdater.Update(Directory.GetCurrentDirectory()); _npmPackagesUpdater.Update(Directory.GetCurrentDirectory());
} }
private void UpdateNugetPackages(CommandLineArgs commandLineArgs) private async Task UpdateNugetPackages(CommandLineArgs commandLineArgs)
{ {
var includePreviews = var includePreviews =
commandLineArgs.Options.GetOrNull(Options.IncludePreviews.Short, Options.IncludePreviews.Long) != null; commandLineArgs.Options.GetOrNull(Options.IncludePreviews.Short, Options.IncludePreviews.Long) != null;
@ -72,7 +72,7 @@ namespace Volo.Abp.Cli.Commands
{ {
var solutionName = Path.GetFileName(solution).RemovePostFix(".sln"); var solutionName = Path.GetFileName(solution).RemovePostFix(".sln");
_nugetPackagesVersionUpdater.UpdateSolution(solution, includePreviews); await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, includePreviews);
Logger.LogInformation($"Volo packages are updated in {solutionName} solution."); Logger.LogInformation($"Volo packages are updated in {solutionName} solution.");
return; return;
@ -84,17 +84,20 @@ namespace Volo.Abp.Cli.Commands
{ {
var projectName = Path.GetFileName(project).RemovePostFix(".csproj"); var projectName = Path.GetFileName(project).RemovePostFix(".csproj");
_nugetPackagesVersionUpdater.UpdateProject(project, includePreviews); await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, includePreviews);
Logger.LogInformation($"Volo packages are updated in {projectName} project."); Logger.LogInformation($"Volo packages are updated in {projectName} project.");
return; return;
} }
throw new CliUsageException("No solution or project found in this directory." + Environment.NewLine + throw new CliUsageException(
Environment.NewLine + AsyncHelper.RunSync(GetUsageInfo)); "No solution or project found in this directory." +
Environment.NewLine + Environment.NewLine +
GetUsageInfo()
);
} }
public Task<string> GetUsageInfo() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -111,13 +114,13 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("See the documentation for more info."); sb.AppendLine("See the documentation for more info.");
return Task.FromResult(sb.ToString()); return sb.ToString();
} }
public Task<string> GetShortDescriptionAsync() public string GetShortDescription()
{ {
return Task.FromResult("Automatically updates all ABP related NuGet packages and NPM packages in a" + return "Automatically updates all ABP related NuGet packages and NPM packages in a" +
" solution or project to the latest versions"); " solution or project to the latest versions";
} }
public static class Options public static class Options

18
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs

@ -1,9 +1,9 @@
using NuGet.Versioning; using NuGet.Versioning;
using System.IO; using System.IO;
using System.Threading.Tasks;
using System.Xml; using System.Xml;
using Volo.Abp.Cli.NuGet; using Volo.Abp.Cli.NuGet;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Cli.ProjectModification namespace Volo.Abp.Cli.ProjectModification
{ {
@ -16,29 +16,29 @@ namespace Volo.Abp.Cli.ProjectModification
_nuGetService = nuGetService; _nuGetService = nuGetService;
} }
public void UpdateSolution(string solutionPath, bool includePreviews) public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews)
{ {
var projectPaths = ProjectFinder.GetProjectFiles(solutionPath); var projectPaths = ProjectFinder.GetProjectFiles(solutionPath);
foreach (var filePath in projectPaths) foreach (var filePath in projectPaths)
{ {
UpdateInternal(filePath, includePreviews); await UpdateInternalAsync(filePath, includePreviews);
} }
} }
public void UpdateProject(string projectPath, bool includePreviews) public async Task UpdateProjectAsync(string projectPath, bool includePreviews)
{ {
UpdateInternal(projectPath, includePreviews); await UpdateInternalAsync(projectPath, includePreviews);
} }
protected virtual void UpdateInternal(string projectPath, bool includePreviews) protected virtual async Task UpdateInternalAsync(string projectPath, bool includePreviews)
{ {
var fileContent = File.ReadAllText(projectPath); var fileContent = File.ReadAllText(projectPath);
File.WriteAllText(projectPath, UpdateVoloPackages(fileContent, includePreviews)); File.WriteAllText(projectPath, await UpdateVoloPackagesAsync(fileContent, includePreviews));
} }
private string UpdateVoloPackages(string content, bool includePreviews) private async Task<string> UpdateVoloPackagesAsync(string content, bool includePreviews)
{ {
var doc = new XmlDocument() { PreserveWhitespace = true }; var doc = new XmlDocument() { PreserveWhitespace = true };
doc.LoadXml(content); doc.LoadXml(content);
@ -49,7 +49,7 @@ namespace Volo.Abp.Cli.ProjectModification
var packageId = package.Attributes["Include"].Value; var packageId = package.Attributes["Include"].Value;
var packageVersion = SemanticVersion.Parse(versionAttribute.Value); var packageVersion = SemanticVersion.Parse(versionAttribute.Value);
var latestVersion = AsyncHelper.RunSync(() => _nuGetService.GetLatestVersionOrNullAsync(packageId, includePreviews)); var latestVersion = await _nuGetService.GetLatestVersionOrNullAsync(packageId, includePreviews);
if (latestVersion != null && packageVersion < latestVersion) if (latestVersion != null && packageVersion < latestVersion)
{ {

15
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs

@ -124,20 +124,5 @@ namespace Volo.Abp.Application.Services
await AuthorizationService.CheckAsync(policyName); await AuthorizationService.CheckAsync(policyName);
} }
/// <summary>
/// Checks for given <paramref name="policyName"/>.
/// Throws <see cref="AbpAuthorizationException"/> if given policy has not been granted.
/// </summary>
/// <param name="policyName">The policy name. This method does nothing if given <paramref name="policyName"/> is null or empty.</param>
protected virtual void CheckPolicy([CanBeNull] string policyName)
{
if (string.IsNullOrEmpty(policyName))
{
return;
}
AuthorizationService.Check(policyName);
}
} }
} }

168
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AsyncCrudAppService.cs

@ -1,168 +0,0 @@
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Application.Services
{
public abstract class AsyncCrudAppService<TEntity, TEntityDto, TKey>
: AsyncCrudAppService<TEntity, TEntityDto, TKey, PagedAndSortedResultRequestDto>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected AsyncCrudAppService(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
public abstract class AsyncCrudAppService<TEntity, TEntityDto, TKey, TGetListInput>
: AsyncCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TEntityDto, TEntityDto>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected AsyncCrudAppService(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
public abstract class AsyncCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput>
: AsyncCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected AsyncCrudAppService(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
public abstract class AsyncCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: AsyncCrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected AsyncCrudAppService(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
protected override TEntityDto MapToGetListOutputDto(TEntity entity)
{
return MapToGetOutputDto(entity);
}
}
public abstract class AsyncCrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CrudAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>,
IAsyncCrudAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
public IAsyncQueryableExecuter AsyncQueryableExecuter { get; set; }
protected AsyncCrudAppService(IRepository<TEntity, TKey> repository)
: base(repository)
{
AsyncQueryableExecuter = DefaultAsyncQueryableExecuter.Instance;
}
public virtual async Task<TGetOutputDto> GetAsync(TKey id)
{
await CheckGetPolicyAsync();
var entity = await GetEntityByIdAsync(id);
return MapToGetOutputDto(entity);
}
public virtual async Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input)
{
await CheckGetListPolicyAsync();
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<TGetListOutputDto>(
totalCount,
entities.Select(MapToGetListOutputDto).ToList()
);
}
public virtual async Task<TGetOutputDto> CreateAsync(TCreateInput input)
{
await CheckCreatePolicyAsync();
var entity = MapToEntity(input);
TryToSetTenantId(entity);
await Repository.InsertAsync(entity, autoSave: true);
return MapToGetOutputDto(entity);
}
public virtual async Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input)
{
await CheckUpdatePolicyAsync();
var entity = await GetEntityByIdAsync(id);
//TODO: Check if input has id different than given id and normalize if it's default value, throw ex otherwise
MapToEntity(input, entity);
await Repository.UpdateAsync(entity, autoSave: true);
return MapToGetOutputDto(entity);
}
public virtual async Task DeleteAsync(TKey id)
{
await CheckDeletePolicyAsync();
await Repository.DeleteAsync(id);
}
protected virtual Task<TEntity> GetEntityByIdAsync(TKey id)
{
return Repository.GetAsync(id);
}
protected virtual async Task CheckGetPolicyAsync()
{
await CheckPolicyAsync(GetPolicyName);
}
protected virtual async Task CheckGetListPolicyAsync()
{
await CheckPolicyAsync(GetListPolicyName);
}
protected virtual async Task CheckCreatePolicyAsync()
{
await CheckPolicyAsync(CreatePolicyName);
}
protected virtual async Task CheckUpdatePolicyAsync()
{
await CheckPolicyAsync(UpdatePolicyName);
}
protected virtual async Task CheckDeletePolicyAsync()
{
await CheckPolicyAsync(DeletePolicyName);
}
}
}

249
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs

@ -1,8 +1,13 @@
using System.Linq; using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
namespace Volo.Abp.Application.Services namespace Volo.Abp.Application.Services
{ {
@ -34,7 +39,6 @@ namespace Volo.Abp.Application.Services
: CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput> : CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
where TEntity : class, IEntity<TKey> where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey> where TEntityDto : IEntityDto<TKey>
where TCreateInput : IEntityDto<TKey>
{ {
protected CrudAppService(IRepository<TEntity, TKey> repository) protected CrudAppService(IRepository<TEntity, TKey> repository)
: base(repository) : base(repository)
@ -44,9 +48,9 @@ namespace Volo.Abp.Application.Services
} }
public abstract class CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput> public abstract class CrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput> : CrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey> where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey> where TEntityDto : IEntityDto<TKey>
{ {
protected CrudAppService(IRepository<TEntity, TKey> repository) protected CrudAppService(IRepository<TEntity, TKey> repository)
: base(repository) : base(repository)
@ -61,38 +65,52 @@ namespace Volo.Abp.Application.Services
} }
public abstract class CrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput> public abstract class CrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CrudAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>, : ApplicationService,
ICrudAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput> ICrudAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey> where TEntity : class, IEntity<TKey>
where TGetOutputDto : IEntityDto<TKey> where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey> where TGetListOutputDto : IEntityDto<TKey>
{ {
public IAsyncQueryableExecuter AsyncQueryableExecuter { get; set; }
protected IRepository<TEntity, TKey> Repository { get; }
protected virtual string GetPolicyName { get; set; }
protected virtual string GetListPolicyName { get; set; }
protected virtual string CreatePolicyName { get; set; }
protected virtual string UpdatePolicyName { get; set; }
protected virtual string DeletePolicyName { get; set; }
protected CrudAppService(IRepository<TEntity, TKey> repository) protected CrudAppService(IRepository<TEntity, TKey> repository)
: base(repository)
{ {
Repository = repository;
AsyncQueryableExecuter = DefaultAsyncQueryableExecuter.Instance;
} }
public virtual TGetOutputDto Get(TKey id) public virtual async Task<TGetOutputDto> GetAsync(TKey id)
{ {
CheckGetPolicy(); await CheckGetPolicyAsync();
var entity = GetEntityById(id); var entity = await GetEntityByIdAsync(id);
return MapToGetOutputDto(entity); return MapToGetOutputDto(entity);
} }
public virtual PagedResultDto<TGetListOutputDto> GetList(TGetListInput input) public virtual async Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input)
{ {
CheckGetListPolicy(); await CheckGetListPolicyAsync();
var query = CreateFilteredQuery(input); var query = CreateFilteredQuery(input);
var totalCount = query.Count(); var totalCount = await AsyncQueryableExecuter.CountAsync(query);
query = ApplySorting(query, input); query = ApplySorting(query, input);
query = ApplyPaging(query, input); query = ApplyPaging(query, input);
var entities = query.ToList(); var entities = await AsyncQueryableExecuter.ToListAsync(query);
return new PagedResultDto<TGetListOutputDto>( return new PagedResultDto<TGetListOutputDto>(
totalCount, totalCount,
@ -100,65 +118,218 @@ namespace Volo.Abp.Application.Services
); );
} }
public virtual TGetOutputDto Create(TCreateInput input) public virtual async Task<TGetOutputDto> CreateAsync(TCreateInput input)
{ {
CheckCreatePolicy(); await CheckCreatePolicyAsync();
var entity = MapToEntity(input); var entity = MapToEntity(input);
TryToSetTenantId(entity); TryToSetTenantId(entity);
Repository.Insert(entity, autoSave: true); await Repository.InsertAsync(entity, autoSave: true);
return MapToGetOutputDto(entity); return MapToGetOutputDto(entity);
} }
public virtual TGetOutputDto Update(TKey id, TUpdateInput input) public virtual async Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input)
{ {
CheckUpdatePolicy(); await CheckUpdatePolicyAsync();
var entity = GetEntityById(id); var entity = await GetEntityByIdAsync(id);
//TODO: Check if input has id different than given id and normalize if it's default value, throw ex otherwise
MapToEntity(input, entity); MapToEntity(input, entity);
Repository.Update(entity, autoSave: true); await Repository.UpdateAsync(entity, autoSave: true);
return MapToGetOutputDto(entity); return MapToGetOutputDto(entity);
} }
public virtual void Delete(TKey id) public virtual async Task DeleteAsync(TKey id)
{ {
CheckDeletePolicy(); await CheckDeletePolicyAsync();
Repository.Delete(id); await Repository.DeleteAsync(id);
} }
protected virtual TEntity GetEntityById(TKey id) protected virtual Task<TEntity> GetEntityByIdAsync(TKey id)
{ {
return Repository.Get(id); return Repository.GetAsync(id);
} }
protected virtual void CheckGetPolicy() protected virtual async Task CheckGetPolicyAsync()
{ {
CheckPolicy(GetPolicyName); await CheckPolicyAsync(GetPolicyName);
} }
protected virtual void CheckGetListPolicy() protected virtual async Task CheckGetListPolicyAsync()
{ {
CheckPolicy(GetListPolicyName); await CheckPolicyAsync(GetListPolicyName);
} }
protected virtual void CheckCreatePolicy() protected virtual async Task CheckCreatePolicyAsync()
{ {
CheckPolicy(CreatePolicyName); await CheckPolicyAsync(CreatePolicyName);
}
protected virtual async Task CheckUpdatePolicyAsync()
{
await CheckPolicyAsync(UpdatePolicyName);
}
protected virtual async Task CheckDeletePolicyAsync()
{
await CheckPolicyAsync(DeletePolicyName);
}
/// <summary>
/// Should apply sorting if needed.
/// </summary>
/// <param name="query">The query.</param>
/// <param name="input">The input.</param>
protected virtual IQueryable<TEntity> ApplySorting(IQueryable<TEntity> query, TGetListInput 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;
}
/// <summary>
/// Should apply paging if needed.
/// </summary>
/// <param name="query">The query.</param>
/// <param name="input">The input.</param>
protected virtual IQueryable<TEntity> ApplyPaging(IQueryable<TEntity> query, TGetListInput 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;
}
/// <summary>
/// This method should create <see cref="IQueryable{TEntity}"/> based on given input.
/// It should filter query if needed, but should not do sorting or paging.
/// Sorting should be done in <see cref="ApplySorting"/> and paging should be done in <see cref="ApplyPaging"/>
/// methods.
/// </summary>
/// <param name="input">The input.</param>
protected virtual IQueryable<TEntity> CreateFilteredQuery(TGetListInput input)
{
return Repository;
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetOutputDto"/>.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual TGetOutputDto MapToGetOutputDto(TEntity entity)
{
return ObjectMapper.Map<TEntity, TGetOutputDto>(entity);
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetListOutputDto"/>.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual TGetListOutputDto MapToGetListOutputDto(TEntity entity)
{
return ObjectMapper.Map<TEntity, TGetListOutputDto>(entity);
}
/// <summary>
/// Maps <see cref="TCreateInput"/> to <see cref="TEntity"/> to create a new entity.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual TEntity MapToEntity(TCreateInput createInput)
{
var entity = ObjectMapper.Map<TCreateInput, TEntity>(createInput);
SetIdForGuids(entity);
return entity;
}
/// <summary>
/// Sets Id value for the entity if <see cref="TKey"/> is <see cref="Guid"/>.
/// It's used while creating a new entity.
/// </summary>
protected virtual void SetIdForGuids(TEntity entity)
{
var entityWithGuidId = entity as IEntity<Guid>;
if (entityWithGuidId == null || entityWithGuidId.Id != Guid.Empty)
{
return;
}
entityWithGuidId.Id = GuidGenerator.Create();
}
/// <summary>
/// Maps <see cref="TUpdateInput"/> to <see cref="TEntity"/> to update the entity.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual void MapToEntity(TUpdateInput updateInput, TEntity entity)
{
if (updateInput is IEntityDto<TKey> entityDto)
{
entityDto.Id = entity.Id;
}
ObjectMapper.Map(updateInput, entity);
} }
protected virtual void CheckUpdatePolicy() protected virtual void TryToSetTenantId(TEntity entity)
{ {
CheckPolicy(UpdatePolicyName); if (entity is IMultiTenant && HasTenantIdProperty(entity))
{
var tenantId = CurrentTenant.Id;
if (!tenantId.HasValue)
{
return;
}
var propertyInfo = entity.GetType().GetProperty(nameof(IMultiTenant.TenantId));
if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
{
propertyInfo.SetValue(entity, tenantId, null);
}
}
} }
protected virtual void CheckDeletePolicy() protected virtual bool HasTenantIdProperty(TEntity entity)
{ {
CheckPolicy(DeletePolicyName); return entity.GetType().GetProperty(nameof(IMultiTenant.TenantId)) != null;
} }
} }
} }

191
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppServiceBase.cs

@ -1,191 +0,0 @@
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
namespace Volo.Abp.Application.Services
{
/// <summary>
/// This is a common base class for CrudAppService and AsyncCrudAppService classes.
/// Inherit either from CrudAppService or AsyncCrudAppService, not from this class.
/// </summary>
public abstract class CrudAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput> :
ApplicationService
where TEntity : class, IEntity<TKey>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
protected IRepository<TEntity, TKey> Repository { get; }
protected virtual string GetPolicyName { get; set; }
protected virtual string GetListPolicyName { get; set; }
protected virtual string CreatePolicyName { get; set; }
protected virtual string UpdatePolicyName { get; set; }
protected virtual string DeletePolicyName { get; set; }
protected CrudAppServiceBase(IRepository<TEntity, TKey> repository)
{
Repository = repository;
}
/// <summary>
/// Should apply sorting if needed.
/// </summary>
/// <param name="query">The query.</param>
/// <param name="input">The input.</param>
protected virtual IQueryable<TEntity> ApplySorting(IQueryable<TEntity> query, TGetListInput 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;
}
/// <summary>
/// Should apply paging if needed.
/// </summary>
/// <param name="query">The query.</param>
/// <param name="input">The input.</param>
protected virtual IQueryable<TEntity> ApplyPaging(IQueryable<TEntity> query, TGetListInput 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;
}
/// <summary>
/// This method should create <see cref="IQueryable{TEntity}"/> based on given input.
/// It should filter query if needed, but should not do sorting or paging.
/// Sorting should be done in <see cref="ApplySorting"/> and paging should be done in <see cref="ApplyPaging"/>
/// methods.
/// </summary>
/// <param name="input">The input.</param>
protected virtual IQueryable<TEntity> CreateFilteredQuery(TGetListInput input)
{
return Repository;
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetOutputDto"/>.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual TGetOutputDto MapToGetOutputDto(TEntity entity)
{
return ObjectMapper.Map<TEntity, TGetOutputDto>(entity);
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetListOutputDto"/>.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual TGetListOutputDto MapToGetListOutputDto(TEntity entity)
{
return ObjectMapper.Map<TEntity, TGetListOutputDto>(entity);
}
/// <summary>
/// Maps <see cref="TCreateInput"/> to <see cref="TEntity"/> to create a new entity.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual TEntity MapToEntity(TCreateInput createInput)
{
var entity = ObjectMapper.Map<TCreateInput, TEntity>(createInput);
SetIdForGuids(entity);
return entity;
}
/// <summary>
/// Sets Id value for the entity if <see cref="TKey"/> is <see cref="Guid"/>.
/// It's used while creating a new entity.
/// </summary>
protected virtual void SetIdForGuids(TEntity entity)
{
var entityWithGuidId = entity as IEntity<Guid>;
if (entityWithGuidId == null || entityWithGuidId.Id != Guid.Empty)
{
return;
}
entityWithGuidId.Id = GuidGenerator.Create();
}
/// <summary>
/// Maps <see cref="TUpdateInput"/> to <see cref="TEntity"/> to update the entity.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
protected virtual void MapToEntity(TUpdateInput updateInput, TEntity entity)
{
if (updateInput is IEntityDto<TKey> entityDto)
{
entityDto.Id = entity.Id;
}
ObjectMapper.Map(updateInput, entity);
}
protected virtual void TryToSetTenantId(TEntity entity)
{
if (entity is IMultiTenant && HasTenantIdProperty(entity))
{
var tenantId = CurrentTenant.Id;
if (!tenantId.HasValue)
{
return;
}
var propertyInfo = entity.GetType().GetProperty(nameof(IMultiTenant.TenantId));
if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
{
propertyInfo.SetValue(entity, tenantId, null);
}
}
}
protected virtual bool HasTenantIdProperty(TEntity entity)
{
return entity.GetType().GetProperty(nameof(IMultiTenant.TenantId)) != null;
}
}
}

49
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IAsyncCrudAppService.cs

@ -1,49 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
namespace Volo.Abp.Application.Services
{
public interface IAsyncCrudAppService<TEntityDto, in TKey>
: IAsyncCrudAppService<TEntityDto, TKey, PagedAndSortedResultRequestDto>
where TEntityDto : IEntityDto<TKey>
{
}
public interface IAsyncCrudAppService<TEntityDto, in TKey, in TGetListInput>
: IAsyncCrudAppService<TEntityDto, TKey, TGetListInput, TEntityDto, TEntityDto>
where TEntityDto : IEntityDto<TKey>
{
}
public interface IAsyncCrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput>
: IAsyncCrudAppService<TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
where TEntityDto : IEntityDto<TKey>
{
}
public interface IAsyncCrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
: IAsyncCrudAppService<TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntityDto : IEntityDto<TKey>
{
}
public interface IAsyncCrudAppService<TGetOutputDto, TGetListOutputDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
: IApplicationService
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
Task<TGetOutputDto> GetAsync(TKey id);
Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input);
Task<TGetOutputDto> CreateAsync(TCreateInput input);
Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input);
Task DeleteAsync(TKey id);
}
}

13
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ICrudAppService.cs

@ -1,3 +1,4 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
namespace Volo.Abp.Application.Services namespace Volo.Abp.Application.Services
@ -24,7 +25,7 @@ namespace Volo.Abp.Application.Services
} }
public interface ICrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput> public interface ICrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
: ICrudAppService<TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput> : ICrudAppService<TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntityDto : IEntityDto<TKey> where TEntityDto : IEntityDto<TKey>
{ {
@ -35,14 +36,14 @@ namespace Volo.Abp.Application.Services
where TGetOutputDto : IEntityDto<TKey> where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey> where TGetListOutputDto : IEntityDto<TKey>
{ {
TGetOutputDto Get(TKey id); Task<TGetOutputDto> GetAsync(TKey id);
PagedResultDto<TGetListOutputDto> GetList(TGetListInput input); Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input);
TGetOutputDto Create(TCreateInput input); Task<TGetOutputDto> CreateAsync(TCreateInput input);
TGetOutputDto Update(TKey id, TUpdateInput input); Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input);
void Delete(TKey id); Task DeleteAsync(TKey id);
} }
} }

23
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs

@ -5,7 +5,6 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.Domain.Repositories namespace Volo.Abp.Domain.Repositories
{ {
@ -27,17 +26,6 @@ namespace Volo.Abp.Domain.Repositories
} }
} }
public static void EnsureCollectionLoaded<TEntity, TKey, TProperty>(
this IBasicRepository<TEntity, TKey> repository,
TEntity entity,
Expression<Func<TEntity, IEnumerable<TProperty>>> propertyExpression
)
where TEntity : class, IEntity<TKey>
where TProperty : class
{
AsyncHelper.RunSync(() => repository.EnsureCollectionLoadedAsync(entity, propertyExpression));
}
public static async Task EnsurePropertyLoadedAsync<TEntity, TKey, TProperty>( public static async Task EnsurePropertyLoadedAsync<TEntity, TKey, TProperty>(
this IBasicRepository<TEntity, TKey> repository, this IBasicRepository<TEntity, TKey> repository,
TEntity entity, TEntity entity,
@ -53,16 +41,5 @@ namespace Volo.Abp.Domain.Repositories
await repo.EnsurePropertyLoadedAsync(entity, propertyExpression, cancellationToken); await repo.EnsurePropertyLoadedAsync(entity, propertyExpression, cancellationToken);
} }
} }
public static void EnsurePropertyLoaded<TEntity, TKey, TProperty>(
this IBasicRepository<TEntity, TKey> repository,
TEntity entity,
Expression<Func<TEntity, TProperty>> propertyExpression
)
where TEntity : class, IEntity<TKey>
where TProperty : class
{
AsyncHelper.RunSync(() => repository.EnsurePropertyLoadedAsync(entity, propertyExpression));
}
} }
} }

3
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs

@ -1,5 +1,6 @@
using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Emailing namespace Volo.Abp.Emailing
{ {
@ -14,7 +15,7 @@ namespace Volo.Abp.Emailing
public override void Execute(BackgroundEmailSendingJobArgs args) public override void Execute(BackgroundEmailSendingJobArgs args)
{ {
EmailSender.Send(args.To, args.Subject, args.Body, args.IsBodyHtml); AsyncHelper.RunSync(() => EmailSender.SendAsync(args.To, args.Subject, args.Body, args.IsBodyHtml));
} }
} }
} }

33
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderBase.cs

@ -3,7 +3,6 @@ using System.Net.Mail;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundJobs;
using Volo.Abp.Threading;
namespace Volo.Abp.Emailing namespace Volo.Abp.Emailing
{ {
@ -36,27 +35,11 @@ namespace Volo.Abp.Emailing
}); });
} }
public virtual void Send(string to, string subject, string body, bool isBodyHtml = true)
{
Send(new MailMessage
{
To = { to },
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
});
}
public virtual async Task SendAsync(string from, string to, string subject, string body, bool isBodyHtml = true) public virtual async Task SendAsync(string from, string to, string subject, string body, bool isBodyHtml = true)
{ {
await SendAsync(new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml }); await SendAsync(new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml });
} }
public virtual void Send(string from, string to, string subject, string body, bool isBodyHtml = true)
{
Send(new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml });
}
public virtual async Task SendAsync(MailMessage mail, bool normalize = true) public virtual async Task SendAsync(MailMessage mail, bool normalize = true)
{ {
if (normalize) if (normalize)
@ -86,28 +69,12 @@ namespace Volo.Abp.Emailing
); );
} }
public virtual void Send(MailMessage mail, bool normalize = true)
{
if (normalize)
{
AsyncHelper.RunSync(() => NormalizeMailAsync(mail));
}
SendEmail(mail);
}
/// <summary> /// <summary>
/// Should implement this method to send email in derived classes. /// Should implement this method to send email in derived classes.
/// </summary> /// </summary>
/// <param name="mail">Mail to be sent</param> /// <param name="mail">Mail to be sent</param>
protected abstract Task SendEmailAsync(MailMessage mail); protected abstract Task SendEmailAsync(MailMessage mail);
/// <summary>
/// Should implement this method to send email in derived classes.
/// </summary>
/// <param name="mail">Mail to be sent</param>
protected abstract void SendEmail(MailMessage mail);
/// <summary> /// <summary>
/// Normalizes given email. /// Normalizes given email.
/// Fills <see cref="MailMessage.From"/> if it's not filled before. /// Fills <see cref="MailMessage.From"/> if it's not filled before.

20
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/IEmailSender.cs

@ -13,31 +13,11 @@ namespace Volo.Abp.Emailing
/// </summary> /// </summary>
Task SendAsync(string to, string subject, string body, bool isBodyHtml = true); Task SendAsync(string to, string subject, string body, bool isBodyHtml = true);
/// <summary>
/// Sends an email.
/// </summary>
void Send(string to, string subject, string body, bool isBodyHtml = true);
/// <summary> /// <summary>
/// Sends an email. /// Sends an email.
/// </summary> /// </summary>
Task SendAsync(string from, string to, string subject, string body, bool isBodyHtml = true); Task SendAsync(string from, string to, string subject, string body, bool isBodyHtml = true);
/// <summary>
/// Sends an email.
/// </summary>
void Send(string from, string to, string subject, string body, bool isBodyHtml = true);
/// <summary>
/// Sends an email.
/// </summary>
/// <param name="mail">Mail to be sent</param>
/// <param name="normalize">
/// Should normalize email?
/// If true, it sets sender address/name if it's not set before and makes mail encoding UTF-8.
/// </param>
void Send(MailMessage mail, bool normalize = true);
/// <summary> /// <summary>
/// Sends an email. /// Sends an email.
/// </summary> /// </summary>

7
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/NullEmailSender.cs

@ -31,13 +31,6 @@ namespace Volo.Abp.Emailing
return Task.FromResult(0); return Task.FromResult(0);
} }
protected override void SendEmail(MailMessage mail)
{
Logger.LogWarning("USING NullEmailSender!");
Logger.LogWarning("SendEmail:");
LogEmail(mail);
}
private void LogEmail(MailMessage mail) private void LogEmail(MailMessage mail)
{ {
Logger.LogDebug(mail.To.ToString()); Logger.LogDebug(mail.To.ToString());

8
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs

@ -75,13 +75,5 @@ namespace Volo.Abp.Emailing.Smtp
await smtpClient.SendMailAsync(mail); await smtpClient.SendMailAsync(mail);
} }
} }
protected override void SendEmail(MailMessage mail)
{
using (var smtpClient = AsyncHelper.RunSync(BuildClientAsync))
{
smtpClient.Send(mail);
}
}
} }
} }

36
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusExtensions.cs

@ -1,36 +0,0 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Threading;
namespace Volo.Abp.EventBus
{
public static class EventBusExtensions
{
/// <summary>
/// Triggers an event.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="eventBus">Event bus instance</param>
/// <param name="eventData">Related data for the event</param>
public static void Publish<TEvent>([NotNull] this IEventBus eventBus, [NotNull] TEvent eventData)
where TEvent : class
{
Check.NotNull(eventBus, nameof(eventBus));
AsyncHelper.RunSync(() => eventBus.PublishAsync(eventData));
}
/// <summary>
/// Triggers an event.
/// </summary>
/// <param name="eventBus">Event bus instance</param>
/// <param name="eventType">Event type</param>
/// <param name="eventData">Related data for the event</param>
public static void Publish([NotNull] this IEventBus eventBus, [NotNull] Type eventType, [NotNull] object eventData)
{
Check.NotNull(eventBus, nameof(eventBus));
AsyncHelper.RunSync(() => eventBus.PublishAsync(eventType, eventData));
}
}
}

45
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureCheckerExtensions.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
using Volo.Abp.Threading;
namespace Volo.Abp.Features namespace Volo.Abp.Features
{ {
@ -22,30 +21,6 @@ namespace Volo.Abp.Features
return value?.To<T>() ?? defaultValue; return value?.To<T>() ?? defaultValue;
} }
public static string GetOrNull(
[NotNull] this IFeatureChecker featureChecker,
[NotNull] string name)
{
Check.NotNull(featureChecker, nameof(featureChecker));
return AsyncHelper.RunSync(() => featureChecker.GetOrNullAsync(name));
}
public static T Get<T>(
[NotNull] this IFeatureChecker featureChecker,
[NotNull] string name,
T defaultValue = default)
where T : struct
{
return AsyncHelper.RunSync(() => featureChecker.GetAsync(name, defaultValue));
}
public static bool IsEnabled(
[NotNull] this IFeatureChecker featureChecker,
[NotNull] string name)
{
return AsyncHelper.RunSync(() => featureChecker.IsEnabledAsync(name));
}
public static async Task<bool> IsEnabledAsync(this IFeatureChecker featureChecker, bool requiresAll, params string[] featureNames) public static async Task<bool> IsEnabledAsync(this IFeatureChecker featureChecker, bool requiresAll, params string[] featureNames)
{ {
if (featureNames.IsNullOrEmpty()) if (featureNames.IsNullOrEmpty())
@ -77,11 +52,6 @@ namespace Volo.Abp.Features
return false; return false;
} }
public static bool IsEnabled(this IFeatureChecker featureChecker, bool requiresAll, params string[] featureNames)
{
return AsyncHelper.RunSync(() => featureChecker.IsEnabledAsync(requiresAll, featureNames));
}
public static async Task CheckEnabledAsync(this IFeatureChecker featureChecker, string featureName) public static async Task CheckEnabledAsync(this IFeatureChecker featureChecker, string featureName)
{ {
if (!(await featureChecker.IsEnabledAsync(featureName))) if (!(await featureChecker.IsEnabledAsync(featureName)))
@ -89,15 +59,7 @@ namespace Volo.Abp.Features
throw new AbpAuthorizationException("Feature is not enabled: " + featureName); throw new AbpAuthorizationException("Feature is not enabled: " + featureName);
} }
} }
public static void CheckEnabled(this IFeatureChecker featureChecker, string featureName)
{
if (!featureChecker.IsEnabled(featureName))
{
throw new AbpAuthorizationException("Feature is not enabled: " + featureName);
}
}
public static async Task CheckEnabledAsync(this IFeatureChecker featureChecker, bool requiresAll, params string[] featureNames) public static async Task CheckEnabledAsync(this IFeatureChecker featureChecker, bool requiresAll, params string[] featureNames)
{ {
if (featureNames.IsNullOrEmpty()) if (featureNames.IsNullOrEmpty())
@ -134,10 +96,5 @@ namespace Volo.Abp.Features
); );
} }
} }
public static void CheckEnabled(this IFeatureChecker featureChecker, bool requiresAll, params string[] featureNames)
{
AsyncHelper.RunSync(() => featureChecker.CheckEnabledAsync(requiresAll, featureNames));
}
} }
} }

14
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs

@ -18,9 +18,7 @@ namespace Volo.Abp.Features
public override void Intercept(IAbpMethodInvocation invocation) public override void Intercept(IAbpMethodInvocation invocation)
{ {
if (AbpCrossCuttingConcerns.IsApplied( if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking))
invocation.TargetObject,
AbpCrossCuttingConcerns.FeatureChecking))
{ {
invocation.Proceed(); invocation.Proceed();
return; return;
@ -32,21 +30,19 @@ namespace Volo.Abp.Features
public override async Task InterceptAsync(IAbpMethodInvocation invocation) public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
if (AbpCrossCuttingConcerns.IsApplied( if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking))
invocation.TargetObject,
AbpCrossCuttingConcerns.FeatureChecking))
{ {
await invocation.ProceedAsync(); await invocation.ProceedAsync();
return; return;
} }
AsyncHelper.RunSync(() => CheckFeaturesAsync(invocation)); await CheckFeaturesAsync(invocation);
await invocation.ProceedAsync(); await invocation.ProceedAsync();
} }
protected virtual Task CheckFeaturesAsync(IAbpMethodInvocation invocation) protected virtual async Task CheckFeaturesAsync(IAbpMethodInvocation invocation)
{ {
return _methodInvocationFeatureCheckerService.CheckAsync( await _methodInvocationFeatureCheckerService.CheckAsync(
new MethodInvocationFeatureCheckerContext( new MethodInvocationFeatureCheckerContext(
invocation.Method invocation.Method
) )

2
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IRemoteServiceHttpClientAuthenticator.cs

@ -4,6 +4,6 @@ namespace Volo.Abp.Http.Client.Authentication
{ {
public interface IRemoteServiceHttpClientAuthenticator public interface IRemoteServiceHttpClientAuthenticator
{ {
Task Authenticate(RemoteServiceHttpClientAuthenticateContext context); Task Authenticate(RemoteServiceHttpClientAuthenticateContext context); //TODO: Rename to AuthenticateAsync
} }
} }

13
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs

@ -1,13 +0,0 @@
using System.Collections.Generic;
using Volo.Abp.Threading;
namespace Volo.Abp.Localization
{
public static class LanguageProviderExtensions
{
public static IReadOnlyList<LanguageInfo> GetLanguages(this ILanguageProvider languageProvider)
{
return AsyncHelper.RunSync(languageProvider.GetLanguagesAsync);
}
}
}

14
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -88,11 +88,11 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted) if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted)
{ {
SetDeletionAuditProperties(entity); SetDeletionAuditProperties(entity);
AsyncHelper.RunSync(() => TriggerEntityDeleteEvents(entity)); AsyncHelper.RunSync(() => TriggerEntityDeleteEventsAsync(entity));
} }
else else
{ {
AsyncHelper.RunSync(() => TriggerEntityUpdateEvents(entity)); AsyncHelper.RunSync(() => TriggerEntityUpdateEventsAsync(entity));
} }
AsyncHelper.RunSync(() => TriggerDomainEventsAsync(entity)); AsyncHelper.RunSync(() => TriggerDomainEventsAsync(entity));
@ -122,11 +122,11 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted) if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted)
{ {
SetDeletionAuditProperties(entity); SetDeletionAuditProperties(entity);
await TriggerEntityDeleteEvents(entity); await TriggerEntityDeleteEventsAsync(entity);
} }
else else
{ {
await TriggerEntityUpdateEvents(entity); await TriggerEntityUpdateEventsAsync(entity);
} }
await TriggerDomainEventsAsync(entity); await TriggerDomainEventsAsync(entity);
@ -294,7 +294,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
await EntityChangeEventHelper.TriggerEntityCreatingEventAsync(entity); await EntityChangeEventHelper.TriggerEntityCreatingEventAsync(entity);
} }
protected virtual async Task TriggerEntityUpdateEvents(TEntity entity) protected virtual async Task TriggerEntityUpdateEventsAsync(TEntity entity)
{ {
await EntityChangeEventHelper.TriggerEntityUpdatedEventOnUowCompletedAsync(entity); await EntityChangeEventHelper.TriggerEntityUpdatedEventOnUowCompletedAsync(entity);
await EntityChangeEventHelper.TriggerEntityUpdatingEventAsync(entity); await EntityChangeEventHelper.TriggerEntityUpdatingEventAsync(entity);
@ -303,11 +303,11 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
protected virtual async Task ApplyAbpConceptsForDeletedEntityAsync(TEntity entity) protected virtual async Task ApplyAbpConceptsForDeletedEntityAsync(TEntity entity)
{ {
SetDeletionAuditProperties(entity); SetDeletionAuditProperties(entity);
await TriggerEntityDeleteEvents(entity); await TriggerEntityDeleteEventsAsync(entity);
await TriggerDomainEventsAsync(entity); await TriggerDomainEventsAsync(entity);
} }
protected virtual async Task TriggerEntityDeleteEvents(TEntity entity) protected virtual async Task TriggerEntityDeleteEventsAsync(TEntity entity)
{ {
await EntityChangeEventHelper.TriggerEntityDeletedEventOnUowCompletedAsync(entity); await EntityChangeEventHelper.TriggerEntityDeletedEventOnUowCompletedAsync(entity);
await EntityChangeEventHelper.TriggerEntityDeletingEventAsync(entity); await EntityChangeEventHelper.TriggerEntityDeletingEventAsync(entity);

14
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs

@ -18,12 +18,22 @@ namespace Volo.Abp.MultiTenancy.ConfigurationStore
public Task<TenantConfiguration> FindAsync(string name) public Task<TenantConfiguration> FindAsync(string name)
{ {
return Task.FromResult(_options.Tenants?.FirstOrDefault(t => t.Name == name)); return Task.FromResult(Find(name));
} }
public Task<TenantConfiguration> FindAsync(Guid id) public Task<TenantConfiguration> FindAsync(Guid id)
{ {
return Task.FromResult(_options.Tenants?.FirstOrDefault(t => t.Id == id)); return Task.FromResult(Find(id));
}
public TenantConfiguration Find(string name)
{
return _options.Tenants?.FirstOrDefault(t => t.Name == name);
}
public TenantConfiguration Find(Guid id)
{
return _options.Tenants?.FirstOrDefault(t => t.Id == id);
} }
} }
} }

4
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs

@ -8,5 +8,9 @@ namespace Volo.Abp.MultiTenancy
Task<TenantConfiguration> FindAsync(string name); Task<TenantConfiguration> FindAsync(string name);
Task<TenantConfiguration> FindAsync(Guid id); Task<TenantConfiguration> FindAsync(Guid id);
TenantConfiguration Find(string name);
TenantConfiguration Find(Guid id);
} }
} }

3
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs

@ -4,7 +4,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.MultiTenancy namespace Volo.Abp.MultiTenancy
{ {
@ -38,7 +37,7 @@ namespace Volo.Abp.MultiTenancy
.ServiceProvider .ServiceProvider
.GetRequiredService<ITenantStore>(); .GetRequiredService<ITenantStore>();
var tenant = AsyncHelper.RunSync(() => tenantStore.FindAsync(_currentTenant.Id.Value)); //TODO: Can we avoid from RunSync? var tenant = tenantStore.Find(_currentTenant.Id.Value);
if (tenant?.ConnectionStrings == null) if (tenant?.ConnectionStrings == null)
{ {

21
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantStoreExtensions.cs

@ -1,21 +0,0 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Threading;
namespace Volo.Abp.MultiTenancy
{
public static class TenantStoreExtensions
{
[CanBeNull]
public static TenantConfiguration Find(this ITenantStore tenantStore, string name)
{
return AsyncHelper.RunSync(() => tenantStore.FindAsync(name));
}
[CanBeNull]
public static TenantConfiguration Find(this ITenantStore tenantStore, Guid id)
{
return AsyncHelper.RunSync(() => tenantStore.FindAsync(id));
}
}
}

10
framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs

@ -72,7 +72,7 @@ namespace Volo.Abp.RabbitMQ
await TrySendQueueBindCommandsAsync(); await TrySendQueueBindCommandsAsync();
} }
protected virtual Task TrySendQueueBindCommandsAsync() protected virtual void TrySendQueueBindCommands()
{ {
try try
{ {
@ -80,7 +80,7 @@ namespace Volo.Abp.RabbitMQ
{ {
if (Channel == null || Channel.IsClosed) if (Channel == null || Channel.IsClosed)
{ {
return Task.CompletedTask; return;
} }
lock (ChannelSendSyncLock) lock (ChannelSendSyncLock)
@ -115,7 +115,11 @@ namespace Volo.Abp.RabbitMQ
{ {
Logger.LogException(ex, LogLevel.Warning); Logger.LogException(ex, LogLevel.Warning);
} }
}
protected virtual Task TrySendQueueBindCommandsAsync()
{
TrySendQueueBindCommands();
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -129,7 +133,7 @@ namespace Volo.Abp.RabbitMQ
if (Channel == null || Channel.IsOpen == false) if (Channel == null || Channel.IsOpen == false)
{ {
TryCreateChannel(); TryCreateChannel();
AsyncHelper.RunSync(TrySendQueueBindCommandsAsync); TrySendQueueBindCommands();
} }
} }

25
framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProviderExtensions.cs

@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using Volo.Abp.Threading;
namespace Volo.Abp.Settings namespace Volo.Abp.Settings
{ {
@ -29,28 +27,5 @@ namespace Volo.Abp.Settings
var value = await settingProvider.GetOrNullAsync(name); var value = await settingProvider.GetOrNullAsync(name);
return value?.To<T>() ?? defaultValue; return value?.To<T>() ?? defaultValue;
} }
public static string GetOrNull([NotNull] this ISettingProvider settingProvider, [NotNull] string name)
{
Check.NotNull(settingProvider, nameof(settingProvider));
return AsyncHelper.RunSync(() => settingProvider.GetOrNullAsync(name));
}
public static List<SettingValue> GetAll([NotNull] this ISettingProvider settingProvider)
{
Check.NotNull(settingProvider, nameof(settingProvider));
return AsyncHelper.RunSync(settingProvider.GetAllAsync);
}
public static T Get<T>([NotNull] this ISettingProvider settingProvider, [NotNull] string name, T defaultValue = default)
where T : struct
{
return AsyncHelper.RunSync(() => settingProvider.GetAsync(name, defaultValue));
}
public static bool IsTrue([NotNull] this ISettingProvider settingProvider, [NotNull] string name)
{
return AsyncHelper.RunSync(() => settingProvider.IsTrueAsync(name));
}
} }
} }

11
framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AbpTimer.cs

@ -1,6 +1,5 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -10,7 +9,7 @@ namespace Volo.Abp.Threading
/// <summary> /// <summary>
/// A roboust timer implementation that ensures no overlapping occurs. It waits exactly specified <see cref="Period"/> between ticks. /// A roboust timer implementation that ensures no overlapping occurs. It waits exactly specified <see cref="Period"/> between ticks.
/// </summary> /// </summary>
public class AbpTimer : IRunnable, ITransientDependency public class AbpTimer : ITransientDependency
{ {
/// <summary> /// <summary>
/// This event is raised periodically according to Period of Timer. /// This event is raised periodically according to Period of Timer.
@ -41,7 +40,7 @@ namespace Volo.Abp.Threading
_taskTimer = new Timer(TimerCallBack, null, Timeout.Infinite, Timeout.Infinite); _taskTimer = new Timer(TimerCallBack, null, Timeout.Infinite, Timeout.Infinite);
} }
public Task StartAsync(CancellationToken cancellationToken = default) public void Start(CancellationToken cancellationToken = default)
{ {
if (Period <= 0) if (Period <= 0)
{ {
@ -53,11 +52,9 @@ namespace Volo.Abp.Threading
_taskTimer.Change(RunOnStart ? 0 : Period, Timeout.Infinite); _taskTimer.Change(RunOnStart ? 0 : Period, Timeout.Infinite);
_isRunning = true; _isRunning = true;
} }
return Task.CompletedTask;
} }
public Task StopAsync(CancellationToken cancellationToken = default) public void Stop(CancellationToken cancellationToken = default)
{ {
lock (_taskTimer) lock (_taskTimer)
{ {
@ -69,8 +66,6 @@ namespace Volo.Abp.Threading
_isRunning = false; _isRunning = false;
} }
return Task.CompletedTask;
} }
/// <summary> /// <summary>

21
framework/src/Volo.Abp.Threading/Volo/Abp/Threading/RunnableExtensions.cs

@ -1,21 +0,0 @@
using JetBrains.Annotations;
namespace Volo.Abp.Threading
{
public static class RunnableExtensions
{
public static void Start([NotNull] this IRunnable runnable)
{
Check.NotNull(runnable, nameof(runnable));
AsyncHelper.RunSync(() => runnable.StartAsync());
}
public static void Stop([NotNull] this IRunnable runnable)
{
Check.NotNull(runnable, nameof(runnable));
AsyncHelper.RunSync(() => runnable.StopAsync());
}
}
}

1
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs

@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.UI.Navigation namespace Volo.Abp.UI.Navigation
{ {

5
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptor.cs

@ -1,7 +1,4 @@
using Microsoft.Extensions.DependencyInjection; using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using Volo.Abp.Aspects; using Volo.Abp.Aspects;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;

2
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs

@ -6,7 +6,7 @@ using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.TestApp.Application namespace Volo.Abp.TestApp.Application
{ {
public interface IPeopleAppService : IAsyncCrudAppService<PersonDto, Guid> public interface IPeopleAppService : ICrudAppService<PersonDto, Guid>
{ {
Task<ListResultDto<PhoneDto>> GetPhones(Guid id, GetPersonPhonesFilter filter); Task<ListResultDto<PhoneDto>> GetPhones(Guid id, GetPersonPhonesFilter filter);

2
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs

@ -10,7 +10,7 @@ using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.TestApp.Application namespace Volo.Abp.TestApp.Application
{ {
public class PeopleAppService : AsyncCrudAppService<Person, PersonDto, Guid>, IPeopleAppService public class PeopleAppService : CrudAppService<Person, PersonDto, Guid>, IPeopleAppService
{ {
public PeopleAppService(IRepository<Person, Guid> repository) public PeopleAppService(IRepository<Person, Guid> repository)
: base(repository) : base(repository)

33
modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/BackgroundJobStore.cs

@ -19,6 +19,13 @@ namespace Volo.Abp.BackgroundJobs
BackgroundJobRepository = backgroundJobRepository; BackgroundJobRepository = backgroundJobRepository;
} }
public BackgroundJobInfo Find(Guid jobId)
{
return ObjectMapper.Map<BackgroundJobRecord, BackgroundJobInfo>(
BackgroundJobRepository.Find(jobId)
);
}
public virtual async Task<BackgroundJobInfo> FindAsync(Guid jobId) public virtual async Task<BackgroundJobInfo> FindAsync(Guid jobId)
{ {
return ObjectMapper.Map<BackgroundJobRecord, BackgroundJobInfo>( return ObjectMapper.Map<BackgroundJobRecord, BackgroundJobInfo>(
@ -26,6 +33,13 @@ namespace Volo.Abp.BackgroundJobs
); );
} }
public void Insert(BackgroundJobInfo jobInfo)
{
BackgroundJobRepository.Insert(
ObjectMapper.Map<BackgroundJobInfo, BackgroundJobRecord>(jobInfo)
);
}
public virtual async Task InsertAsync(BackgroundJobInfo jobInfo) public virtual async Task InsertAsync(BackgroundJobInfo jobInfo)
{ {
await BackgroundJobRepository.InsertAsync( await BackgroundJobRepository.InsertAsync(
@ -33,6 +47,13 @@ namespace Volo.Abp.BackgroundJobs
); );
} }
public List<BackgroundJobInfo> GetWaitingJobs(int maxResultCount)
{
return ObjectMapper.Map<List<BackgroundJobRecord>, List<BackgroundJobInfo>>(
BackgroundJobRepository.GetWaitingList(maxResultCount)
);
}
public virtual async Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount) public virtual async Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount)
{ {
return ObjectMapper.Map<List<BackgroundJobRecord>, List<BackgroundJobInfo>>( return ObjectMapper.Map<List<BackgroundJobRecord>, List<BackgroundJobInfo>>(
@ -40,11 +61,23 @@ namespace Volo.Abp.BackgroundJobs
); );
} }
public void Delete(Guid jobId)
{
BackgroundJobRepository.Delete(jobId);
}
public virtual async Task DeleteAsync(Guid jobId) public virtual async Task DeleteAsync(Guid jobId)
{ {
await BackgroundJobRepository.DeleteAsync(jobId); await BackgroundJobRepository.DeleteAsync(jobId);
} }
public void Update(BackgroundJobInfo jobInfo)
{
BackgroundJobRepository.Update(
ObjectMapper.Map<BackgroundJobInfo, BackgroundJobRecord>(jobInfo)
);
}
public virtual async Task UpdateAsync(BackgroundJobInfo jobInfo) public virtual async Task UpdateAsync(BackgroundJobInfo jobInfo)
{ {
await BackgroundJobRepository.UpdateAsync( await BackgroundJobRepository.UpdateAsync(

2
modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/IBackgroundJobRepository.cs

@ -7,6 +7,8 @@ namespace Volo.Abp.BackgroundJobs
{ {
public interface IBackgroundJobRepository : IBasicRepository<BackgroundJobRecord, Guid> public interface IBackgroundJobRepository : IBasicRepository<BackgroundJobRecord, Guid>
{ {
List<BackgroundJobRecord> GetWaitingList(int maxResultCount);
Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount); Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount);
} }
} }

17
modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs

@ -21,16 +21,27 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
Clock = clock; Clock = clock;
} }
public List<BackgroundJobRecord> GetWaitingList(int maxResultCount)
{
return GetWaitingListQuery(maxResultCount)
.ToList();
}
public async Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount) public async Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount)
{
return await GetWaitingListQuery(maxResultCount)
.ToListAsync();
}
private IQueryable<BackgroundJobRecord> GetWaitingListQuery(int maxResultCount)
{ {
var now = Clock.Now; var now = Clock.Now;
return await DbSet return DbSet
.Where(t => !t.IsAbandoned && t.NextTryTime <= now) .Where(t => !t.IsAbandoned && t.NextTryTime <= now)
.OrderByDescending(t => t.Priority) .OrderByDescending(t => t.Priority)
.ThenBy(t => t.TryCount) .ThenBy(t => t.TryCount)
.ThenBy(t => t.NextTryTime) .ThenBy(t => t.NextTryTime)
.Take(maxResultCount) .Take(maxResultCount);
.ToListAsync();
} }
} }
} }

17
modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs

@ -21,16 +21,27 @@ namespace Volo.Abp.BackgroundJobs.MongoDB
Clock = clock; Clock = clock;
} }
public List<BackgroundJobRecord> GetWaitingList(int maxResultCount)
{
return GetWaitingListQuery(maxResultCount)
.ToList();
}
public async Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount) public async Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount)
{
return await GetWaitingListQuery(maxResultCount)
.ToListAsync();
}
private IMongoQueryable<BackgroundJobRecord> GetWaitingListQuery(int maxResultCount)
{ {
var now = Clock.Now; var now = Clock.Now;
return await GetMongoQueryable() return GetMongoQueryable()
.Where(t => !t.IsAbandoned && t.NextTryTime <= now) .Where(t => !t.IsAbandoned && t.NextTryTime <= now)
.OrderByDescending(t => t.Priority) .OrderByDescending(t => t.Priority)
.ThenBy(t => t.TryCount) .ThenBy(t => t.TryCount)
.ThenBy(t => t.NextTryTime) .ThenBy(t => t.NextTryTime)
.Take(maxResultCount) .Take(maxResultCount);
.ToListAsync();
} }
} }
} }

2
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs

@ -5,7 +5,7 @@ using Volo.Abp.Application.Services;
namespace Volo.Abp.Identity namespace Volo.Abp.Identity
{ {
public interface IIdentityRoleAppService : IAsyncCrudAppService<IdentityRoleDto, Guid, GetIdentityRolesInput, IdentityRoleCreateDto, IdentityRoleUpdateDto> public interface IIdentityRoleAppService : ICrudAppService<IdentityRoleDto, Guid, GetIdentityRolesInput, IdentityRoleCreateDto, IdentityRoleUpdateDto>
{ {
//TODO: remove after a better design //TODO: remove after a better design
Task<List<IdentityRoleDto>> GetAllListAsync(); Task<List<IdentityRoleDto>> GetAllListAsync();

2
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs

@ -5,7 +5,7 @@ using Volo.Abp.Application.Services;
namespace Volo.Abp.Identity namespace Volo.Abp.Identity
{ {
public interface IIdentityUserAppService : IAsyncCrudAppService<IdentityUserDto, Guid, GetIdentityUsersInput, IdentityUserCreateDto, IdentityUserUpdateDto> public interface IIdentityUserAppService : ICrudAppService<IdentityUserDto, Guid, GetIdentityUsersInput, IdentityUserCreateDto, IdentityUserUpdateDto>
{ {
Task<ListResultDto<IdentityRoleDto>> GetRolesAsync(Guid id); Task<ListResultDto<IdentityRoleDto>> GetRolesAsync(Guid id);

2
modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/ITenantAppService.cs

@ -4,7 +4,7 @@ using Volo.Abp.Application.Services;
namespace Volo.Abp.TenantManagement namespace Volo.Abp.TenantManagement
{ {
public interface ITenantAppService : IAsyncCrudAppService<TenantDto, Guid, GetTenantsInput, TenantCreateDto, TenantUpdateDto> public interface ITenantAppService : ICrudAppService<TenantDto, Guid, GetTenantsInput, TenantCreateDto, TenantUpdateDto>
{ {
Task<string> GetDefaultConnectionStringAsync(Guid id); Task<string> GetDefaultConnectionStringAsync(Guid id);

5
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs

@ -13,6 +13,11 @@ namespace Volo.Abp.TenantManagement
bool includeDetails = true, bool includeDetails = true,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Tenant FindByName(
string name,
bool includeDetails = true
);
Task<List<Tenant>> GetListAsync( Task<List<Tenant>> GetListAsync(
string sorting = null, string sorting = null,
int maxResultCount = int.MaxValue, int maxResultCount = int.MaxValue,

28
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs

@ -51,5 +51,33 @@ namespace Volo.Abp.TenantManagement
return _objectMapper.Map<Tenant, TenantConfiguration>(tenant); return _objectMapper.Map<Tenant, TenantConfiguration>(tenant);
} }
} }
public TenantConfiguration Find(string name)
{
using (_currentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
var tenant = _tenantRepository.FindByName(name);
if (tenant == null)
{
return null;
}
return _objectMapper.Map<Tenant, TenantConfiguration>(tenant);
}
}
public TenantConfiguration Find(Guid id)
{
using (_currentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
var tenant = _tenantRepository.Find(id);
if (tenant == null)
{
return null;
}
return _objectMapper.Map<Tenant, TenantConfiguration>(tenant);
}
}
} }
} }

11
modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs

@ -25,7 +25,14 @@ namespace Volo.Abp.TenantManagement.EntityFrameworkCore
{ {
return await DbSet return await DbSet
.IncludeDetails(includeDetails) .IncludeDetails(includeDetails)
.FirstOrDefaultAsync(t => t.Name == name, cancellationToken); .FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken));
}
public Tenant FindByName(string name, bool includeDetails = true)
{
return DbSet
.IncludeDetails(includeDetails)
.FirstOrDefault(t => t.Name == name);
} }
public virtual async Task<List<Tenant>> GetListAsync( public virtual async Task<List<Tenant>> GetListAsync(
@ -45,7 +52,7 @@ namespace Volo.Abp.TenantManagement.EntityFrameworkCore
) )
.OrderBy(sorting ?? nameof(Tenant.Name)) .OrderBy(sorting ?? nameof(Tenant.Name))
.PageBy(skipCount, maxResultCount) .PageBy(skipCount, maxResultCount)
.ToListAsync(cancellationToken); .ToListAsync(GetCancellationToken(cancellationToken));
} }
public override IQueryable<Tenant> WithDetails() public override IQueryable<Tenant> WithDetails()

10
modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs

@ -25,7 +25,13 @@ namespace Volo.Abp.TenantManagement.MongoDB
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
return await GetMongoQueryable() return await GetMongoQueryable()
.FirstOrDefaultAsync(t => t.Name == name, cancellationToken); .FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken));
}
public Tenant FindByName(string name, bool includeDetails = true)
{
return GetMongoQueryable()
.FirstOrDefault(t => t.Name == name);
} }
public virtual async Task<List<Tenant>> GetListAsync( public virtual async Task<List<Tenant>> GetListAsync(
@ -45,7 +51,7 @@ namespace Volo.Abp.TenantManagement.MongoDB
.OrderBy(sorting ?? nameof(Tenant.Name)) .OrderBy(sorting ?? nameof(Tenant.Name))
.As<IMongoQueryable<Tenant>>() .As<IMongoQueryable<Tenant>>()
.PageBy<Tenant, IMongoQueryable<Tenant>>(skipCount, maxResultCount) .PageBy<Tenant, IMongoQueryable<Tenant>>(skipCount, maxResultCount)
.ToListAsync(cancellationToken); .ToListAsync(GetCancellationToken(cancellationToken));
} }
} }
} }
Loading…
Cancel
Save