问题描述
我正在尝试使用 Simple Injector 作为 Caliburn.Micro 的 DI 容器。演示源:https://github.com/nvstrien/WPFDemos
这个项目有一个基本的 Caliburn.Micro 设置和一个简单的注射器容器。 ShellView 有 1 个按钮,按下时会调用异步方法来获取一些模拟数据。
我在 Bootstrapper.Buildup 中收到此错误。
SimpleInjector.ActivationException: '找不到 SequentialResult 类型的注册。确保 SequentialResult 已注册,例如通过调用 'Container.Register
这里建议注释掉 Bootstrapper.BuildUp 应该可以工作:Caliburn.Micro Bootstrapper 'BuildUp' method throws exception when Simple Injector is used
但是,这样做时,SimpleInjector 仍然会抛出异常。
任何解决此问题的帮助将不胜感激
我完整的 Bootstrapper 配置文件如下所示:
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 中,我有 1 个方法在按下 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()'被调用时发生错误。
在 Bootstrapper.Configure 中添加 SequentialResult 时,如下所示。
protected override void Configure()
{
_container.Register<IWindowManager,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();
}
system.invalidOperationException
HResult=0x80131509 消息=配置无效。创造
SequentialResult 类型的实例失败。类型的构造函数
SequentialResult 包含名称为“enumerator”的参数和
输入 IEnumerator
内部异常1:ActivationException:类型的构造函数
SequentialResult 包含名称为“enumerator”的参数和
输入 IEnumerator
当我像这样将 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 中的某些实现一起工作,但 Bootstrapper 配置遵循推荐的路径。不幸的是,我无法遵循此处的解释:Caliburn.Micro Bootstrapper 'BuildUp' method throws exception when Simple Injector is used 此外,标记为解决方案的内容在我的代码示例中似乎不起作用。
解决方法
@Steven:注释 BuildUp 确实解决了我的问题。
我以为我在来 SO 询问我的问题之前已经测试过在我的示例项目中注释掉 BuildUp,但现在再次尝试解决了我的问题。感谢您让我重回正轨!
解决方案:注释掉/删除 BootStrapper.BuildUp ,正如此处的建议:Caliburn.Micro Bootstrapper 'BuildUp' method throws exception when Simple Injector is used
//protected override void BuildUp(object instance)
//{
// InstanceProducer registration = _container.GetRegistration(instance.GetType(),true);
// registration.Registration.InitializeInstance(instance);
//}