Open Closed

Loading modules dynamically/conditionally #3660


User avatar
0
yilmaz.atalar created
  • ABP Framework version: v5.2.2

Hi,

Is it possible to load module(s) at runtime instead of adding them using "DependsOnAttribute"? Or can you suggest a reasonable workaround compatible with Abp framework?

For example;

public class ModuleA : AbpModule 
{
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        if (...)
        {
            context.Services.AddDependentModule(typeof(ModuleX));
        }
        else 
        {            
            context.Services.AddDependentModule(typeof(ModuleY));
        }
    }
}

Instead of

[DependsOn(typeof(ModuleX))]
[DependsOn(typeof(ModuleY))]
public class ModuleA : AbpModule
...

9 Answer(s)
  • User Avatar
    1
    berkansasmaz created
    Support Team .NET Developer

    I guess you want to conditionally load a module in runtime. If so, ABP's Plug-In modules feature will be useful for you. See: https://docs.abp.io/en/abp/latest/PlugIn-Modules

  • User Avatar
    0
    yilmaz.atalar created

    Plugin mechanism quite useful but documents say we should add plugin from startup module but I do not want to break up the dependency tree. In other words, I want to add a module conditionally but working same as DependsOnAttribute.If I can add plugin module from another module that will also work for me.

  • User Avatar
    0
    berkansasmaz created
    Support Team .NET Developer

    I understand, but it seems to me that doing something like the following is against the design of the Module system.

    public class ModuleA : AbpModule 
    {
        public override void ConfigureService(ServiceConfigurationContext context)
        {
            if (...)
            {
                context.Services.AddDependentModule(typeof(ModuleX));
            }
            else 
            {            
                context.Services.AddDependentModule(typeof(ModuleY));
            }
        }
    }
    

    Because, for example, if your A module depends on module B, then module B is initialized before your A module. Also, it basically executed the ConfigureServices(or other public methods in AbpModule) methods of all the modules by respecting the order of module dependencies.

    However, you want to load module B in the ConfigureService of module A.

    Maybe I'm wrong, what are your views on this?

  • User Avatar
    0
    yilmaz.atalar created

    Yes you are right but I've given PreConfigureServices or ConfigureServices methods just for example. I've tried to explain what I need. I only need to inject a module dynamically to the module tree. Maybe like this:

    public class ModuleA : AbpModule
    {
        public override ICollection<Type> GetDynamicDependencies() 
        {
            List<Type> dependencies = new List<Type>();
            
            if (condition)
            {
                dependencies.Add(typeof(ModuleX));
            }
            else
            {
                dependencies.Add(typeof(ModuleY));
            }
            
            return result;
        }
    }
    

    And basically "GetDynamicDependencies" method can be called by the framework if possible while populating module dependency tree.

  • User Avatar
    0
    berkansasmaz created
    Support Team .NET Developer

    I think you can use the Global feature system.

    See: https://docs.abp.io/en/abp/latest/Global-Features

    For example, the CmsKit module uses the global feature system. If the relevant feature of CmsKit is not enabled, even the database tables for the relevant feature are not created.

    See: https://github.com/abpframework/abp/blob/6514385e0897a4e3432db9d06ab61bb4fbae8734/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs#L27-L45

    I can give the CmsKitDomainModule class as another example. Here, some configurations are made depending on whether the relevant feature is enabled or not.

    See: https://github.com/abpframework/abp/blob/6514385e0897a4e3432db9d06ab61bb4fbae8734/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs#L24-L83

    With similar logic, you can depend on both modules, but their configuration depends on whether the feature is enabled or not.

    Note: You must enable/disable the feature dynamically before your related startup module class is called, otherwise the feature will always appear disabled because the dependent modules are called first.

  • User Avatar
    0
    yilmaz.atalar created

    I know feature system very well and it is irrelevant. I do not want my parent module depend all of optional/plugin modules. Every plugin module has implementations of some interfaces, for example. And I must manage DI manually for this scenario. At last I assume that Abp does not support dynamic dependency tree modification and we must add plugins at startup module.

    This feature would be nice, Abp team may consider adding it.

  • User Avatar
    0
    berkansasmaz created
    Support Team .NET Developer

    Yes, you are right.

    I'm treating this as a feature request and creating an internal issue. Let's take a closer look at what we can do.

    Thanks for your understanding, have a nice day.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    https://github.com/abpframework/abp/issues/13983

  • User Avatar
    0
    yilmaz.atalar created

    @berkansasmaz, @maliming

    Thank you for your attention.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19