处理解析错误
Prism-Documentation-CH
2023-1-13
[!注意] 此功能是在Prism 8中引入的,如果您的应用程序使用的是早期版本,则此功能不适用
出现异常的原因有很多。开发人员遇到的一些常见错误是未注册的服务或在解析视图时生成异常的无效XAML。Prism容器扩展现在非常有意地捕捉任何底层容器异常并抛出ContainerResolutionException
。ContainerResolutionException的目标也很简单,通过为您提供诊断和修复代码中问题时所需的信息来缩短开发周期。
ContainerResolutionException
包含许多常量消息,例如MissingRegistration
、CannotResolveAbstractType
或CyclicalDependency
。除了这些常量之外,它还暴露了正在解析的ServiceName和/或ServiceType的属性。
public class ModuleA : IModule
{
private IServiceIForgotToRegister IAmADunce { get; }
public ModuleA(IServiceIForgotToRegister iAmADummy)
{
IAmADunce = iAmADummy;
}
}
通过查看上面的代码片段,我们可以看到我有一个服务作为硬依赖注入到ModuleA中。不幸的是我忘记注册服务了。我们当然可以挂接到 ModuleManager中的LoadModuleCompleted事件上,这样我们就可以看到加载模块时发生了什么,如下所示:
protected override void InitializeModules()
{
var manager = Container.Resolve<IModuleManager>();
manager.LoadModuleCompleted += LoadModuleCompleted;
manager.Run();
}
private void LoadModuleCompleted(object sender, LoadModuleCompletedEventArgs e)
{
LoadModuleCompleted(e.ModuleInfo, e.Error, e.IsErrorHandled);
}
protected virtual void LoadModuleCompleted(IModuleInfo moduleInfo, Exception error, bool isHandled)
{
if (error != null)
{
// Do Something
}
}
在此例子中,我将看到错误是一个ContainerResolutionException,并且ServiceType是ModuleA,以及没有ServiceName。但这并没有给我足够的信息。幸运的是,ContainerResolutionException
也有一个GetErrors()
方法,它为我们提供了查看类型和错误信息的能力:
protected virtual void LoadModuleCompleted(IModuleInfo moduleInfo, Exception error, bool isHandled)
{
if (error != null && error is ContainerResolutionException cre)
{
var errors = cre.GetErrors();
foreach((var type, var ex) in errors)
{
Console.WriteLine($"Error with: {type.FullName}");
Console.WriteLine($"{ex.GetType().Name}: {ex.Message}");
}
}
}
当我们运行该程序时,应该会看到类似以下输出的内容:
Error with: MyProject.Services.IServiceIForgotToRegister
ContainerResolutionException: No Registration was found in the container for the specified type