From ac8c1330ace801160c985c5e7acc02c0cc47eda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 13 Apr 2022 19:21:17 +0300 Subject: [PATCH 1/2] Added more info for add-module command --- docs/en/Customizing-Application-Modules-Guide.md | 2 +- docs/en/Customizing-Application-Modules-Overriding-Services.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/en/Customizing-Application-Modules-Guide.md b/docs/en/Customizing-Application-Modules-Guide.md index b62d4e5bb7..4fe3c71dbe 100644 --- a/docs/en/Customizing-Application-Modules-Guide.md +++ b/docs/en/Customizing-Application-Modules-Guide.md @@ -31,7 +31,7 @@ If you don't think to make huge changes on the pre-built modules, re-using them If you want to make **huge changes** or add **major features** on a pre-built module, but the available extension points are not enough, you can consider to directly work the source code of the depended module. -In this case, you typically **add the source code** of the module to your solution and replace **every** package reference in the solution with its corresponding local project references. **[ABP CLI](CLI.md)** automates this process for you. +In this case, you typically **add the source code** of the module to your solution and replace **every** package reference in the solution with its corresponding local project references. **[ABP CLI](CLI.md)**'s `add-module` command automates this process for you with the `--with-source-code` parameter. This command can also replace a module by its source code if the module already installed as NuGet packages. #### Separating the Module Solution diff --git a/docs/en/Customizing-Application-Modules-Overriding-Services.md b/docs/en/Customizing-Application-Modules-Overriding-Services.md index 081b142ad7..fd42d4cfde 100644 --- a/docs/en/Customizing-Application-Modules-Overriding-Services.md +++ b/docs/en/Customizing-Application-Modules-Overriding-Services.md @@ -205,7 +205,8 @@ If you don't want to remove either controller, you can configure `AbpAspNetCoreM ```csharp Configure(options => { - options.IgnoredControllersOnModelExclusion.AddIfNotContains(typeof(MyAccountController)); + options.IgnoredControllersOnModelExclusion + .AddIfNotContains(typeof(MyAccountController)); }); ``` From 2b2905654908cdcbdfe3c77839242f2e2b56a53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 13 Apr 2022 19:48:00 +0300 Subject: [PATCH 2/2] Documented: Overriding a Repository --- ...Application-Modules-Overriding-Services.md | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/en/Customizing-Application-Modules-Overriding-Services.md b/docs/en/Customizing-Application-Modules-Overriding-Services.md index fd42d4cfde..a1a6c8b778 100644 --- a/docs/en/Customizing-Application-Modules-Overriding-Services.md +++ b/docs/en/Customizing-Application-Modules-Overriding-Services.md @@ -161,6 +161,73 @@ This example class inherits from the `IdentityUserManager` [domain service](Doma Check the [localization system](Localization.md) to learn how to localize the error messages. +### Example: Overriding a Repository + +````csharp +public class MyEfCoreIdentityUserRepository : EfCoreIdentityUserRepository +{ + public MyEfCoreIdentityUserRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + /* You can override any base method here */ +} +```` + +In this example, we are overriding the `EfCoreIdentityUserRepository` class that is defined by the [Identity module](Modules/Identity.md). This is the [Entity Framework Core](Entity-Framework-Core.md) implementation of the user repository. + +Thanks to the naming convention (`MyEfCoreIdentityUserRepository` ends with `EfCoreIdentityUserRepository`), no additional setup is required. You can override any base method to customize it for your needs. + +However, if you inject `IRepository` or `IRepository`, it will still use the default repository implementation. To replace the default repository implementation, write the following code in the `ConfigureServices` method of your module class: + +````csharp +context.Services.AddDefaultRepository( + typeof(Volo.Abp.Identity.IdentityUser), + typeof(MyEfCoreIdentityUserRepository), + replaceExisting: true +); +```` + +In this way, your implementation will be used if you inject `IRepository`, `IRepository` or `IIdentityUserRepository`. + +If you want to add extra methods to your repository and use it in your own code, you can define an interface and expose it from your repository implementation. You can also extend the pre-built repository interface. Example: + +````csharp +public interface IMyIdentityUserRepository : IIdentityUserRepository +{ + public Task DeleteByEmailAddress(string email); +} +```` + +The `IMyIdentityUserRepository` interface extends the Identity module's `IIdentityUserRepository` interface. Then you can implement it as shown in the following example: + +````csharp +[ExposeServices(typeof(IMyIdentityUserRepository), IncludeDefaults = true)] +public class MyEfCoreIdentityUserRepository + : EfCoreIdentityUserRepository, IMyIdentityUserRepository +{ + public MyEfCoreIdentityUserRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public async Task DeleteByEmailAddress(string email) + { + var dbContext = await GetDbContextAsync(); + var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Email == email); + if (user != null) + { + dbContext.Users.Remove(user); + } + } +} +```` + +The `MyEfCoreIdentityUserRepository` class implements the `IMyIdentityUserRepository` interface. `ExposeServices` attribute is needed since ABP can not expose `IMyIdentityUserRepository` by naming conventions (`MyEfCoreIdentityUserRepository` doesn't end with `MyIdentityUserRepository`). Now, you can inject the `IMyIdentityUserRepository` interface into your services and call its `DeleteByEmailAddress` method. + ### Example: Overriding a Controller ````csharp