Prism应用程序中的多个DirectoryModuleCatalog

时间:2018-02-23 10:33:12

标签: c# wpf unity-container prism

我们有Unity + Prism WPF应用程序,并且有2个文件夹,我们希望从中动态加载模块。

我知道要从目录加载模块,我应该使用DirectoryModuleCatalog,但CreateModuleCatalog方法只允许返回一个目录,那么如何将它们包装在一个目录中呢? / p>

在我的boostrapper中,我应该回到这里:

    protected override IModuleCatalog CreateModuleCatalog()
    {
        new DirectoryModuleCatalog() { ModulePath = @".\Services" };
        new DirectoryModuleCatalog() { ModulePath = @".\Packages" };
        //Maybe some day another catalog, maybe not even a directory one.

        return ???????;
    }

根据@Haukinger的说法,我应该开发自己的目录,所以我从这开始:

public class AggregatedModuleCatalog : IModuleCatalog
{

    private readonly List<IModuleCatalog> _catalogs;
    private readonly ModuleCatalog _localModulesCatalog = new ModuleCatalog();

    public IEnumerable<ModuleInfo> Modules => _catalogs.SelectMany(c => c.Modules).ToList();

    public AggregatedModuleCatalog(IReadOnlyCollection<IModuleCatalog> catalogs)
    {
        if (catalogs == null)
        {
            throw new ArgumentNullException();
        }
        _catalogs = new List<IModuleCatalog>(_catalogs) {_localModulesCatalog};
    }

    public IEnumerable<ModuleInfo> GetDependentModules(ModuleInfo moduleInfo)
    {
        return _catalogs.SelectMany(c => c.GetDependentModules(moduleInfo)).Distinct().ToList();
    }

    public IEnumerable<ModuleInfo> CompleteListWithDependencies(IEnumerable<ModuleInfo> modules)
    {
        return _catalogs.SelectMany(c => c.CompleteListWithDependencies(modules)).Distinct().ToList();
    }

    public void Initialize()
    {
        _catalogs.ForEach(c => c.Initialize());
    }

    public void AddModule(ModuleInfo moduleInfo)
    {
        _localModulesCatalog.AddModule(moduleInfo);
    }
}

2 个答案:

答案 0 :(得分:0)

您需要编写一个AggregatingModuleCatalog来实现IModuleCatalog并接收其他几个IModuleCatalog,并且它的实现会以某种方式委托内部目录。

可能更容易克隆DirectoryModuleCatalog并使其在多个目录中查找。旧的SmartDirectoryModuleCatalog也可能是一个很好的起点。

答案 1 :(得分:0)

以下解决方案适用于 Prism 8。如果对您有帮助,请告诉我。

protected override IModuleCatalog CreateModuleCatalog()
{
     var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
     var directories = new string[]{"Modules", "Services" };

     List<IModuleCatalogItem> components = new List<IModuleCatalogItem>();

     foreach (var dir in directories)
     {
         var dirCatelog = new DirectoryModuleCatalog() { ModulePath = $"{path}\\{dir}" };
         dirCatelog.Initialize();

         components.AddRange(dirCatelog.Items);
     }

     var catelog = new ModuleCatalog();

     foreach (var com in components)
     {
         catelog.Items.Add(com);
     }

     return catelog;
}