In the project, we need to configure some parameters, usually using the aspnetcore configuration system through Appsettings JSON to store configuration parameters; Abp framework contains a set of perfect device management module, which can be used to easily obtain and set the settings of application programs.
The five preset settings management providers in the Abp settings management module are
- DefaultValueSettingManagementProvider: gets the value from the default value of the setting definition. The default value cannot be changed because it is hard coded on the setting definition
- ConfigurationSettingManagementProvider: from IConfiguration service Get value from The configuration value cannot be changed because the configuration value cannot be changed at run time
- GlobalSettingManagementProvider: gets or sets the global (system wide) value of the setting
- TenantSettingManagementProvider: gets or sets the setting value of the tenant
- UserSettingManagementProvider: gets or sets the setting value of the user
The following graphically shows the model for setting and obtaining values between five settings
You can also extend your own settings provider, such as the organization's settings management provider, which should be placed between tenants and users.
The following is an example of the source code of the previous chapter to introduce how to add setting management for the file management module.
1. Add settings definition
The so-called DDD domain driver is designed from the domain layer. Whether it is the file management module in the previous chapter or the setting management here, it starts from the domain and extends step by step until the front-end page
Find the Domain project of file management, and in the Settings directory, filemanagementsettings CS to add a constant to set the Key
public static class FileManagementSettings { public const string GroupName = "FileManagement"; // File size allowed to upload public const string MaxUploadFileSize = GroupName + ".MaxUploadFileSize"; // User storage space public const string UserStorageSize = GroupName + ".UserStorageSize"; }
In filemanagementsettingdefinitionprovider Add setting definitions to the CS file
using MyCompany.FileManagement.Localization; using Volo.Abp.Localization; using Volo.Abp.Settings; namespace MyCompany.FileManagement.Settings { public class FileManagementSettingDefinitionProvider : SettingDefinitionProvider { public override void Define(ISettingDefinitionContext context) { context.Add( new SettingDefinition( FileManagementSettings.MaxUploadFileSize, "1048576", // Default value L("MaxUploadFileSize:Display"), // Display value L("MaxUploadFileSize:Desc"), // describe true)); // Is it visible to the client context.Add( new SettingDefinition( FileManagementSettings.UserStorageSize, "1073741824", L("UserStorageSize:Display"), L("UserStorageSize:Desc"), true)); } // Language localization private static LocalizableString L(string name) { return LocalizableString.Create<FileManagementResource>(name); } } }
After doing so, the settings have taken effect. Start httpapi Host, enter in the browser https://localhost:44358/api/abp/application-configuration , check the application configuration. Find the Settings configuration section below to find the Settings just defined:
2. ConfigurationSetting
Open the Appsettings of the startup project JSON file, add the file management configuration as follows:
"Settings": { "FileManagement.MaxUploadFileSize": 1000000, "FileManagement.UserStorageSize": 200000000 }
Restart httpapi Host project, review the application configuration again and find that the value of the setting has changed
For the settings of other settings providers, you need to design the application service layer
3. Application service layer design
For the setting management function module, its infrastructure has been implemented in the Abp framework, and dependencies have been added in the startup project; Therefore, there is no need to care about how to design database entities and store data. You can directly inject the ISettingManager interface provided by it to realize the functions of the application service layer
First, in application Add data transfer object DTO and service interface in contracts project:
FileManagementSettingsDto.cs
namespace MyCompany.FileManagement.Settings { public class FileManagementSettingsDto { public long MaxUploadFileSize { get; set; } public long UserStorageSize { get; set; } } }
IFileManagementSettingsService.cs
using System.Threading.Tasks; using Volo.Abp.Application.Services; namespace MyCompany.FileManagement.Settings { public interface IFileManagementSettingsService : IApplicationService { Task<FileManagementSettingsDto> GetAsync(); Task UpdateAsync(FileManagementSettingsDto input); } }
Then implement the setting management application service
Add Volo. In the Application project Abp. SettingManagement. Reference to Application package
Add filemanagementsettingsservice cs
using Microsoft.AspNetCore.Authorization; using MyCompany.FileManagement.Permissions; using MyCompany.FileManagement.Settings; using System; using System.Threading.Tasks; using Volo.Abp.SettingManagement; namespace MyCompany.FileManagement.Services { [Authorize(FileManagementPermissions.Settings.Default)] public class FileManagementSettingsService : FileManagementAppService, IFileManagementSettingsService { private readonly ISettingManager _settingManager; public FileManagementSettingsService(ISettingManager settingManager) { _settingManager = settingManager; } public virtual async Task<FileManagementSettingsDto> GetAsync() { return new FileManagementSettingsDto { // User settings MaxUploadFileSize = Convert.ToInt64(await _settingManager.GetOrNullForCurrentUserAsync(FileManagementSettings.MaxUploadFileSize)), // Global settings UserStorageSize = Convert.ToInt64(await _settingManager.GetOrNullGlobalAsync(FileManagementSettings.UserStorageSize)), }; } public virtual async Task UpdateAsync(FileManagementSettingsDto input) { await _settingManager.SetForCurrentUserAsync(FileManagementSettings.MaxUploadFileSize, input.MaxUploadFileSize.ToString()); await _settingManager.SetGlobalAsync(FileManagementSettings.UserStorageSize, input.UserStorageSize.ToString()); } } }
Finally, add the permission definition. Note that here we put the setting menu item of the file management module under the permission menu of the setting management of the framework. Therefore, it needs to be in application Add Volo. In the contracts project Abp. SettingManagement. Application. References to contracts package
In filemanagementpermissions Add constant to CS
... using Volo.Abp.SettingManagement; namespace MyCompany.FileManagement.Permissions { public class FileManagementPermissions { ... ... public static class Settings { public const string Default = SettingManagementPermissions.GroupName + ".FileManagement"; } } }
Add a permission definition in FileManagementPermissionDefinitionProvider
... using Volo.Abp.SettingManagement; namespace MyCompany.FileManagement.Permissions { public class FileManagementPermissionDefinitionProvider : PermissionDefinitionProvider { public override void Define(IPermissionDefinitionContext context) { ... // Gets the settings management permission group for the framework var settingGroup = context.GetGroup(SettingManagementPermissions.GroupName); // Add file management permissions to the set management permissions group settingGroup.AddPermission(FileManagementPermissions.Settings.Default, L("Menu:FileManagement")); } ... } }
Start the front and rear projects, log in and enter the role management page to view the admin role permissions, as shown in the figure:
You can see that file management permission is available in settings management. Check it and save it
4. Add WebApi controller
The Abp framework supports the automatic generation of webapi controllers from the Application service. Here, like file management, we create our own api controllers and add filemanagementsettingscontroller in HttpApi cs
using Microsoft.AspNetCore.Mvc; using MyCompany.FileManagement.Settings; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.AspNetCore.Mvc; namespace MyCompany.FileManagement { [RemoteService(Name = FileManagementRemoteServiceConsts.RemoteServiceName)] [Area(FileManagementRemoteServiceConsts.ModuleName)] [Route("api/file-management/settings")] public class FileManagementSettingsController : AbpController, IFileManagementSettingsService { protected IFileManagementSettingsService _fileManagementSettingsService { get; } public FileManagementSettingsController(IFileManagementSettingsService fileManagementSettingsService) { _fileManagementSettingsService = fileManagementSettingsService; } [HttpGet] public Task<FileManagementSettingsDto> GetAsync() { return _fileManagementSettingsService.GetAsync(); } [HttpPut] public Task UpdateAsync(FileManagementSettingsDto input) { return _fileManagementSettingsService.UpdateAsync(input); } } }
5. Configure angular settings menu and components
The angular setting component collects the setting methods of each module through the SettingTabsService service, and then displays them through the setting menu and Tab page.
First, add the file management setting interface component in the config sub module of file management, because the config sub module is added manually. Before adding components using angular cli, you need to add components in angular Configure config sub module in JSON:
"file-management": { ... ... }, "file-management-config": { "projectType": "library", "root": "projects/file-management/config", "sourceRoot": "projects/file-management/config/src", "prefix": "" }
The project name of the sub module is defined as file management config, so you can add components in the terminal execution statement:
ng generate component file-management-settings-group --skip-tests --project file-management-config
Then add setting - tab. In the providers directory provider. TS, as follows:
import { SettingTabsService } from '@abp/ng.setting-management/config'; import { APP_INITIALIZER } from '@angular/core'; import { FileManagementSettingsGroupComponent } from '../lib/file-management-settings-group/file-management-settings-group.component'; export const FILE_MANAGE_SETTING_TAB_PROVIDERS = [ { provide: APP_INITIALIZER, useFactory: configureSettingTabs, deps: [SettingTabsService], multi: true, }, ]; export function configureSettingTabs(settingTabs: SettingTabsService) { return () => { settingTabs.add([ { name: 'FileManagement::Menu:FileManagement', order: 50, requiredPolicy: 'SettingManagement.FileManagement', component: FileManagementSettingsGroupComponent, }, ]); }; }
Including APP_INITIALIZER is an injectable token of InjectionToken type. The value it can receive is a method group. In these methods, the program can be configured, and file in the code_ MANAGE_ SETTING_ TAB_ Providers will set settingtabs add(...) The method is encapsulated as the configureSettingTabs method and provided to APP_INITIALIZER, other modules may also have this setting tab Providers, they will provide the root module with the forRoot() method of the module for initialization, and inject app anywhere in the program_ The initializer can get the configuration methods provided in all places
Modify file management config module. TS file, add file in forRoot()_ MANAGE_ SETTING_ TAB_ PROVIDERS
Execute yarn build:files to compile the file module, and then start npm start
You can see that the settings page has taken effect
6. Generate an angular service agent
You can directly run ABP generate proxy - t ng - M filemanagement - a filemanagement -- target file management config to generate the client proxy code to the config sub module, but in this way, the file management main module and config sub module have the same client proxy code, and config cannot reference the methods in the main module;
There are two ways to solve this problem. The first is to create a proxy sub module in the file module, so that both the main module and the config sub module can reference the proxy sub module; The second method is to modify the Area attribute modification of the back-end webapi controller and generate the proxy instruction -m, which is also replaced by the value of the Area attribute modification
Here, we use the second method to modify the Area property of FileManagementSettingsController. The modified value is fileManagementConfig
[Area("fileManagementConfig")] ... public class FileManagementSettingsController : AbpController, IFileManagementSettingsService
Restart the backend Host project
Generate the client agent again (note that the method of generating the agent by ABP cli after the latest version upgrade is somewhat different):
abp generate-proxy -t ng -m fileManagementConfig -a FileManagement --target file-management-config
7. Write file setup component code
Modify file management settings group component. HTML, as follows:
<h2>{{ 'FileManagement::Menu:FileManagement' | abpLocalization }}</h2> <hr class="my-3" /> <form *ngIf="form" [formGroup]="form" (ngSubmit)="submit()" validateOnSubmit> <div class="mb-3"> <label class="form-label" for="max-upload-size">{{ 'FileManagement::MaxUploadFileSize:Display' | abpLocalization }}</label> <input type="number" id="max-upload-size" class="form-control" formControlName="maxUploadFileSize" /> </div> <div class="mb-3"> <label class="form-label" for="user-storage-size">{{ 'FileManagement::UserStorageSize:Display' | abpLocalization }}</label> <input type="number" id="user-storage-size" class="form-control" formControlName="userStorageSize" /> </div> <hr /> <button type="submit" [disabled]="saving" class="btn btn-primary"> <i class="ms-1" [ngClass]="{'fa fa-save': !saving, 'fa fa-spinner fa-spin': saving}"></i> {{ 'FileManagement::Files:Save' | abpLocalization }} </button> </form>
Modify file management settings group component. TS, as follows:
import { ToasterService } from '@abp/ng.theme.shared'; import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { finalize } from 'rxjs/operators'; import { FileManagementSettingsService } from '../proxy'; import { FileManagementSettingsDto } from '../proxy/settings'; @Component({ selector: 'lib-file-management-settings-group', templateUrl: './file-management-settings-group.component.html', styleUrls: ['./file-management-settings-group.component.css'] }) export class FileManagementSettingsGroupComponent implements OnInit { form: FormGroup; selected: FileManagementSettingsDto; saving = false; constructor( private filesSettingsService: FileManagementSettingsService, private toasterService: ToasterService, protected fb: FormBuilder, ) { } ngOnInit(): void { this.getData(); } private getData() { this.filesSettingsService.get().subscribe(res => { this.buildForm(res); }); } private buildForm(filesSettings: FileManagementSettingsDto) { this.selected = filesSettings; this.form = this.fb.group({ maxUploadFileSize: [filesSettings.maxUploadFileSize, [Validators.required]], userStorageSize: [filesSettings.userStorageSize, [Validators.required]], }); } submit() { if (this.saving || this.form.invalid) { return; } this.saving = true; this.filesSettingsService .update(this.form.value) .pipe(finalize(() => (this.saving = false))) .subscribe(() => { this.toasterService.success('AbpSettingManagement::SuccessfullySaved'); this.getData(); }); } }
8. Add localized language resources
In the background domain Add multilingual resources to shared
"MaxUploadFileSize:Display": "Upload file size limit", "MaxUploadFileSize:Desc": "Maximum file size allowed to upload (unit) KB). ", "UserStorageSize:Display": "User storage space", "UserStorageSize:Desc": "The amount of file storage space owned by each user."
Restart the background Host project,
Execute yarn build:files in angular to compile the file module, and then start npm start. The interface is as follows:
Modify the setting value and click save
9. Get the setting value in the angular front end
Previously, we can modify the file upload size limit and user storage space by setting. How can I obtain the setting value? For example, judge the size limit of uploaded files before submitting files to the background
Open the UploadFilesComponent component in the file management module and inject the ConfigStateService service service. The modifications are as follows:
constructor( ... private toastService: ToasterService, private config: ConfigStateService, ...) { // Get upload size limit settings const maxFileSize = this.config.getOne('setting').values['FileManagement.MaxUploadFileSize']; this.options = { concurrency: 1, maxUploads: 3, maxFileSize: maxFileSize // Upload file size limit }; ... }
Re execute yarn build:files to compile the file module, and then start npm start. It is found that the upload is intercepted when it exceeds 1M
10. Get the setting value at the back end
Open the FileManagementManager file of the file module Domain project and inject the ISettingProvider service to obtain the setting value. The modifications are as follows:
using MyCompany.FileManagement.Settings; ... namespace MyCompany.FileManagement { public class FileManagementManager: DomainService { ... // Injection setup program interface private readonly ISettingProvider _settingProvider; public FileManagementManager(... ISettingProvider settingProvider) { ... _settingProvider = settingProvider; } ... public async Task<string> CreateAsync(...) { // Gets the setting value of the user's storage space limit var userStorageLimit = await _settingProvider.GetAsync<int>(FileManagementSettings.UserStorageSize); // Gets the current used user space size var userUsedSize = await _fileRepository.GetStorageSizeAsync(userId); var userTotalSize = bytes.Length + userUsedSize; if (userTotalSize > userStorageLimit) { throw new UserFriendlyException("Insufficient space left!"); }
11. Verify user's configuration
Before saving the settings in the Application service, the user storage space is stored as the global setting, while the upload file size limit is stored as the user setting. Open the file management setting page, modify the setting value, then add a new user, set the permissions, switch to the new user login and view the file management setting page, It is found that the upload file size limit set by the user changes to the configured value of 1000000, while the global setting user storage space is the same as the value in the admin user
Source code of this article: Abp5.0.0 file management module