简单注入器WPF无效uri
尝试验证容器时出错 配置无效。为类型创建实例 设置模型失败。类型SettingModel的注册委托 抛出了一个异常。无效URI:指定的端口无效 这似乎是由属于mahapps.metro dll的管理器引起的。我似乎无法使它与简单的注入器配合使用简单注入器WPF无效uri,wpf,simple-injector,mahapps.metro,Wpf,Simple Injector,Mahapps.metro,尝试验证容器时出错 配置无效。为类型创建实例 设置模型失败。类型SettingModel的注册委托 抛出了一个异常。无效URI:指定的端口无效 这似乎是由属于mahapps.metro dll的管理器引起的。我似乎无法使它与简单的注入器配合使用 public SettingModel() { ThemeColor = ThemeManager.AppThemes.Select(t => t.Name).ToList(); AccentColor = ThemeManager
public SettingModel()
{
ThemeColor = ThemeManager.AppThemes.Select(t => t.Name).ToList();
AccentColor = ThemeManager.Accents.Select(a => a.Name).ToList();
var currentSetting = ThemeManager.DetectAppStyle(Application.Current);
CurrentTheme = currentSetting.Item1.Name;
CurrentAccent = currentSetting.Item2.Name;
}
我慢慢地移除了一些东西,它达到了我使用主题管理器的每一个地方都被破坏的程度。所以我开始把代码分成几部分,直到编译时我一直得到xamlparseexception,这很奇怪,因为我的代码在放入简单注入器之前就已经编译好了
我遵循了WPF集成教程,除非已经过时。我真的很想尝试简单的注入器,但它不能很好地集成
更新:完全例外
System.InvalidOperationException was unhandled
HResult=-2146233079
Message=The configuration is invalid. Creating the instance for type MainWindow failed. The registered delegate for type MainWindow threw an exception. Invalid URI: Invalid port specified.
Source=SimpleInjector
StackTrace:
at SimpleInjector.InstanceProducer.VerifyInstanceCreation()
at SimpleInjector.Container.VerifyInstanceCreation(InstanceProducer[] producersToVerify)
at SimpleInjector.Container.VerifyThatAllRootObjectsCanBeCreated()
at SimpleInjector.Container.VerifyInternal()
at SimpleInjector.Container.Verify(VerificationOption option)
at SimpleInjector.Container.Verify()
at Program.Bootstrap() in c:\Users\Work\Documents\Visual Studio 2012\Projects\AzurePeek\AzurePeek\Program.cs:line 35
at Program.Main() in c:\Users\Work\Documents\Visual Studio 2012\Projects\AzurePeek\AzurePeek\Program.cs:line 14
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: SimpleInjector.ActivationException
HResult=-2146233088
Message=The registered delegate for type MainWindow threw an exception. Invalid URI: Invalid port specified.
Source=SimpleInjector
StackTrace:
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.InstanceProducer.VerifyInstanceCreation()
InnerException: System.UriFormatException
HResult=-2146233033
Message=Invalid URI: Invalid port specified.
Source=System
StackTrace:
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString)
at MahApps.Metro.ThemeManager.get_AppThemes()
at AzurePeek.M
odel.SettingModel..ctor() in c:\Users\Work\Documents\Visual Studio 2012\Projects\AzurePeek\AzurePeek\Model\SettingModel.cs:line 24
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.GetInstance()
InnerException:
更新 在与MahApps.Metro库的colaborator之一@punker76讨论后,我们得出结论,发生此异常是因为您运行的代码超出了WPF应用程序的范围。很可能是因为您正在单元测试中测试配置 在这里你可以做两件事。您需要愚弄您的测试套件,使其认为它作为WPF应用程序运行,或者必须将依赖于
MyApps
的代码移出SettingModel
的构造函数
正如@punker76所讨论的,在启动WPF应用程序时,调用new FrameworkElement()
以某种方式确保内部UriParser
能够解析pack://
URI(谈论奇怪的隐藏依赖项)
另一个选择,也是我的偏好,就是做出选择。这意味着任何与构建对象图无关的代码都应该移出构造函数,并且应该在运行时完成
有很多方法可以做到这一点,但一个简单的方法是推迟SettingsModel
属性的初始化或推迟SettingsModel
本身的创建,因为它看起来根本不像是应该由DI容器维护的服务
通过引入允许在运行时访问设置的抽象,推迟创建设置模型
很容易:
public interface ISettingsProvider {
SettingsModel CurrentSettings { get; }
}
通过以下实施:
public class SettingsProvider : ISettingsProvider {
private readonly Lazy<SettingsModel> model = new Lazy<SettingsModel>(
() => new SettingsModel());
public SettingsModel CurrentSettings {
get { return this.model.Value; }
}
}
如果您查看提供给Uri
构造函数的url,就可以理解为什么它会抛出“Invalid Uri:Invalid port specified”异常。如果在控制台应用程序中运行以下代码,将出现相同的错误:
新Uri(“pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml”);
因此,我必须得出结论,
MahApps.Metro.ThemeManager.AppThemes
属性中存在导致此问题的错误。我想知道你以前是如何做到这一点的,因为我看不到解决这个问题的方法。您是否在引入Simple Injector的同时升级到MahApps.Metro的更新版本?有趣的是,在我的应用程序开始时,我使用了nuget的最新版本。当我在整个应用程序中安装和使用它时,一切似乎都很好。具有讽刺意味的是,如果我完全删除了设置模型,那么使用mahapps.metro的资源就会出现错误。hmm@ThaoNguyen:在我看来,这个mahapps.metro可能需要一些额外的开发。@Steven为什么你认为URI有一个bug?@punker76:在URI
类中没有bug,但是.NETURI
类根本不接受端口包://
,因此,MahApps.Metro的AppThemes
属性中显然存在一个bug。在与@punker76讨论后更新了这个问题。
container.RegisterSingle<ISettingsProvider>(new SettingsProvider());