Question

I am implementing application in PRISM, which need to import modules dynamically from dll files. I managed to do that - they are importing, but I can't display it. I decided to create a special module to encapsulate it - let us call it ModuleDock. So we have something like that:

Bootstrapper.cs:

class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<Shell>();
    }

    protected override void InitializeShell()
    {
        base.InitializeShell();

        Application.Current.MainWindow = (Window)Shell;
        Application.Current.MainWindow.Show();
    }

    protected override IModuleCatalog CreateModuleCatalog()
    {
        var modules = new DirectoryModuleCatalog
        {
            LoadSubdirectories = true,
            ModulePath = @"C:\Modules"
        };

        modules.AddModule(typeof(ModuleDockModule));

        return modules;
    }
}

Shell.xaml:

<ContentControl regions:RegionManager.RegionName="ModuleDockModule" />

ModuleDockModule.cs (in ModuleDock project):

public class ModuleDockModule : IModule
{
    private readonly IRegionManager _regionManager;
    private readonly IUnityContainer _unityContainer;

    public void Initialize()
    {
        RegisterIoc();
        if (_regionManager.Regions.ContainsRegionWithName("ModuleDockModule"))
        {
            _regionManager.RegisterViewWithRegion("ModuleDockModule", typeof(ModuleDockView));
        }
    }

    public ModuleDockModule(IRegionManager regionManager, IUnityContainer unityContainer, IRegionViewRegistry regionViewRegistry)
    {
        _regionManager = regionManager;
        _unityContainer = unityContainer;
    }

    private void RegisterIoc()
    {
        _unityContainer.RegisterType<IModuleDockView, ModuleDockView>();

        _unityContainer.RegisterType<IModuleDockViewModel, ModuleDockViewModel>();
    }

}

and finally in one of loaded modules:

[Module(ModuleName = "TestModule", OnDemand = false)]
public class TestModuleModule : IModule
{
    private readonly IRegionManager _regionManager;
    private readonly IUnityContainer _unityContainer;

    public void Initialize()
    {
        RegisterIoc();
        if (_regionManager.Regions.ContainsRegionWithName("TestModule"))
        {
            _regionManager.RegisterViewWithRegion("TestModule", typeof(TestView));
        }
    }

    public TestModuleModule(IRegionManager regionManager, IUnityContainer unityContainer)
    {
        _regionManager = regionManager;
        _unityContainer = unityContainer;
    }

    private void RegisterIoc()
    {
        _unityContainer.RegisterType<ITestView, TestView>();

        _unityContainer.RegisterType<ITestViewModel, TestViewModel>();
    }
}

For test purposes I've created that line of XAML:

<ContentControl regions:RegionManager.RegionName="TestModule" />

Could you tell me, why that line displays TestModule in Shell.xaml, but don't display it in ModuleDockView.xaml?

Please, mind that in final stage I have to use various number of unknown modules provided by other users of my platform, so I can't make anything static (like module names or initializations). Thank you in advance!

Was it helpful?

Solution

Based on the code you described, the TestModule module has a module dependency with ModuleDockModule as this is defining the region that the TestModule's Views would then be registered into.

Therefore, you would need to make sure that ModuleDockModule is initialized before TestModule and any other module that would depend on it. In order to do this, you would need to declare a dependency attribute on TestModuleModule class, right above the class definition as follows:

[Module(ModuleName = "TestModule", OnDemand = false)]
[ModuleDependency("ModuleDockModule")]
public class TestModuleModule : IModule
{ ...

For more information about Moduled you may refer to the following MSDN Prism Guide chapter:

I hope this helped you, Regards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top