Simple Injector在Caliburn中引发错误.微型引导程序.在视图模型中调用异步方法时生成



我正在尝试使用Simple Injector作为Caliburn的DI容器。Micro。演示来源:https://github.com/nvstrien/WPFDemos

这个项目有一个基本的Caliburn。使用简单注射器容器的微型设置。ShellView有一个按钮,当按下时,会调用一个异步方法来获取一些模拟数据。

我在引导程序中收到这个错误。累积。

SimpleInjector。ActivationException:"找不到类型SequentialResult的注册。"。确保已注册SequentialResult,例如通过调用"Container"。注册<SequentialResult>((;'在注册阶段。由于Container,无法进行隐式注册。选项。ResolveUnregisteredConcreteTypes设置为"false",这是v5中的默认设置。这将禁止容器构造此未注册的具体类型。有关为什么默认情况下不允许解析未注册的具体类型,以及可以应用哪些可能的修复程序的更多信息,请参阅https://simpleinjector.org/ructd.'

这里有人建议注释掉Bootstrapper。BuildUp应该起作用:Caliburn。Micro引导程序';BuildUp';方法在使用Simple Injector时引发异常

但是,在执行此操作时,SimpleInjector仍将抛出异常。

将非常感谢任何解决此问题的帮助

我完整的引导程序配置文件如下:

public static readonly Container _container = new();
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
_container.Register<IWindowManager, WindowManager>();
_container.RegisterSingleton<IEventAggregator, EventAggregator>();
GetType().Assembly.GetTypes()
.Where(type => type.IsClass)
.Where(type => type.Name.EndsWith("ViewModel"))
.ToList()
.ForEach(viewModelType => _container.RegisterSingleton(viewModelType, viewModelType));
_container.Verify();
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
// as discussed here: https://stackoverflow.com/questions/32258863/simple-injector-getallinstances-throwing-exception-with-caliburn-micro
//_container.GetAllInstances(service);
IServiceProvider provider = _container;
Type collectionType = typeof(IEnumerable<>).MakeGenericType(service);
IEnumerable<object> services = (IEnumerable<object>)provider.GetService(collectionType);
return services ?? Enumerable.Empty<object>();
}
protected override object GetInstance(System.Type service, string key)
{
return _container.GetInstance(service);
}
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[] { Assembly.GetExecutingAssembly() };
}
// see: https://stackoverflow.com/questions/37631468/caliburn-micro-bootstrapper-buildup-method-throws-exception-when-simple-inject
// commenting out BuildUp still throws an exception in SimpleInjector.dll 
protected override void BuildUp(object instance)
{
InstanceProducer registration = _container.GetRegistration(instance.GetType(), true);
registration.Registration.InitializeInstance(instance);
}

在ShellViewModel中,我有一个方法,当按下ShellView上的按钮时会运行。

public async Task Button1()
{
Debug.Print("Hello world");
var data = await GetSampleDataAsync();
foreach (var item in data)
{
Debug.Print(item);
}
}
public async Task<IEnumerable<string>> GetSampleDataAsync()
{
// method simulating getting async data
var data = new List<string>() { "hello", "world" };
return await Task.FromResult(data);
}

调用"await GetSampleDataAsync(("时发生错误。

在引导程序中添加SequentialResult时。配置如下。

protected override void Configure()
{
_container.Register<IWindowManager, WindowManager>();
_container.RegisterSingleton<IEventAggregator, EventAggregator>();
_container.Register<SequentialResult>();
GetType().Assembly.GetTypes()
.Where(type => type.IsClass)
.Where(type => type.Name.EndsWith("ViewModel"))
.ToList()
.ForEach(viewModelType => _container.RegisterSingleton(viewModelType, viewModelType));
_container.Verify();
}

我得到下一个错误:

系统。InvalidOperationException
HResult=0x80131509消息=配置无效。正在创建类型SequentialResult的实例失败。类型的构造函数SequentialResult包含名为"enumerator"且类型IEnumerator<IResult>,但是IEnumerator<IResult>未注册。对于IEnumerator<IResult>若要解决,必须在容器Source=SimpleInjector StackTrace:位于SimpleInjector。InstanceProducer。位于的VerifyExpressionBuild((SimpleInjector。容器验证是否可以构建所有表达式(InstanceProducer[]生产商验证(SimpleInjector。容器VerifyThatAllExpressionsCanBeBuilt((位于SimpleInjector。容器VerifyInternal(布尔suppressLifestyleMismatchVerification(SimpleInjector。容器验证(VerificationOption选项(SimpleInjector。容器Verify((位于CaliburnMicroWithSimpleInjectorDemo。引导程序。中的Configure((C: \Users\Niels\source\repos\WPFDemos\CaliburnMicroWithSimpleInjectorDemo\Bootstrapper.cs:line37在Caliburn。Micro。BootstrapperBase。在开始运行时间((Caliburn。Micro。BootstrapperBase。在初始化((CaliburnMicroWithSimpleInjectorDemo。引导程序。。中的ctor((C: \Users\Niels\source\repos\WPFDemos\CaliburnMicroWithSimpleInjectorDemo\Bootstrapper.cs:line22

此异常最初是在此调用堆栈中引发的:【外部代码】

内部异常1:ActivationException:类型的构造函数SequentialResult包含名为"enumerator"且类型IEnumerator<IResult>,但是IEnumerator<IResult>未注册。对于IEnumerator<IResult>若要解决,必须在容器

当我将ShellViewModel中的方法更改为像这样同步时,我不会得到任何异常:

public void Button1()
{
Debug.Print("Hello world");
var data = GetSampleData();
foreach (var item in data)
{
Debug.Print(item);
}
}
public IEnumerable<string> GetSampleData()
{
var data = new List<string>() { "hello", "world" };
return data;
}

在我看来,容器没有得到正确的配置,无法与Caliburn中的一些实现一起工作。Micro,但引导程序配置遵循建议的路径。不幸的是,我无法理解这里的解释:Caliburn。Micro引导程序';BuildUp';方法在使用SimpleInjector时抛出异常。此外,标记为解决方案的内容在我的代码示例中似乎不起作用。

@Steven:评论BuildUp确实解决了我的问题。

我以为在来SO问我的问题之前,我已经在我的示例项目中测试了对BuildUp的注释,但现在再次尝试解决了我的问题。谢谢你让我重回正轨!

解决方案:注释掉/删除BootStrapper。正如这里也建议的那样:Caliburn。Micro引导程序';BuildUp';方法在使用Simple Injector时引发异常

//protected override void BuildUp(object instance)
//{
//    InstanceProducer registration = _container.GetRegistration(instance.GetType(), true);
//    registration.Registration.InitializeInstance(instance);
//}

最新更新