Activities of "maliming"

Hi,

About the CLI: abp suite generate uses the same cleanup as the UI when "RemoveUnusedUsings": true is set in the entity JSON you pass with -e. Apply the template change from my earlier reply, make sure the solution builds, then generate the entity again with the CLI. If unused usings are still there, check the Suite log in %USERPROFILE%\.abp\suite\logs for the cleanup warning.

About the pop-up after saving: we'll pass your suggestion for a toast to the Suite team.

Thanks

Hi,

abp add-module adds AIManagementOpenAIModule to the DependsOn of your Domain module, but it adds the wrong using for it. The class is in the Volo.AIManagement.OpenAI namespace.

Adding this using to the Domain module fixes it:

using Volo.AIManagement.OpenAI;

We'll fix this.

Thanks

Hi,

By default, the WebAssembly client only gets the dynamic texts (for example, texts changed in Language Management) from the server. Static texts are read from the JSON files embedded in the module DLLs, and the JSON contributor reads every culture file of a resource the first time it needs these texts. There is no built-in option to limit this to the configured languages.

Here's a workaround you can use for now. Replace that contributor in your Blazor.Client project, so it skips the culture files you don't need:

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using Microsoft.Extensions.FileProviders;
using Volo.Abp.Localization;
using Volo.Abp.Localization.VirtualFiles;
using Volo.Abp.Localization.VirtualFiles.Json;

namespace MyProject.Blazor.Client.Localization;

public class CultureFilteredJsonLocalizationResourceContributor : JsonVirtualFileLocalizationResourceContributor
{
    private static readonly FieldInfo VirtualPathField = typeof(VirtualFileLocalizationResourceContributorBase)
        .GetField("_virtualPath", BindingFlags.Instance | BindingFlags.NonPublic)!;

    private static readonly Regex CultureFileNameRegex = new("^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$");

    private readonly HashSet<string> _cultures;

    public CultureFilteredJsonLocalizationResourceContributor(string virtualPath, HashSet<string> cultures)
        : base(virtualPath)
    {
        _cultures = cultures;
    }

    protected override bool CanParseFile(IFileInfo file)
    {
        if (!base.CanParseFile(file))
        {
            return false;
        }

        var fileName = Path.GetFileNameWithoutExtension(file.Name);
        return !CultureFileNameRegex.IsMatch(fileName) || _cultures.Contains(fileName);
    }

    public static void ReplaceAll(AbpLocalizationOptions options, params string[] cultureNames)
    {
        foreach (var resource in options.Resources.Values)
        {
            var cultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            foreach (var cultureName in cultureNames)
            {
                cultures.Add(cultureName);
                cultures.Add(CultureHelper.GetBaseCultureName(cultureName));
            }

            if (!resource.DefaultCultureName.IsNullOrEmpty())
            {
                cultures.Add(resource.DefaultCultureName!);
            }

            for (var i = 0; i < resource.Contributors.Count; i++)
            {
                if (resource.Contributors[i].GetType() != typeof(JsonVirtualFileLocalizationResourceContributor))
                {
                    continue;
                }

                var virtualPath = (string)VirtualPathField.GetValue(resource.Contributors[i])!;
                resource.Contributors[i] = new CultureFilteredJsonLocalizationResourceContributor(virtualPath, cultures);
            }
        }
    }
}

Then use it in your client module:

using MyProject.Blazor.Client.Localization;
using Volo.Abp.Localization;

// In ConfigureServices
PostConfigure<AbpLocalizationOptions>(options =>
{
    CultureFilteredJsonLocalizationResourceContributor.ReplaceAll(options, "en", "pt-PT");
});

It also keeps the parent culture (pt) and the default culture of each resource. If you add a new language later, add it to this list too.

It decides by file name, not by the culture inside the file. A file named like a culture (tr.json, de-DE.json, or any 2-3 letter name like app.json) is skipped when that name isn't in the list. Other names, like en_Books.json, are always read. The ABP module files all follow this, but please check your own localization files.

The code reads the private _virtualPath field, so please check it again when you upgrade ABP.

For the other steps in your table, could you share an online URL where we can check the startup, with a test account? Please also let us know if the times were measured with a Release build. You can send them to liming.ma@volosoft.com.

Thanks

Hi,

The fix was merged one day after 10.7.0 was published, so it missed that release. It will be in 10.7.1, which we plan to release next week.

Until then, keep the workaround in main.ts. Remove it after upgrading to 10.7.1.

Sorry for the confusion. Your ticket has been refunded.

Thanks

Hi,

About RemoveUnusedUsings: Suite keeps the cleanup only if the solution builds after it. Apply the template change from my previous reply, make sure the solution builds, then generate the entity again. Existing .Extended.cs files are excluded from this cleanup because they contain your own code, so you can clean up their unused usings in your IDE.

About the .Extended.cs formatting: Suite 10.7.0 reformats the whole file when it updates the generated constructor. We're working on a fix so Suite only changes the generated constructor and keeps the rest of your code as it is. It isn't released yet.

About the consts: the consts files are regenerated each time. Thanks for the suggestion, we'll pass it to the Suite team.

About the nullable navigation properties: in 10.7, the navigation properties in *WithNavigationProperties and its DTO are nullable on purpose. The list query loads them with a left join, so they can be null when the related record is soft-deleted. The foreign key itself is still required.

Thanks

Hi,

Thanks for the files. Neither of them has using Volo.AIManagement;, even in a comment, so my earlier explanation doesn't apply to your case. I tried both abp add-module and abp install-module with your two files on a 10.7.0 solution, and the using was added each time.

Could you send:

  • the exact install command, with options, and the folder you ran it from
  • the output of abp --version
  • your OS
  • the full install output

If you still have the failed branch, please also send the git diff of the affected module file and its .csproj from before you added the using manually.

Thanks

Hi,

About the broken usings in EfCoreProjektDokumentRepository.cs: Suite 10.7.0 breaks the using Bpo.EntityFrameworkCore; line when it adds the usings of the navigation properties. The RemoveUnusedUsings option doesn't change it. We've fixed it, and the fix will be in the next patch release.

Until then, you can change the Suite template once:

  1. Open the Templates page in Suite, search for Server.Repository.EfCoreRepository.txt and edit it.
  2. Replace this line:
using %%solution-namespace%%.%%dbcontext-namespace%%;

with:

using Bpo.EntityFrameworkCore;
  1. Save it and generate the entity again.

The change only applies to this solution. You can restore the template to default after you upgrade.

Thanks

Hi,

The app template already generates a BpoDbContextBase<TDbContext> like yours when you choose a separate tenant database. Suite doesn't use it yet. For a multi-tenant entity, it writes the mapping into both DbContexts.

For now, you can make Suite write the mappings into one place:

  1. Add a BpoDbContextModelCreatingExtensions.cs file to the EntityFrameworkCore project. When this file exists, Suite writes the entity mappings into its first Configure... method instead of BpoDbContext:
using Microsoft.EntityFrameworkCore;

namespace Bpo.EntityFrameworkCore;

public static class BpoDbContextModelCreatingExtensions
{
    public static void ConfigureBpo(this ModelBuilder builder)
    {
    }
}
  1. Call it in BpoDbContextBase.OnModelCreating, after the module configurations:
builder.ConfigureBpo();
  1. Move your existing entity mappings into ConfigureBpo.

Suite puts the host-only entities inside if (builder.IsHostDatabase()) in this method. For a multi-tenant entity, it still adds a second copy of the mapping to BpoTenantDbContext. Delete that copy after you generate the entity. The tenant model is the same without it.

We'll consider using the base class directly in Suite.

Thanks

Hi,

Thanks for the suggestion. We'll make the generated test classes partial in the next release: the abstract *AppServiceTests<TStartupModule>, the EF Core/MongoDB *AppServiceTests classes, and *RepositoryTests.

Until then, you can keep the partial change in your customized template.

Thanks

Hi,

Thanks for letting us know. Feel free to open a new question if anything else comes up.

Thanks

Showing 1 to 10 of 12910 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on October 30, 2026, 06:34
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.