diff --git a/docs/en/Migration-Guides/Abp-8_1.md b/docs/en/Migration-Guides/Abp-8_1.md index 6f4c316d3f..f13ac8d209 100644 --- a/docs/en/Migration-Guides/Abp-8_1.md +++ b/docs/en/Migration-Guides/Abp-8_1.md @@ -83,3 +83,64 @@ public partial class Add_NormalizedName : Migration See https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/managing?tabs=dotnet-core-cli#adding-raw-sql to learn how to add raw SQL to migrations. +## Use `Asp.Versioning.Mvc` to replace `Microsoft.AspNetCore.Mvc.Versioning` + +The Microsoft.AspNetCore.Mvc.Versioning packages are now deprecated and superseded by Asp.Versioning.Mvc. +See the announcement here: https://github.com/dotnet/aspnet-api-versioning/discussions/807 + +The namespace of the `[ControllerName]` attribute has changed to `using Asp.Versioning`, Please update your code to use the new namespace. + +Related PR: https://github.com/abpframework/abp/pull/18380 + +## New asynchronous methods for `IAppUrlProvider` + +The `IsRedirectAllowedUrl` method of `IAppUrlProvider` has been changed to `IsRedirectAllowedUrlAsync` and it is now an async method. +You should update your usage of `IAppUrlProvider` to use the new method. + +Related PR: https://github.com/abpframework/abp/pull/18492 + +## New attribute: `ExposeKeyedServiceAttribute` + +The new `ExposeKeyedServiceAttribute` is used to control which keyed services are provided by the related class. Example: + +````C# +[ExposeKeyedService("taxCalculator")] +[ExposeKeyedService("calculator")] +public class TaxCalculator: ICalculator, ITaxCalculator, ICanCalculate, ITransientDependency +{ +} +```` + +In the example above, the `TaxCalculator` class exposes the `ITaxCalculator` interface with the key `taxCalculator` and the `ICalculator` interface with the key `calculator`. That means you can get keyed services from the `IServiceProvider` as shown below: + +````C# +var taxCalculator = ServiceProvider.GetRequiredKeyedService("taxCalculator"); +var calculator = ServiceProvider.GetRequiredKeyedService("calculator"); +```` + +Also, you can use the [`FromKeyedServicesAttribute`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.fromkeyedservicesattribute?view=dotnet-plat-ext-8.0) to resolve a certain keyed service in the constructor: + +```csharp +public class MyClass +{ + //... + public MyClass([FromKeyedServices("taxCalculator")] ITaxCalculator taxCalculator) + { + TaxCalculator = taxCalculator; + } +} +``` + +> Notice that the `ExposeKeyedServiceAttribute` only exposes the keyed services. So, you can not inject the `ITaxCalculator` or `ICalculator` interfaces in your application without using the `FromKeyedServicesAttribute` as shown in the example above. If you want to expose both keyed and non-keyed services, you can use the `ExposeServicesAttribute` and `ExposeKeyedServiceAttribute` attributes together as shown below: +````C# +[ExposeKeyedService("taxCalculator")] +[ExposeKeyedService("calculator")] +[ExposeServices(typeof(ITaxCalculator), typeof(ICalculator))] +public class TaxCalculator: ICalculator, ITaxCalculator, ICanCalculate, ITransientDependency +{ +} +```` + +This is a small **Breaking Change** because `IOnServiceExposingContext` has changed. You should update your usage of `IOnServiceExposingContext` if you have related code. + +Related PR: https://github.com/abpframework/abp/pull/18819