我对内置的CM SimpleContainer没有任何问题,但今天我需要转到Simple Injector。
当我通过cal:Message.Attach
调用异步方法时,Bootstrapper BuildUp
方法会引发异常:
发生类型
'SimpleInjector.ActivationException'
的异常 SimpleInjector.dll但未在用户代码中处理其他信息:SequentialResult类型的构造函数 包含名称'枚举器'的参数。并输入 未注册的
IEnumerator<IResult>
。请确保IEnumerator<IResult>
已注册,或更改了构造函数 SequentialResult。
这是我的引导课程:
protected override void Configure()
{
_container.RegisterSingleton<IEventAggregator, EventAggregator>();
_container.RegisterSingleton<IWindowManager, WindowManager>();
_container.Verify();
}
protected override object GetInstance(Type service, string key)
{
var instance = _container.GetInstance(service);
if (instance != null)
return instance;
throw new InvalidOperationException("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
IServiceProvider provider = _container;
Type collectionType = typeof(IEnumerable<>).MakeGenericType(service);
var services = (IEnumerable<object>)provider.GetService(collectionType);
return services ?? Enumerable.Empty<object>();
}
protected override void BuildUp(object instance)
{
var registration = _container.GetRegistration(instance.GetType(), true);
registration.Registration.InitializeInstance(instance);
}
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[] { Assembly.GetExecutingAssembly() };
}
XAML的一部分:
<Border Grid.Row="2" Padding="10" Background="#F0F0F0" BorderBrush="#DFDFDF" BorderThickness="0,1,0,0">
<StackPanel Orientation="Horizontal">
<Button IsCancel="True" Content="{Resx Key=Close}" />
<Button IsDefault="True" MinWidth="{Resx Key=CheckOrUpdateBtnWidth, DefaultValue='115'}" Margin="8,0,0,0"
cal:Message.Attach="CheckUpdateAsync" />
</StackPanel>
</Border>
VM的一部分:
public async Task CheckUpdateAsync()
{
IsUpdateDownloading = true;
try
{
await Task.Run(async () =>
{
Cts = new CancellationTokenSource();
var http = new HttpClient();
HttpResponseMessage rm = await http.GetAsync(UpdateInfo.DownloadUri, HttpCompletionOption.ResponseHeadersRead, Cts.Token);
long size = rm.Content.Headers.ContentLength.GetValueOrDefault();
var downloader = FileDownloader.Create(UpdateInfo.DownloadUri);
byte[] data = downloader.Download(Cts.Token);
downloader.ValidateHash(data, CloudManager.UpdateInfo.Sha256);
});
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
Logger.Error(ex);
throw;
}
finally
{
IsUpdateDownloading = false;
ProgressValue = 0;
}
}
我做错了什么?
答案 0 :(得分:1)
在C.M.内部使用Message.Attach()
使用CoRoutines。看看C. {的source我看到这段代码:
public static Func<IEnumerator<IResult>, IResult> CreateParentEnumerator =
inner => new SequentialResult(inner);
即。如果没有覆盖,则使用默认的SequentialResult<IResult>
。
Furtheron:
var enumerator = CreateParentEnumerator(coroutine);
IoC.BuildUp(enumerator);
这是例外来自。内部调用BuildUp
,当您直接调用容器来查找注册时,Simple Injector将抛出ActivationException
。
在大多数情况下,您根本不需要实施BuildUp
方法。当您使用Simple Injector作为DI容器时,我无法想到您为什么要使用此方法。我通常不会实施这种方法。
BuildUp是一种方法,如果需要将(使用属性注入)注入到无法使用普通Simple Injector管道创建的组件中,通常需要这种方法。您可以在Simple Injector文档here中阅读有关详细信息。
在这种情况下,我认为在这种情况下你不需要建立SequentialResult
。你不需要注入这个C.M.默认类。
所以这里的问题是你需要BuildUp
所需的任何课程吗?您的应用程序设计通常应该只使用您在Simple Injector中注册的应用程序本身中定义的类,并且可以使用GetInstance()
直接解析。
如果答案是&#39; no&#39;,则永远不会在外部类中注入依赖项,完全删除BuildUp()方法。
如果你需要BuildUp()其他类,只有覆盖默认的PropertyInjectionBehaviour
才有意义。如果你不重写这个,打电话给registration.InitializeInstance
根本没有意义,因为Simple Injector不知道要注入什么,因为Simple Injector只支持{{3 }} 盒子外面。覆盖默认的PropertyInjectionBehaviour
时,您可以创建某种隐式行为。
总而言之,我认为你应该完全删除BuildUp方法,因为当前的实现并没有做任何事情。 InitializeInstance不会注入任何内容。
答案 1 :(得分:0)
//this was an example from Simple Injector.
var repositoryAssembly = typeof(SqlUserRepository).Assembly;
var registrations =
from type in repositoryAssembly.GetExportedTypes()
where type.Namespace == "MyComp.MyProd.BL.SqlRepositories"
where type.GetInterfaces().Any()
select new { Service = type.GetInterfaces().Single(), Implementation = type };
foreach (var reg in registrations) {
container.Register(reg.Service, reg.Implementation, Lifestyle.Transient);
}
虽然我知道具有SelectedAssemblies覆盖的CM是&#34;假设&#34;为了解决与程序集相关的所有事情,我推测GetAllInstances中的几行并没有获得CM所需的所有内容。我认为您需要扩展以包含type.GetIntefaces().Any()
。我希望能够满足SequentialResult的CTOR需求。
我还没有使用过Simple Injector,但是我说它的工作方式非常相似,并且对于开放式泛型可能会有更好的处理。我认为你应该在Configure中进行更少的注册。我假设没有其他任何事情在XAML的那部分之前死亡或失败,并且#34;抛出&#34;注射器问题..这似乎不是CM问题,而是简单的注射器配置。