mirror of https://github.com/abpframework/abp.git
177 changed files with 4084 additions and 497 deletions
@ -0,0 +1,5 @@ |
|||
uid: Microsoft.AspNetCore.Routing.AbpEndpointRouterOptions |
|||
summary: '*Summary test' |
|||
|
|||
*Information Test* |
|||
|
|||
@ -1,3 +1,356 @@ |
|||
## Unit of Work |
|||
# Unit of Work |
|||
|
|||
ABP Framework's Unit Of Work (UOW) implementation provides an abstraction and control on a **database connection and transaction** scope in an application. |
|||
|
|||
Once a new UOW started, it creates an **ambient scope** that is participated by **all the database operations** performed in the current scope and considered as a **single transaction boundary**. The operations are **committed** (on success) or **rolled back** (on exception) all together. |
|||
|
|||
ABP's UOW system is; |
|||
|
|||
* **Works conventional**, so most of the times you don't deal with UOW at all. |
|||
* **Database provider independent**. |
|||
* **Web independent**, that means you can create unit of work scopes in any type of applications beside web applications/services. |
|||
|
|||
## Conventions |
|||
|
|||
The following method types are considered as a unit of work: |
|||
|
|||
* ASP.NET Core MVC **Controller Actions**. |
|||
* ASP.NET Core Razor **Page Handlers**. |
|||
* **Application service** methods. |
|||
* **Repository methods**. |
|||
|
|||
A UOW automatically begins for these methods **except** if there is already a **surrounding (ambient)** UOW in action. Examples; |
|||
|
|||
* If you call a [repository](Repositories.md) method and there is no UOW started yet, it automatically **begins a new transactional UOW** that involves all the operations done in the repository method and **commits the transaction** if the repository method **doesn't throw any exception.** The repository method doesn't know about UOW or transaction at all. It just works on a regular database objects (`DbContext` for [EF Core](Entity-Framework-Core.md), for example) and the UOW is handled by the ABP Framework. |
|||
* If you call an [application service](Application-Services.md) method, the same UOW system works just as explained above. If the application service method uses some repositories, the repositories **don't begin a new UOW**, but **participates to the current unit of work** started by the ABP Framework for the application service method. |
|||
* The same is true for an ASP.NET Core controller action. If the operation has started with a controller action, then the **UOW scope is the controller action's method body**. |
|||
|
|||
All of these are automatically handled by the ABP Framework. |
|||
|
|||
### Database Transaction Behavior |
|||
|
|||
While the section above explains the UOW as it is database transaction, actually a UOW doesn't have to be transactional. By default; |
|||
|
|||
* **HTTP GET** requests don't start a transactional UOW. They still starts a UOW, but **doesn't create a database transaction**. |
|||
* All other HTTP request types start a UOW with a database transaction, if database level transactions are supported by the underlying database provider. |
|||
|
|||
This is because an HTTP GET request doesn't (and shouldn't) make any change in the database. You can change this behavior using the options explained below. |
|||
|
|||
## Default Options |
|||
|
|||
`AbpUnitOfWorkDefaultOptions` is used to configure the default options for the unit of work system. Configure the options in the `ConfigureServices` method of your [module](Module-Development-Basics.md). |
|||
|
|||
**Example: Completely disable the database transactions** |
|||
|
|||
````csharp |
|||
Configure<AbpUnitOfWorkDefaultOptions>(options => |
|||
{ |
|||
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; |
|||
}); |
|||
```` |
|||
|
|||
### Option Properties |
|||
|
|||
* `TransactionBehavior` (`enum`: `UnitOfWorkTransactionBehavior`). A global point to configure the transaction behavior. Default value is `Auto` and work as explained in the "*Database Transaction Behavior*" section above. You can enable (even for HTTP GET requests) or disable transactions with this option. |
|||
* `TimeOut` (`TimeSpan?`): Used to set the timeout value for UOWs. **Default value is `null`** and uses to the default of the underlying database provider. |
|||
* `IsolationLevel` (`IsolationLevel?`): Used to set the [isolation level](https://docs.microsoft.com/en-us/dotnet/api/system.data.isolationlevel) of the database transaction, if the UOW is transactional. |
|||
|
|||
## Controlling the Unit Of Work |
|||
|
|||
In some cases, you may want to change the conventional transaction scope, create inner scopes or fine control the transaction behavior. The following sections cover these possibilities. |
|||
|
|||
### IUnitOfWorkEnabled Interface |
|||
|
|||
This is an easy way to enable UOW for a class (or a hierarchy of classes) that is not unit of work by the conventions explained above. |
|||
|
|||
**Example: Implement `IUnitOfWorkEnabled` for an arbitrary service** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace AbpDemo |
|||
{ |
|||
public class MyService : ITransientDependency, IUnitOfWorkEnabled |
|||
{ |
|||
public virtual async Task FooAsync() |
|||
{ |
|||
//this is a method with a UOW scope |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Then `MyService` (and any class derived from it) methods will be UOW. |
|||
|
|||
However, there are **some rules should be followed** in order to make it working; |
|||
|
|||
* If you are **not injecting** the service over an interface (like `IMyService`), then the methods of the service must be `virtual` (otherwise, [dynamic proxy / interception](Dynamic-Proxying-Interceptors.md) system can not work). |
|||
* Only `async` methods (methods returning a `Task` or `Task<T>`) are intercepted. So, sync methods can not start a UOW. |
|||
|
|||
> Notice that if `FooAsync` is called inside a UOW scope, then it already participates to the UOW without needing to the `IUnitOfWorkEnabled` or any other configuration. |
|||
|
|||
### UnitOfWorkAttribute |
|||
|
|||
`UnitOfWork` attribute provides much more possibility like enabling or disabling UOW and controlling the transaction behavior. |
|||
|
|||
`UnitOfWork` attribute can be used for a **class** or a **method** level. |
|||
|
|||
**Example: Enable UOW for a specific method of a class** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace AbpDemo |
|||
{ |
|||
public class MyService : ITransientDependency |
|||
{ |
|||
[UnitOfWork] |
|||
public virtual async Task FooAsync() |
|||
{ |
|||
//this is a method with a UOW scope |
|||
} |
|||
|
|||
public virtual async Task BarAsync() |
|||
{ |
|||
//this is a method without UOW |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
**Example: Enable UOW for all the methods of a class** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace AbpDemo |
|||
{ |
|||
[UnitOfWork] |
|||
public class MyService : ITransientDependency |
|||
{ |
|||
public virtual async Task FooAsync() |
|||
{ |
|||
//this is a method with a UOW scope |
|||
} |
|||
|
|||
public virtual async Task BarAsync() |
|||
{ |
|||
//this is a method with a UOW scope |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Again, the **same rules** are valid here: |
|||
|
|||
* If you are **not injecting** the service over an interface (like `IMyService`), then the methods of the service must be `virtual` (otherwise, [dynamic proxy / interception](Dynamic-Proxying-Interceptors.md) system can not work). |
|||
* Only `async` methods (methods returning a `Task` or `Task<T>`) are intercepted. So, sync methods can not start a UOW. |
|||
|
|||
#### UnitOfWorkAttribute Properties |
|||
|
|||
* `IsTransactional` (`bool?`): Used to set whether the UOW should be transactional or not. **Default value is `null`**. if you leave it `null`, it is determined automatically based on the conventions and the configuration. |
|||
* `TimeOut` (`int?`): Used to set the timeout value for this UOW. **Default value is `null`** and fallbacks to the default configured value. |
|||
* `IsolationLevel` (`IsolationLevel?`): Used to set the [isolation level](https://docs.microsoft.com/en-us/dotnet/api/system.data.isolationlevel) of the database transaction, if the UOW is transactional. If not set, uses the default configured value. |
|||
* `IsDisabled` (`bool`): Used to disable the UOW for the current method/class. |
|||
|
|||
> If a method is called in an ambient UOW scope, then the `UnitOfWork` attribute is ignored and the method participates to the surrounding transaction in any way. |
|||
|
|||
**Example: Disable UOW for a controller action** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace AbpDemo.Web |
|||
{ |
|||
public class MyController : AbpController |
|||
{ |
|||
[UnitOfWork(IsDisabled = true)] |
|||
public virtual async Task FooAsync() |
|||
{ |
|||
//... |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
## IUnitOfWorkManager |
|||
|
|||
`IUnitOfWorkManager` is the main service that is used to control the unit of work system. The following sections explains how to directly work with this service (while most of the times you won't need). |
|||
|
|||
### Begin a New Unit Of Work |
|||
|
|||
`IUnitOfWorkManager.Begin` method is used to create a new UOW scope. |
|||
|
|||
**Example: Create a new non-transactional UOW scope** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace AbpDemo |
|||
{ |
|||
public class MyService : ITransientDependency |
|||
{ |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
|
|||
public MyService(IUnitOfWorkManager unitOfWorkManager) |
|||
{ |
|||
_unitOfWorkManager = unitOfWorkManager; |
|||
} |
|||
|
|||
public virtual async Task FooAsync() |
|||
{ |
|||
using (var uow = _unitOfWorkManager.Begin( |
|||
requiresNew: true, isTransactional: false |
|||
)) |
|||
{ |
|||
//... |
|||
|
|||
await uow.CompleteAsync(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
`Begin` method gets the following optional parameters: |
|||
|
|||
* `requiresNew` (`bool`): Set `true` to ignore the surrounding unit of work and start a new UOW with the provided options. **Default value is `false`. If it is `false` and there is a surrounding UOW, `Begin` method doesn't actually begin a new UOW, but silently participates to the existing UOW.** |
|||
* `isTransactional` (`bool`). Default value is `false`. |
|||
* `isolationLevel` (`IsolationLevel?`): Used to set the [isolation level](https://docs.microsoft.com/en-us/dotnet/api/system.data.isolationlevel) of the database transaction, if the UOW is transactional. If not set, uses the default configured value. |
|||
* `TimeOut` (`TimeSpan?`): Used to set the timeout value for this UOW. **Default value is `null`** and fallbacks to the default configured value. |
|||
|
|||
### The Current Unit Of Work |
|||
|
|||
UOW is ambient, as explained before. If you need to access to the current unit of work, you can use the `IUnitOfWorkManager.Current` property. |
|||
|
|||
**Example: Get the current UOW** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace AbpDemo |
|||
{ |
|||
public class MyProductService : ITransientDependency |
|||
{ |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
|
|||
public MyProductService(IUnitOfWorkManager unitOfWorkManager) |
|||
{ |
|||
_unitOfWorkManager = unitOfWorkManager; |
|||
} |
|||
|
|||
public async Task FooAsync() |
|||
{ |
|||
var uow = _unitOfWorkManager.Current; |
|||
//... |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
`Current` property returns a `IUnitOfWork` object. |
|||
|
|||
> **Current Unit Of Work can be `null`** if there is no surrounding unit of work. It won't be `null` if your class is a conventional UOW class, you manually made it UOW or it was called inside a UOW scope, as explained before. |
|||
|
|||
#### SaveChangesAsync |
|||
|
|||
`IUnitOfWork.SaveChangesAsync()` method can be needed to save all the changes until now to the database. If you are using EF Core, it behaves exactly same. If the current UOW is transactional, even saved changes can be rolled back on an error (for the supporting database providers). |
|||
|
|||
**Example: Save changes after inserting an entity to get its auto-increment id** |
|||
|
|||
````csharp |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace AbpDemo |
|||
{ |
|||
public class CategoryAppService : ApplicationService, ICategoryAppService |
|||
{ |
|||
private readonly IRepository<Category, int> _categoryRepository; |
|||
|
|||
public CategoryAppService(IRepository<Category, int> categoryRepository) |
|||
{ |
|||
_categoryRepository = categoryRepository; |
|||
} |
|||
|
|||
public async Task<int> CreateAsync(string name) |
|||
{ |
|||
var category = new Category {Name = name}; |
|||
await _categoryRepository.InsertAsync(category); |
|||
|
|||
//Saving changes to be able to get the auto increment id |
|||
await UnitOfWorkManager.Current.SaveChangesAsync(); |
|||
|
|||
return category.Id; |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
This example uses auto-increment `int` primary key for the `Category` [entity](Entities.md). Auto-increment PKs require to save the entity to the database to get the id of the new entity. |
|||
|
|||
This example is an [application service](Application-Services.md) derived from the base `ApplicationService` class, which already has the `IUnitOfWorkManager` service injected as the `UnitOfWorkManager` property. So, no need to inject it manually. |
|||
|
|||
Since getting the current UOW is pretty common, there is also a `CurrentUnitOfWork` property as a shortcut to the `UnitOfWorkManager.Current`. So, the example above can be changed to use it: |
|||
|
|||
````csharp |
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
```` |
|||
|
|||
##### Alternative to the SaveChanges() |
|||
|
|||
Since saving changes after inserting, updating or deleting an entity can be frequently needed, corresponding [repository](Repositories.md) methods has an optional `autoSave` parameter. So, the `CreateAsync` method above could be re-written as shown below: |
|||
|
|||
````csharp |
|||
public async Task<int> CreateAsync(string name) |
|||
{ |
|||
var category = new Category {Name = name}; |
|||
await _categoryRepository.InsertAsync(category, autoSave: true); |
|||
return category.Id; |
|||
} |
|||
```` |
|||
|
|||
If your intent is just to save the changes after creating/updating/deleting an entity, it is suggested to use the `autoSave` option instead of manually using the `CurrentUnitOfWork.SaveChangesAsync()`. |
|||
|
|||
> **Note-1**: All changes are automatically saved when a unit of work ends without any error. So, don't call `SaveChangesAsync()` unless you really need it. |
|||
> |
|||
> **Note-2**: If you use `Guid` as the primary key, you never need to save changes on insert to just get the generated id, because `Guid` keys are set in the application and are immediately available once you create a new entity. |
|||
|
|||
#### Other IUnitOfWork Properties/Methods |
|||
|
|||
* `OnCompleted` method gets a callback action which is called when the unit of work successfully completed (where you can be sure that all changes are saved). |
|||
* `Failed` and `Disposed` events can be used to be notified if the UOW fails or when it is disposed. |
|||
* `Complete` and `Rollback` methods are used to complete (commit) or roll backs the current UOW, which are normally used internally by the ABP Framework but can be used if you manually start a transaction using the `IUnitOfWorkManager.Begin` method. |
|||
* `Options` can be used to get options that was used while starting the UOW. |
|||
* `Items` dictionary can be used to store and get arbitrary objects inside the same unit of work, which can be a point to implement custom logics. |
|||
|
|||
## ASP.NET Core Integration |
|||
|
|||
Unit of work system is fully integrated to the ASP.NET Core. It properly works when you use ASP.NET Core MVC Controllers or Razor Pages. It defines action filters and page filters for the UOW system. |
|||
|
|||
> You typically do nothing to configure the UOW when you use ASP.NET Core. |
|||
|
|||
### Unit Of Work Middleware |
|||
|
|||
`AbpUnitOfWorkMiddleware` is a middleware that can enable UOW in the ASP.NET Core request pipeline. This might be needed if you need to enlarge the UOW scope to cover some other middleware(s). |
|||
|
|||
**Example:** |
|||
|
|||
````csharp |
|||
app.UseUnitOfWork(); |
|||
app.UseConfiguredEndpoints(); |
|||
```` |
|||
|
|||
TODO |
|||
@ -1,23 +1,35 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Resources |
|||
{ |
|||
public class WebRequestResources : IWebRequestResources, IScopedDependency |
|||
{ |
|||
protected List<string> Resources { get; } |
|||
protected Dictionary<string, List<string>> Resources { get; } |
|||
|
|||
public WebRequestResources() |
|||
protected IHttpContextAccessor HttpContextAccessor{ get; } |
|||
|
|||
public WebRequestResources(IHttpContextAccessor httpContextAccessor) |
|||
{ |
|||
Resources = new List<string>(); |
|||
HttpContextAccessor = httpContextAccessor; |
|||
Resources = new Dictionary<string, List<string>>(); |
|||
} |
|||
|
|||
public List<string> TryAdd(IEnumerable<string> resources) |
|||
public List<string> TryAdd(List<string> resources) |
|||
{ |
|||
var resourceToBeAdded = resources.Except(Resources).ToList(); |
|||
Resources.AddRange(resourceToBeAdded); |
|||
return resourceToBeAdded; |
|||
var path = HttpContextAccessor.HttpContext?.Request?.Path ?? ""; |
|||
|
|||
if (Resources.TryGetValue(path, out var res)) |
|||
{ |
|||
var resourceToBeAdded = resources.Except(res).ToList(); |
|||
res.AddRange(resourceToBeAdded); |
|||
return resourceToBeAdded; |
|||
} |
|||
|
|||
Resources.Add(path, resources); |
|||
return resources; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,70 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Volo.Abp.Cli.ProjectBuilding.Building; |
|||
|
|||
namespace Volo.Abp.Cli.ProjectBuilding.Templates.App |
|||
{ |
|||
public class AppTemplateRemoveMongodbCollectionFixtureStep : ProjectBuildPipelineStep |
|||
{ |
|||
public override void Execute(ProjectBuildContext context) |
|||
{ |
|||
//MyCompanyName.MyProjectName.Application.Tests
|
|||
RemoveFile(context, "/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationCollection.cs"); |
|||
RemoveKeyword(context, |
|||
"/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleAppServiceTests.cs", |
|||
"[Collection(MyProjectNameTestConsts.CollectionDefinitionName)]"); |
|||
|
|||
//MyCompanyName.MyProjectName.Domain.Tests
|
|||
RemoveFile(context, "/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyProjectNameDomainCollection.cs"); |
|||
RemoveKeyword(context, |
|||
"/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/Samples/SampleDomainTests.cs", |
|||
"[Collection(MyProjectNameTestConsts.CollectionDefinitionName)]"); |
|||
|
|||
//MyCompanyName.MyProjectName.EntityFrameworkCore.Tests
|
|||
RemoveFile(context, "/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreCollection.cs"); |
|||
RemoveFile(context, "/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreCollectionFixtureBase.cs"); |
|||
RemoveFile(context, "/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreFixture.cs"); |
|||
RemoveKeyword(context, |
|||
"/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/Samples/SampleRepositoryTests.cs", |
|||
"[Collection(MyProjectNameTestConsts.CollectionDefinitionName)]"); |
|||
|
|||
//MyCompanyName.MyProjectName.Web.Tests
|
|||
RemoveFile(context, "/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests/MyProjectNameWebCollection.cs"); |
|||
RemoveKeyword(context, |
|||
"/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests/Pages/Index_Tests.cs", |
|||
"[Collection(MyProjectNameTestConsts.CollectionDefinitionName)]"); |
|||
|
|||
//MyCompanyName.MyProjectName.TestBase
|
|||
RemoveFile(context, "/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestConsts.cs"); |
|||
} |
|||
|
|||
private static void RemoveFile(ProjectBuildContext context, string targetModuleFilePath) |
|||
{ |
|||
var file = context.Files.FirstOrDefault(x => x.Name == targetModuleFilePath); |
|||
if (file != null) |
|||
{ |
|||
context.Files.Remove(file); |
|||
} |
|||
} |
|||
|
|||
private static void RemoveKeyword(ProjectBuildContext context, string targetModuleFilePath, string keyword) |
|||
{ |
|||
var file = context.GetFile(targetModuleFilePath); |
|||
|
|||
file.NormalizeLineEndings(); |
|||
|
|||
var lines = file.GetLines(); |
|||
var newLines = new List<string>(); |
|||
|
|||
for (var i = 0; i < lines.Length; i++) |
|||
{ |
|||
if (!lines[i].Contains(keyword)) |
|||
{ |
|||
newLines.Add(lines[i]); |
|||
} |
|||
} |
|||
|
|||
file.SetLines(newLines); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using System.Net.Http; |
|||
|
|||
namespace Volo.Abp.IdentityModel |
|||
{ |
|||
public class IdentityModelHttpRequestMessageOptions |
|||
{ |
|||
public Action<HttpRequestMessage> ConfigureHttpRequestMessage { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
namespace Volo.Abp.Localization |
|||
{ |
|||
public static class AbpLocalizationOptionsExtensions |
|||
{ |
|||
public static AbpLocalizationOptions AddLanguagesMapOrUpdate(this AbpLocalizationOptions localizationOptions, |
|||
string packageName, params NameValue[] maps) |
|||
{ |
|||
foreach (var map in maps) |
|||
{ |
|||
AddOrUpdate(localizationOptions.LanguagesMap, packageName, map); |
|||
} |
|||
|
|||
return localizationOptions; |
|||
} |
|||
|
|||
public static string GetLanguagesMap(this AbpLocalizationOptions localizationOptions, string packageName, |
|||
string language) |
|||
{ |
|||
return localizationOptions.LanguagesMap.TryGetValue(packageName, out var maps) |
|||
? maps.FirstOrDefault(x => x.Name == language)?.Value ?? language |
|||
: language; |
|||
} |
|||
|
|||
public static AbpLocalizationOptions AddLanguageFilesMapOrUpdate(this AbpLocalizationOptions localizationOptions, |
|||
string packageName, params NameValue[] maps) |
|||
{ |
|||
foreach (var map in maps) |
|||
{ |
|||
AddOrUpdate(localizationOptions.LanguageFilesMap, packageName, map); |
|||
} |
|||
|
|||
return localizationOptions; |
|||
} |
|||
|
|||
public static string GetLanguageFilesMap(this AbpLocalizationOptions localizationOptions, string packageName, |
|||
string language) |
|||
{ |
|||
return localizationOptions.LanguageFilesMap.TryGetValue(packageName, out var maps) |
|||
? maps.FirstOrDefault(x => x.Name == language)?.Value ?? language |
|||
: language; |
|||
} |
|||
|
|||
private static void AddOrUpdate(IDictionary<string, List<NameValue>> maps, string packageName, NameValue value) |
|||
{ |
|||
if (maps.TryGetValue(packageName, out var existMaps)) |
|||
{ |
|||
existMaps.GetOrAdd(x => x.Name == value.Name, () => value).Value = value.Value; |
|||
} |
|||
else |
|||
{ |
|||
maps.Add(packageName, new List<NameValue> {value}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,25 +1,398 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Linq.Expressions; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Linq |
|||
{ |
|||
public interface IAsyncQueryableExecuter |
|||
{ |
|||
#region Contains
|
|||
|
|||
Task<bool> ContainsAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] T item, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Any/All
|
|||
|
|||
Task<bool> AnyAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<bool> AllAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Count/LongCount
|
|||
|
|||
Task<int> CountAsync<T>( |
|||
IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int> CountAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> LongCountAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> LongCountAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region First/FirstOrDefault
|
|||
|
|||
Task<T> FirstAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> FirstAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<List<T>> ToListAsync<T>( |
|||
IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<T> FirstOrDefaultAsync<T>( |
|||
IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> FirstOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Last/LastOrDefault
|
|||
|
|||
Task<T> LastAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> LastAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> LastOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> LastOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Single/SingleOrDefault
|
|||
|
|||
Task<T> SingleAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> SingleAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<T> SingleOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<T> SingleOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Min
|
|||
|
|||
Task<T> MinAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<TResult> MinAsync<T, TResult>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, TResult>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Max
|
|||
|
|||
Task<T> MaxAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<TResult> MaxAsync<T, TResult>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, TResult>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Sum
|
|||
|
|||
Task<decimal> SumAsync( |
|||
[NotNull] IQueryable<decimal> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal?> SumAsync( |
|||
[NotNull] IQueryable<decimal?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int> SumAsync( |
|||
[NotNull] IQueryable<int> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int?> SumAsync( |
|||
[NotNull] IQueryable<int?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> SumAsync( |
|||
[NotNull] IQueryable<long> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long?> SumAsync( |
|||
[NotNull] IQueryable<long?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> SumAsync( |
|||
[NotNull] IQueryable<double> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> SumAsync( |
|||
[NotNull] IQueryable<double?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> SumAsync( |
|||
[NotNull] IQueryable<float> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> SumAsync( |
|||
[NotNull] IQueryable<float?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Average
|
|||
|
|||
Task<decimal> AverageAsync( |
|||
[NotNull] IQueryable<decimal> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal?> AverageAsync( |
|||
[NotNull] IQueryable<decimal?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<decimal?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync( |
|||
[NotNull] IQueryable<int> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync( |
|||
[NotNull] IQueryable<int?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<double?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<double> AverageAsync( |
|||
[NotNull] IQueryable<long> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync( |
|||
[NotNull] IQueryable<long?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync( |
|||
[NotNull] IQueryable<double> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync( |
|||
[NotNull] IQueryable<double?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> AverageAsync( |
|||
[NotNull] IQueryable<float> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> AverageAsync( |
|||
[NotNull] IQueryable<float?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region ToList/Array
|
|||
|
|||
Task<List<T>> ToListAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T[]> ToArrayAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,18 +1,400 @@ |
|||
using System.Collections.Generic; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Linq.Expressions; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
|
|||
namespace Volo.Abp.Linq |
|||
{ |
|||
public interface IAsyncQueryableProvider |
|||
{ |
|||
bool CanExecute<T>(IQueryable<T> queryable); |
|||
|
|||
Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default); |
|||
|
|||
Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default); |
|||
#region Contains
|
|||
|
|||
Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default); |
|||
Task<bool> ContainsAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] T item, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Any/All
|
|||
|
|||
Task<bool> AnyAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<bool> AllAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Count/LongCount
|
|||
|
|||
Task<int> CountAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int> CountAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> LongCountAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> LongCountAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region First/FirstOrDefault
|
|||
|
|||
Task<T> FirstAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> FirstAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> FirstOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> FirstOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Last/LastOrDefault
|
|||
|
|||
Task<T> LastAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> LastAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> LastOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> LastOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Single/SingleOrDefault
|
|||
|
|||
Task<T> SingleAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T> SingleAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<T> SingleOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<T> SingleOrDefaultAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, bool>> predicate, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Min
|
|||
|
|||
Task<T> MinAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<TResult> MinAsync<T, TResult>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, TResult>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Max
|
|||
|
|||
Task<T> MaxAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<TResult> MaxAsync<T, TResult>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, TResult>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Sum
|
|||
|
|||
Task<decimal> SumAsync( |
|||
[NotNull] IQueryable<decimal> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal?> SumAsync( |
|||
[NotNull] IQueryable<decimal?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int> SumAsync( |
|||
[NotNull] IQueryable<int> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int?> SumAsync( |
|||
[NotNull] IQueryable<int?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<int?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> SumAsync( |
|||
[NotNull] IQueryable<long> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long?> SumAsync( |
|||
[NotNull] IQueryable<long?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<long?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> SumAsync( |
|||
[NotNull] IQueryable<double> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> SumAsync( |
|||
[NotNull] IQueryable<double?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> SumAsync( |
|||
[NotNull] IQueryable<float> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> SumAsync( |
|||
[NotNull] IQueryable<float?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> SumAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region Average
|
|||
|
|||
Task<decimal> AverageAsync( |
|||
[NotNull] IQueryable<decimal> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal?> AverageAsync( |
|||
[NotNull] IQueryable<decimal?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<decimal> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<decimal?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, decimal?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync( |
|||
[NotNull] IQueryable<int> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync( |
|||
[NotNull] IQueryable<int?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<double?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, int?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<double> AverageAsync( |
|||
[NotNull] IQueryable<long> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync( |
|||
[NotNull] IQueryable<long?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, long?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync( |
|||
[NotNull] IQueryable<double> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync( |
|||
[NotNull] IQueryable<double?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<double?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, double?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> AverageAsync( |
|||
[NotNull] IQueryable<float> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> AverageAsync( |
|||
[NotNull] IQueryable<float?> source, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<float?> AverageAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
[NotNull] Expression<Func<T, float?>> selector, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
|
|||
#region ToList/Array
|
|||
|
|||
Task<List<T>> ToListAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
|
|||
Task<T[]> ToArrayAsync<T>( |
|||
[NotNull] IQueryable<T> queryable, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,31 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Blogging.Admin.Application.Contracts</AssemblyName> |
|||
<PackageId>Volo.Blogging.Admin.Application.Contracts</PackageId> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Blogging.Domain.Shared\Volo.Blogging.Domain.Shared.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Ddd.Application\Volo.Abp.Ddd.Application.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\cs.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\de.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\en.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\nl.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\pl-PL.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\pt-BR.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\sl.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\tr.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\vi.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\zh-Hans.json" /> |
|||
<EmbeddedResource Include="Volo\Blogging\Admin\Localization\Resources\Blogging\Admin\ApplicationContracts\zh-Hant.json" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,25 @@ |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
using Volo.Blogging.Localization; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
[DependsOn(typeof(BloggingDomainSharedModule))] |
|||
public class BloggingAdminApplicationContractsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<BloggingAdminApplicationContractsModule>(); |
|||
}); |
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<BloggingResource>() |
|||
.AddVirtualJson("Volo/Blogging/Admin/Localization/Resources/Blogging/Admin/ApplicationContracts"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Blogging.Localization; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
public class BloggingAdminPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var bloggingGroup = context.AddGroup(BloggingAdminPermissions.GroupName, L("Permission:BloggingAdmin")); |
|||
|
|||
var blogs = bloggingGroup.AddPermission(BloggingAdminPermissions.Blogs.Default, L("Permission:Blogs")); |
|||
blogs.AddChild(BloggingAdminPermissions.Blogs.Management, L("Permission:Management")); |
|||
blogs.AddChild(BloggingAdminPermissions.Blogs.Update, L("Permission:Edit")); |
|||
blogs.AddChild(BloggingAdminPermissions.Blogs.Delete, L("Permission:Delete")); |
|||
blogs.AddChild(BloggingAdminPermissions.Blogs.Create, L("Permission:Create")); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<BloggingResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using Volo.Abp.Reflection; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
public class BloggingAdminPermissions |
|||
{ |
|||
public const string GroupName = "Blogging.Admin"; |
|||
|
|||
public static class Blogs |
|||
{ |
|||
public const string Default = GroupName + ".Blog"; |
|||
public const string Management = Default + ".Management"; |
|||
public const string Delete = Default + ".Delete"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Create = Default + ".Create"; |
|||
} |
|||
|
|||
public static string[] GetAll() |
|||
{ |
|||
return ReflectionHelper.GetPublicConstantsRecursively(typeof(BloggingAdminPermissions)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
public static class BloggingAdminRemoteServiceConsts |
|||
{ |
|||
public const string RemoteServiceName = "BloggingAdmin"; |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.Blogging.Admin.Blogs |
|||
{ |
|||
public class BlogDto : FullAuditedEntityDto<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public string ShortName { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Volo.Blogging.Admin.Blogs |
|||
{ |
|||
public interface IBlogManagementAppService : IApplicationService |
|||
{ |
|||
Task<ListResultDto<BlogDto>> GetListAsync(); |
|||
|
|||
Task<BlogDto> GetAsync(Guid id); |
|||
|
|||
Task<BlogDto> CreateAsync(CreateBlogDto input); |
|||
|
|||
Task<BlogDto> UpdateAsync(Guid id, UpdateBlogDto input); |
|||
|
|||
Task DeleteAsync(Guid id); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Blogy", |
|||
"Permission:Management": "Správa", |
|||
"Permission:Edit": "Upravit", |
|||
"Permission:Create": "Vytvořit", |
|||
"Permission:Delete": "Smazat" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "de", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Blogs", |
|||
"Permission:Management": "Verwaltung", |
|||
"Permission:Edit": "Bearbeiten", |
|||
"Permission:Create": "Erstellen", |
|||
"Permission:Delete": "Löschen" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blogging", |
|||
"Permission:Blogs": "Blogs", |
|||
"Permission:Management": "Management", |
|||
"Permission:Edit": "Edit", |
|||
"Permission:Create": "Create", |
|||
"Permission:Delete": "Delete" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "nl", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Blogs", |
|||
"Permission:Management": "Beheer", |
|||
"Permission:Edit": "Bewerk", |
|||
"Permission:Create": "Maak aan", |
|||
"Permission:Delete": "Verwijder" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "pl-PL", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Blogi", |
|||
"Permission:Management": "Zarządzanie", |
|||
"Permission:Edit": "Edytuj", |
|||
"Permission:Create": "Utwórz", |
|||
"Permission:Delete": "Usuń" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Blogs", |
|||
"Permission:Management": "Gerenciamento", |
|||
"Permission:Edit": "Editar", |
|||
"Permission:Create": "Criar", |
|||
"Permission:Delete": "Excluir" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Blogi", |
|||
"Permission:Management": "Upravljanje", |
|||
"Permission:Edit": "Urejanje", |
|||
"Permission:Create": "Ustvarjanje", |
|||
"Permission:Delete": "Brisanje" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Bloglar", |
|||
"Permission:Management": "Yönetme", |
|||
"Permission:Edit": "Düzenle", |
|||
"Permission:Create": "Ekle", |
|||
"Permission:Delete": "Sil" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "Blog", |
|||
"Permission:Blogs": "Blogs", |
|||
"Permission:Management": "Quản lý", |
|||
"Permission:Edit": "Sửa", |
|||
"Permission:Create": "Tạo", |
|||
"Permission:Delete": "Xóa" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "博客", |
|||
"Permission:Blogs": "博客", |
|||
"Permission:Management": "管理", |
|||
"Permission:Edit": "编辑", |
|||
"Permission:Create": "创建", |
|||
"Permission:Delete": "删除" |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"Permission:BloggingAdmin": "部落格", |
|||
"Permission:Blogs": "部落格", |
|||
"Permission:Management": "管理", |
|||
"Permission:Edit": "標及", |
|||
"Permission:Create": "新增", |
|||
"Permission:Delete": "刪除" |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Blogging.Admin.Application</AssemblyName> |
|||
<PackageId>Volo.Blogging.Admin.Application</PackageId> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" /> |
|||
<ProjectReference Include="..\Volo.Blogging.Admin.Application.Contracts\Volo.Blogging.Admin.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\Volo.Blogging.Domain\Volo.Blogging.Domain.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Caching\Volo.Abp.Caching.csproj" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,14 @@ |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Blogging.Localization; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
public abstract class BloggingAdminAppServiceBase : ApplicationService |
|||
{ |
|||
protected BloggingAdminAppServiceBase() |
|||
{ |
|||
ObjectMapperContext = typeof(BloggingAdminApplicationModule); |
|||
LocalizationResource = typeof(BloggingResource); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using AutoMapper; |
|||
using Volo.Blogging.Admin.Blogs; |
|||
using Volo.Blogging.Blogs; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
public class BloggingAdminApplicationAutoMapperProfile : Profile |
|||
{ |
|||
public BloggingAdminApplicationAutoMapperProfile() |
|||
{ |
|||
CreateMap<Blog, BlogDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Blogging.Comments; |
|||
using Volo.Blogging.Posts; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
[DependsOn( |
|||
typeof(BloggingDomainModule), |
|||
typeof(BloggingAdminApplicationContractsModule), |
|||
typeof(AbpCachingModule), |
|||
typeof(AbpAutoMapperModule))] |
|||
public class BloggingAdminApplicationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAutoMapperObjectMapper<BloggingAdminApplicationModule>(); |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddProfile<BloggingAdminApplicationAutoMapperProfile>(validate: true); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Blogging.Blogs; |
|||
|
|||
namespace Volo.Blogging.Admin.Blogs |
|||
{ |
|||
public class BlogManagementAppService : BloggingAdminAppServiceBase, IBlogManagementAppService |
|||
{ |
|||
private readonly IBlogRepository _blogRepository; |
|||
|
|||
public BlogManagementAppService(IBlogRepository blogRepository) |
|||
{ |
|||
_blogRepository = blogRepository; |
|||
} |
|||
|
|||
public async Task<ListResultDto<BlogDto>> GetListAsync() |
|||
{ |
|||
var blogs = await _blogRepository.GetListAsync(); |
|||
|
|||
return new ListResultDto<BlogDto>( |
|||
ObjectMapper.Map<List<Blog>, List<BlogDto>>(blogs) |
|||
); |
|||
} |
|||
|
|||
public async Task<BlogDto> GetAsync(Guid id) |
|||
{ |
|||
var blog = await _blogRepository.GetAsync(id); |
|||
|
|||
return ObjectMapper.Map<Blog, BlogDto>(blog); |
|||
} |
|||
|
|||
[Authorize(BloggingAdminPermissions.Blogs.Create)] |
|||
public async Task<BlogDto> CreateAsync(CreateBlogDto input) |
|||
{ |
|||
var newBlog = await _blogRepository.InsertAsync(new Blog(GuidGenerator.Create(), input.Name, input.ShortName) |
|||
{ |
|||
Description = input.Description |
|||
}); |
|||
|
|||
return ObjectMapper.Map<Blog, BlogDto>(newBlog); |
|||
} |
|||
|
|||
[Authorize(BloggingAdminPermissions.Blogs.Update)] |
|||
public async Task<BlogDto> UpdateAsync(Guid id, UpdateBlogDto input) |
|||
{ |
|||
var blog = await _blogRepository.GetAsync(id); |
|||
|
|||
blog.SetName(input.Name); |
|||
blog.SetShortName(input.ShortName); |
|||
blog.Description = input.Description; |
|||
|
|||
return ObjectMapper.Map<Blog, BlogDto>(blog); |
|||
} |
|||
|
|||
[Authorize(BloggingAdminPermissions.Blogs.Delete)] |
|||
public async Task DeleteAsync(Guid id) |
|||
{ |
|||
await _blogRepository.DeleteAsync(id); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Blogging.Admin.HttpApi.Client</AssemblyName> |
|||
<PackageId>Volo.Blogging.Admin.HttpApi.Client</PackageId> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Blogging.Admin.Application.Contracts\Volo.Blogging.Admin.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Http.Client\Volo.Abp.Http.Client.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,19 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
[DependsOn( |
|||
typeof(BloggingAdminApplicationContractsModule), |
|||
typeof(AbpHttpClientModule))] |
|||
public class BloggingAdminHttpApiClientModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddHttpClientProxies(typeof(BloggingAdminApplicationContractsModule).Assembly, |
|||
BloggingAdminRemoteServiceConsts.RemoteServiceName); |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<AssemblyName>Volo.Blogging.Admin.HttpApi</AssemblyName> |
|||
<PackageId>Volo.Blogging.Admin.HttpApi</PackageId> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Blogging.Admin.Application.Contracts\Volo.Blogging.Admin.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc\Volo.Abp.AspNetCore.Mvc.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,56 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Blogging.Admin.Blogs; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
[RemoteService(Name = BloggingAdminRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("bloggingAdmin")] |
|||
[Route("api/blogging/blogs/admin")] |
|||
public class BlogManagementController : AbpController, IBlogManagementAppService |
|||
{ |
|||
private readonly IBlogManagementAppService _blogManagementAppService; |
|||
|
|||
public BlogManagementController(IBlogManagementAppService blogManagementAppService) |
|||
{ |
|||
_blogManagementAppService = blogManagementAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
public async Task<ListResultDto<BlogDto>> GetListAsync() |
|||
{ |
|||
return await _blogManagementAppService.GetListAsync(); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public async Task<BlogDto> GetAsync(Guid id) |
|||
{ |
|||
return await _blogManagementAppService.GetAsync(id); |
|||
} |
|||
|
|||
[HttpPost] |
|||
public async Task<BlogDto> CreateAsync(CreateBlogDto input) |
|||
{ |
|||
return await _blogManagementAppService.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
public async Task<BlogDto> UpdateAsync(Guid id, UpdateBlogDto input) |
|||
{ |
|||
return await _blogManagementAppService.UpdateAsync(id, input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
public async Task DeleteAsync(Guid id) |
|||
{ |
|||
await _blogManagementAppService.DeleteAsync(id); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using Localization.Resources.AbpUi; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Blogging.Localization; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
[DependsOn( |
|||
typeof(BloggingAdminApplicationContractsModule), |
|||
typeof(AbpAspNetCoreMvcModule))] |
|||
public class BloggingAdminHttpApiModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(BloggingAdminHttpApiModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<BloggingResource>() |
|||
.AddBaseTypes(typeof(AbpUiResource)); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using AutoMapper; |
|||
using Volo.Blogging.Admin.Blogs; |
|||
using Volo.Blogging.Admin.Pages.Blogging.Admin.Blogs; |
|||
using EditModel = Volo.Blogging.Admin.Pages.Blogging.Admin.Blogs.EditModel; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
public class AbpBloggingAdminWebAutoMapperProfile : Profile |
|||
{ |
|||
public AbpBloggingAdminWebAutoMapperProfile() |
|||
{ |
|||
CreateMap<CreateModel.BlogCreateModalView, CreateBlogDto>(); |
|||
CreateMap<BlogDto, EditModel.BlogEditViewModel>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc.Localization; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.UI.Navigation; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
using Volo.Blogging.Localization; |
|||
|
|||
namespace Volo.Blogging.Admin |
|||
{ |
|||
[DependsOn( |
|||
typeof(BloggingAdminHttpApiModule), |
|||
typeof(AbpAspNetCoreMvcUiBootstrapModule), |
|||
typeof(AbpAspNetCoreMvcUiBundlingModule), |
|||
typeof(AbpAutoMapperModule) |
|||
)] |
|||
public class BloggingAdminWebModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
|||
{ |
|||
options.AddAssemblyResource(typeof(BloggingResource), typeof(BloggingAdminWebModule).Assembly); |
|||
}); |
|||
|
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(BloggingAdminWebModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpNavigationOptions>(options => |
|||
{ |
|||
options.MenuContributors.Add(new BloggingAdminMenuContributor()); |
|||
}); |
|||
|
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<BloggingAdminWebModule>("Volo.Blogging.Admin"); |
|||
}); |
|||
|
|||
context.Services.AddAutoMapperObjectMapper<BloggingAdminWebModule>(); |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddProfile<AbpBloggingAdminWebAutoMapperProfile>(validate: true); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,17 @@ |
|||
using Microsoft.AspNetCore.Mvc.Localization; |
|||
using Microsoft.AspNetCore.Mvc.Razor.Internal; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
|||
using Volo.Blogging.Localization; |
|||
|
|||
namespace Volo.Blogging.Admin.Pages.Blogging |
|||
{ |
|||
public abstract class BloggingAdminPage : AbpPage |
|||
{ |
|||
[RazorInject] |
|||
public IHtmlLocalizer<BloggingResource> L { get; set; } |
|||
|
|||
public const string DefaultTitle = "Blogging"; |
|||
|
|||
public const int MaxShortContentLength = 200; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
|||
|
|||
namespace Volo.Blogging.Admin.Pages |
|||
{ |
|||
public abstract class BloggingAdminPageModel : AbpPageModel |
|||
{ |
|||
public BloggingAdminPageModel() |
|||
{ |
|||
ObjectMapperContext = typeof(BloggingAdminWebModule); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue