我们有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);
}
}
答案 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;
}