@ -47,7 +47,7 @@ ABP supports all the following approaches to store the tenant data in the databa
- **Database per Tenant**: Every tenant has a separate, dedicated database to store the data related to that tenant.
- **Hybrid**: Some tenants share a single database while some tenants may have their own databases.
[Saas module (PRO)](../../../modules/saas.md) allows you to set a connection string for any tenant (as optional), so you can achieve any of the approaches.
[SaaS module (PRO)](../../../modules/saas.md) allows you to set a connection string for any tenant (as optional), so you can achieve any of the approaches.
> You can see the community article *[Multi-Tenancy with Separate Databases in .NET and ABP Framework](https://abp.io/community/articles/multitenancy-with-separate-databases-in-dotnet-and-abp-51nvl4u9)* for more details about different database architectures with practical implementation details.
@ -466,7 +466,7 @@ The [Tenant Management module](../../../modules/tenant-management.md) provides a
### A note about separate database per tenant approach in open source version
While ABP fully supports this option, managing connection strings of tenants from the UI is not available in open source version. You need to have [Saas module (PRO)](../../../modules/saas.md).
While ABP fully supports this option, managing connection strings of tenants from the UI is not available in open source version. You need to have [SaaS module (PRO)](../../../modules/saas.md).
Alternatively, you can implement this feature yourself by customizing the tenant management module and tenant application service to create and migrate the database on the fly.
@ -264,7 +264,7 @@ public class TaxAppService : ApplicationService
``TaxAppService`` gets ``ITaxCalculator`` in its constructor. The dependency injection system automatically provides the requested service at runtime.
Constructor injection is preffered way of injecting dependencies to a class. In that way, the class can not be constructed unless all constructor-injected dependencies are provided. Thus, the class explicitly declares it's required services.
Constructor injection is preferred way of injecting dependencies to a class. In that way, the class can not be constructed unless all constructor-injected dependencies are provided. Thus, the class explicitly declares it's required services.
@ -88,7 +88,7 @@ Error **details** in an optional field of the JSON error message. Thrown `Except
}
````
`AbpValidationException` implements the `IHasValidationErrors` interface and it is automatically thrown by the framework when a request input is not valid. So, usually you don't need to deal with validation errors unless you have higly customised validation logic.
`AbpValidationException` implements the `IHasValidationErrors` interface and it is automatically thrown by the framework when a request input is not valid. So, usually you don't need to deal with validation errors unless you have highly customized validation logic.
### Logging
@ -289,7 +289,7 @@ The `IHttpExceptionStatusCodeFinder` is used to automatically determine the HTTP
### Custom Mappings
Automatic HTTP status code determination can be overrided by custom mappings. For example:
Automatic HTTP status code determination can be overridden by custom mappings. For example:
@ -43,7 +43,7 @@ public class YourModule : AbpModule
}
````
> Quartz background worker integration provided `QuartzPeriodicBackgroundWorkerAdapter` to adapt `PeriodicBackgroundWorkerBase` and `AsyncPeriodicBackgroundWorkerBase` derived class. So, you can still fllow the [background workers document](../background-workers) to define the background worker.
> Quartz background worker integration provided `QuartzPeriodicBackgroundWorkerAdapter` to adapt `PeriodicBackgroundWorkerBase` and `AsyncPeriodicBackgroundWorkerBase` derived class. So, you can still follow the [background workers document](../background-workers) to define the background worker.
@ -235,7 +235,7 @@ The final rendered message was shown above.
You typically want to replace the standard templates with your own ones, so you can prepare a branded email messages. To do that, you can use the power of the [virtual file system](../infrastructure/virtual-file-system.md) (VFS) or replace them in your own template definition provider.
Pathes of the templates in the virtual file system are shown below:
Paths of the templates in the virtual file system are shown below:
* `/Volo/Abp/Emailing/Templates/Layout.tpl`
* `/Volo/Abp/Emailing/Templates/Message.tpl`
@ -250,7 +250,7 @@ See the [text templating system](./text-templating) document for details.
## NullEmailSender
`NullEmailSender` is a built-in class that implements the `IEmailSender`, but writes email contents to the [standard log system](../fundamentals/logging.md), rathen than actually sending the emails.
`NullEmailSender` is a built-in class that implements the `IEmailSender`, but writes email contents to the [standard log system](../fundamentals/logging.md), rather than actually sending the emails.
This class can be useful especially in development time where you generally don't want to send real emails. The [application startup template](../../solution-templates/layered-web-application) already uses this class in the **DEBUG mode** with the following configuration in the domain layer:
@ -43,7 +43,7 @@ ABP automatically discovers this class and registers the setting definitions.
* **DefaultValue**: A setting may have a default value.
* **DisplayName**: A localizable string that can be used to show the setting name on the UI.
* **Description**: A localizable string that can be used to show the setting description on the UI.
* **IsVisibleToClients**: A boolean value indicates that whether this setting value is available in the client side or not. Default value is false to prevent accidently publishing an internal critical setting value.
* **IsVisibleToClients**: A boolean value indicates that whether this setting value is available in the client side or not. Default value is false to prevent accidentally publishing an internal critical setting value.
* **IsInherited**: A boolean value indicates that whether this setting value is inherited from other providers or not. Default value is true and fallbacks to the next provider if the setting value was not set for the requested provider (see the setting value providers section for more).
* **IsEncrypted**: A boolean value indicates that whether this setting value should be encrypted on save and decrypted on read. It makes possible to secure the setting value in the database.
* **Providers**: Can be used to restrict providers available for a particular setting (see the setting value providers section for more).
User impersonation allows you to temporarily sign in as a different user in your tenant's users. This article introduces how to enable impersonation in ABP. Impersonation is enabled by defautl in ABP v5.0 and above.
User impersonation allows you to temporarily sign in as a different user in your tenant's users. This article introduces how to enable impersonation in ABP. Impersonation is enabled by default in ABP v5.0 and above.
## Using Dynamic Workspace Configurations for custom requirements
The AI Management module allows you to access only configuration of a workspace without resolving pre-constructed chat client. This is useful when you want to use a workspace for your own purposes and you don't need to use the chat client.
The `IWorkspaceConfigurationStore` service is used to access the configuration of a workspace. It has multiple implementaations according to the usage scenario.
The `IWorkspaceConfigurationStore` service is used to access the configuration of a workspace. It has multiple implementations according to the usage scenario.