Yes, AutoMapper and Mapperly can coexist in the same ABP 10+ solution. ABP 10 switched ABP modules/templates to use Mapperly by default, but ABP still provides both AutoMapper and Mapperly integration packages, so you can keep existing AutoMapper profiles while using Mapperly elsewhere (or for ABP-provided modules).
What “coexistence” practically means in ABP
IObjectMapper / ObjectMapper.Map(...).Recommended best practices / common pitfalls when using both
context.Services.AddAutoMapperObjectMapper<MyBlazorModule>();
// or
context.Services.AddMapperlyObjectMapper<MyBlazorModule>();
- Then set the context where you map (e.g., in an `ApplicationService` / Blazor page base):
ObjectMapperContext = typeof(MyBlazorModule);
- Otherwise, ABP may fall back to the *default* provider and you can get “no mapping found” errors (especially visible in UI layers like Blazor).
Avoid ambiguous/duplicate mappings for the same source/destination pair
Decide which one is the default provider for ObjectMapper.Map
ObjectMapper.Map<TSource, TDestination> to use Mapperly, ensure your startup/host module registers Mapperly as the default object mapper:context.Services.AddMapperlyObjectMapper();
- If you keep AutoMapper as default, you’ll do the analogous AutoMapper default registration instead.
Framework design intent in ABP 10
Is coexistence “officially supported long-term” or only transitional?
Migration guidance / strategy for large AutoMapper profile bases (phased approach)
MapperBase<>, TwoWayMapperBase<>), then remove the corresponding AutoMapper maps.ObjectMapper (ABP abstraction) where possible, and only inject concrete Mapperly mappers when you need very specific behavior.Sources (validated)
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
DbContext/transactions alive; the Unit Of Work (UOW) is. ABP’s UOW defines the database connection/transaction boundary and disposes it when the UOW ends.IQueryable/DbContext-backed object and use it later).What to do (recommended ABP approach)
Do not inject repositories/DbContext and run EF code directly inside Blazor components.
Keep components “UI only” and call Application Services (or domain services) instead.
Ensure each operation is wrapped in its own UOW (short-lived).
[UnitOfWork] or IUnitOfWorkManager.Begin(...) to scope it to that single method call.Example (explicit UOW):
public class MyBlazorActionService : ITransientDependency
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IMyEntityRepository _repo;
public MyBlazorActionService(IUnitOfWorkManager unitOfWorkManager, IMyEntityRepository repo)
{
_unitOfWorkManager = unitOfWorkManager;
_repo = repo;
}
public async Task DoSomethingAsync()
{
await using var uow = _unitOfWorkManager.Begin(isTransactional: true);
// db work here
await uow.CompleteAsync();
}
}
Never keep a transaction open waiting for user interaction.
In Blazor it’s tempting to “start transaction on button A, commit on button B”. Don’t do that. Between those clicks you may block rows/tables (especially in PostgreSQL depending on what you touched). Instead:
Avoid holding EF Core queryables across events.
Don’t cache IQueryable, repositories, or anything that implicitly depends on an ambient UOW and then enumerate it later. Materialize results inside the same method/UOW (e.g., ToListAsync) and return DTOs to the component.
About your workaround
Creating a new scope per handler can work, but it’s not the intended pattern in ABP. The intended pattern is: Blazor component → call app service → app service method runs in its own UOW → done. That gives you the “per action” scope you want without manual service resolution.
https://abp.io/docs/latest/framework/architecture/domain-driven-design/unit-of-work
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
This CS8795 in Visual Studio is caused by Mapperly source-generator output not being picked up by VS/IntelliSense, so VS thinks your public override partial ... methods have no implementation part (even though dotnet build/run can still succeed sometimes). In ABP v10, your mapper class shape is correct; the problem is the generator not running/being loaded by the IDE consistently.
Fix it by ensuring Mapperly’s source generator is referenced as an analyzer in the project which contains the [Mapper] classes (typically your *.Application project), and by enabling compiler-generated files so VS can “see” them.
AcessorioToAcessorioDtoMapper etc.:<ItemGroup>
<PackageReference Include="Volo.Abp.Mapperly" Version="10.0.2" />
<PackageReference Include="Riok.Mapperly" Version="*" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="$(NuGetPackageRoot)riok.mapperly\*\analyzers\dotnet\cs\Riok.Mapperly.Generators.dll" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\Generated</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
.vs, bin, obj, reopen, then Rebuild.After rebuild, you should see generated files under:
obj\Debug\net10.0\Generated\...
and CS8795 should disappear.
In your ABP module (Application/Blazor/Host as appropriate), ensure you are using Mapperly registration (not AutoMapper):
using Volo.Abp.Mapperly;
[DependsOn(typeof(AbpMapperlyModule))]
public class GestaoComercialApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddMapperlyObjectMapper<GestaoComercialApplicationModule>();
// If you want Mapperly as the default provider globally:
// context.Services.AddMapperlyObjectMapper();
}
}
If you still have Volo.Abp.AutoMapper referenced anywhere, remove it from the projects you migrated, otherwise ABP may still try to resolve mappings via AutoMapper in some contexts.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
What you’re seeing (UI still saying “at least 6 characters” after you set Required length = 8 in the Identity Settings page) is almost always client-side validation text being cached / hardcoded in the UI, while the server-side rule is already updated (or will be updated after cache refresh).
Fix it definitively with these steps (do all):
Hard refresh / clear browser storage
Restart the app and clear distributed cache (if enabled)
Confirm the server-side password rule is really 8
Check setting scope (Host vs Tenant)
If it’s Angular UI: update the Identity config package
yarn upgrade @volo/abp.ng.identity.configSources (verified):
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
In ABP, IdentityOptions can be configured in your module, but password rules can also be overridden at runtime by ABP’s Setting System. So if your Configure<IdentityOptions>(...) change “doesn’t work”, it’s typically because the effective password policy is coming from Identity settings (possibly tenant-specific), not from your hardcoded options.
Do this to make it work definitively:
ConfigureServices):using Microsoft.AspNetCore.Identity;
using Volo.Abp.Modularity;
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 8;
});
}
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity.Settings;
using Volo.Abp.Settings;
public class PasswordPolicyChanger : ITransientDependency
{
private readonly ISettingManager _settingManager;
public PasswordPolicyChanger(ISettingManager settingManager)
{
_settingManager = settingManager;
}
public async Task SetMinLengthForCurrentTenantAsync()
{
await _settingManager.SetForCurrentTenantAsync(
IdentitySettingNames.Password.RequiredLength,
"8"
);
}
}
If you want it globally (host side) use:
SetGlobalAsync(...) instead of SetForCurrentTenantAsync(...).
Result: once you set IdentitySettingNames.Password.RequiredLength to 8 for the relevant scope (tenant/global/user), password validation will enforce length 8 even if your module option is different—because settings take precedence.
https://abp.io/docs/latest/modules/identity
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
.Pro suffix:abp get-source Volo.Abp.LeptonXTheme
--version:abp get-source Volo.Abp.LeptonXTheme --version 10.0.2
5.1.0-rc2, use the CLI approach above (it bypasses Suite’s module version dropdown limitation) and it should let you fetch the version you need, as long as your license/subscription allows it.10.0.2 via CLI (e.g., “No module was found” or server error), that’s typically a commercial account/license entitlement or backend issue; in that case, please contact ABP support via the contact form.Links:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Dockerfile.local) and it uses nginx to serve the built dist output.Example (as shown in ABP docs):
FROM nginx:alpine-slim
WORKDIR /app
COPY dist/BookStore /usr/share/nginx/html
COPY dynamic-env.json /usr/share/nginx/html
COPY /nginx.conf /etc/nginx/conf.d/default.conf
Notes for ABP Angular:
dynamic-env.json is used for runtime environment overriding (so you can change env without rebuilding the image).nginx.conf maps /getEnvConfig to serve that JSON file.Build & image creation (manual):
yarnnpm run build:proddocker build -f Dockerfile.local -t mycompany/myapp-angular:latest .This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
dotnet tool install/update expects (it can manifest exactly as: “Settings file 'DotnetToolSettings.xml' was not found in the package.”).dotnet tool uninstall -g Volo.Abp.Cli
dotnet tool uninstall -g Volo.Abp.Studio.Cli
%USERPROFILE%\.dotnet\tools\.store\volo.abp.studio.cli%USERPROFILE%\.dotnet\tools\.store\volo.abp.cli (if exists)dotnet tool install -g Volo.Abp.Studio.Cli
abp --version
Sometimes a specific published version can have packaging/metadata issues. Pinning avoids “latest” until the fixed package is pulled:
dotnet tool install -g Volo.Abp.Studio.Cli --version <x.y.z>
Volo.Abp.Studio.Cli, and it replaced the legacy Volo.Abp.Cli in v8.2+; having both installed can create confusing outcomes, so remove the legacy one first.Links (validated):
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
(Empty response because the question is not in English.)
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
options.IntrospectAccessToken() on the cookie scheme will indeed trigger a remote /connect/introspect call during cookie validation on every request that hits the authentication middleware. In Blazor Server that can be dozens of requests during initial load (static files, _blazor endpoints, negotiate, etc.), so your observation about the performance impact is valid.options.IsDynamicClaimsEnabled = true + app.UseDynamicClaims()), then you already have a per-request “is session still valid?” style check (via ABP’s dynamic-claims pipeline + Identity session integration). Keeping token introspection on top typically becomes redundant and expensive in this setup.Recommended action (what to change in your app): remove introspection from the UI cookie scheme
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(365);
// Remove this to avoid /connect/introspect on every request:
// options.IntrospectAccessToken();
})
Why this is safe in the default ABP setup you described
If you still need introspection for a specific security requirement, don’t apply it globally to the cookie scheme in a request-heavy UI; apply it only where needed (otherwise it will run for static assets too).
Link checked:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.