我正在使用Prism + Unity库构建模块化WPF应用程序。我将解决方案分为以下项目: -通用项目(界面) -主应用程序,加载dll -模块,主应用程序项目不会引用它们。
子模块dll被构建到bin \(Debug | Release)\ Modules文件夹中
要在主应用中加载的代码如下:
它:
已加载的dll中的设置模块(搜索IModule类型)
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
base.ConfigureModuleCatalog(moduleCatalog);
List<Assembly> allAssemblies = new List<Assembly>();
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
foreach (string dll in Directory.GetFiles(path + "/Modules/", "*.dll"))
allAssemblies.Add(Assembly.LoadFile(dll));
AutoRegisterClasses(allAssemblies);
var modules = AllClasses.FromAssemblies(allAssemblies).Where(t => t.GetInterfaces().Contains(typeof(IModule)));
foreach (var module in modules)
{
moduleCatalog.AddModule(
new ModuleInfo()
{
ModuleName = module.Name,
ModuleType = module.AssemblyQualifiedName,
Ref = "file://" + module.Assembly.Location
});
}
}
private void AutoRegisterClasses(List<Assembly> allAssemblies)
{
var defaultRegisters = AllClasses.FromAssemblies(allAssemblies).Where(t => t.IsDefined(typeof(AutoRegisterAttribute), true));
foreach (var register in defaultRegisters)
foreach (var interface_ in register.GetInterfaces())
Container.GetContainer().RegisterType(interface_, register, null, new TransientLifetimeManager());
}
注册和模块初始化有效-一切都被调用了。当我尝试从子模块项目中实现与通用项目的交互时,我收到正确的对象。但是,当我尝试显示此提供程序返回的 ContentControl 时,会收到以下异常:
组件'AdditionalDll.MainWindow'没有由URI'/AdditionalDll;component/mainwindow.xaml'标识的资源。
我不知道为什么会出现问题,更有趣的是,当我不将DLL存储在Modules文件夹中时-也就是说,当我将它们与主exe并存时,一切正常 > !!!
我创建了具有此问题的最小解决方案: https://github.com/BAndysc/AssemblyLoadProblemExample
Common/Interfaces.cs - is common project, contains AutoRegister attribute and example interface that I will try to resolve
AdditionalDll/ExampleProvider.cs - is in submodule project, it is implementation of the mentioned interface, it returns new view from AdditionalDll project
TestMultiProjectApp/App.xaml.cs - setups everything - load dlls, register types, init modules
TestMultiProjectApp/MainWindow.xaml - is simple view, which shows given ContentControl
TestMultiProjectApp/MainWindowViewModel.cs - is simple viewmodel, which resolves IProvider interface (it works) and on command assigns returned view to property, which is then displayed by view (this causes exception)
虽然将dll与exe放在同一文件夹中是一种解决方法,但我宁愿将它们放在单独的文件夹中以保持整洁,如果有人对如何修复它们有任何想法,我将不胜感激。
答案 0 :(得分:0)
这在很多层面上都是有缺陷的。例如:
MainWindowViewModel
尝试创建和存储ContentControl
MainWindow
?您应该退后一步,重新访问您的体系结构。您的模块的职责是什么?您的应用程序有什么责任?您如何识别并加载模块?您想如何部署和加载模块的依赖项? gui的计划布局如何?
然后您应该再退一步,并回顾一些有关WPF开发的基本文档,即数据绑定,数据模板,资源字典,视图和视图模型之间的区别。
编辑:让我谈谈评论中提到的几点。
public
类型。DataTemplate
发生,或者(对于Prism)通过ViewModelLocator
发生。如果可以的话,视图模型永远都不应该拥有,创建或知道视图类型。