- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 simpleinjector 2.3.0.0 和 .net 4.5。
我一直在尝试注册一个依赖于 IEnumerable 的工厂、一个事物的实例以及一个工作单元装饰器。 (除其他事项外)
这是我的工厂:
public class ThingFactory : IThingFactory
{
private readonly IEnumerable<IThing> things;
public ThingFactory (IEnumerable<IThing> things)
{
this.things= things;
}
public IThing GetThing(ThingType thingType)
{
return things.FirstOrDefault(t => t.IsApplicable(thingType));
}
}
这是我对 IThing 的实现
public class ThingOne: IThing
{
private IThingFactory thingFactory;
public ThingOne(IThingFactory thingFactory)
{
this.thingFactory= thingFactory;
}
public void Execute(MyDto myDto)
{
//do stuff
//get the next approiate IThing out of the factory and execute
}
public bool IsApplicable(ThingType thingType)
{
return thingType == ThingType.ThingOne;
}
我的注册是
container.RegisterAll<IThing>(
from tp in typeof (IThing).Assembly.GetExportedTypes()
where !tp.IsAbstract
where typeof (IThing).IsAssignableFrom(tp)
select tp);
container.Register<IThingFactory , ThingFactory>();
这绝对没问题,我可以无一异常(exception)地验证容器。但是,当我还将以下注册添加到容器时,出现异常
container.RegisterDecorator(typeof(ICommandHandler<,>),
typeof(UnitOfWorkDecorator<,>));
装饰器是一个 Nhibernate UnitOFWork,它管理一个 Nhibernate 事务(这并不重要)(遵循此模式 https://cuttingedge.it/blogs/steven/pivot/entry.php?id=91)
public class UnitOfWorkDecorator<TCommand, TResult>
: ICommandHandler<TCommand, TResult>
where TCommand : ICommand
{
public UnitOfWorkDecorator(
ICommandHandler<TCommand, TResult> decoratedCommandHandler)
{
this.currentSessionContextService = currentSessionContextService;
this.decoratedCommandHandler = decoratedCommandHandler;
}
public void Handle(TCommand command)
{
//start my nhibernate transaction
decoratedCommandHandler.Handle(command);
//commit the transaction
}
所以无论如何,当我添加装饰器时,我得到以下异常。当我打电话时
container.Verify();
然而,当我删除装饰器注册时,一切又好了。
Topshelf v3.1.107.0, .NET Framework v4.0.30319.18052
Topshelf.Hosts.ConsoleRunHost Error: 0 : An exception occurred, System.Reflectio
n.TargetInvocationException: Exception has been thrown by the target of an invoc
ation. ---> System.InvalidOperationException: The configuration is invalid. Crea
ting the instance for type IThingManager failed. The registered delegate for t
ype IThingManager threw an exception. The registered delegate for type IThingFa
ctory threw an exception. The registered delegate for type IEnumerable<IThing> th
rew an exception. No registration for type ThingOne could be found a
nd an implicit registration could not be made. ---> SimpleInjector.ActivationEx
ception: The registered delegate for type IThingManager threw an exception. Th
e registered delegate for type IThingFactory threw an exception. The registered d
elegate for type IEnumerable<IThing> threw an exception. No registration for type
ThingOne could be found and an implicit registration could not be m
ade. ---> SimpleInjector.ActivationException: The registered delegate for type
IThingFactory threw an exception. The registered delegate for type IEnumerable<IThing>
threw an exception. No registration for type ThingOne could be
found and an implicit registration could not be made. ---> SimpleInjector.Activ
ationException: The registered delegate for type IEnumerable<IThing> threw an exc
eption. No registration for type ThingOne could be found and an impl
icit registration could not be made. ---> SimpleInjector.ActivationException: N
o registration for type ThingOne could be found and an implicit regi
stration could not be made.
堆栈跟踪:
at SimpleInjector.Container.ThrowNotConstructableException(Type concreteType)
at SimpleInjector.Container.ThrowMissingInstanceProducerException(Type servic
eType)at SimpleInjector.Container.GetRegistration(Type serviceType, Boolean throwOn
Failure) at SimpleInjector.Advanced.ContainerControlledCollection`1.
<>c__DisplayClass1
0.<ToLazyInstanceProducer>b__f() at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue() at
SimpleInjector.Advanced.ContainerControlledCollection`1.<SimpleInjector.Ad
vanced.IContainerControlledCollection.GetRelationships>b__1(Lazy`1 p)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<SelectManyIterator>d__31`3.MoveNext()
at System.Linq.Enumerable.<DistinctIterator>d__81`1.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at SimpleInjector.Advanced.ContainerControlledCollection`1.SimpleInjector.Adv
anced.IContainerControlledCollection.GetRelationships()
at SimpleInjector.Extensions.Decorators.DecoratorHelpers.ContainerControlledC
ollectionRegistration.GetRelationshipsCore()
at SimpleInjector.Registration.GetRelationships()
at SimpleInjector.InstanceProducer.GetRelationships()
at SimpleInjector.Container.OnExpressionBuilt(ExpressionBuiltEventArgs e, Ins
tanceProducer instanceProducer)
at SimpleInjector.InstanceProducer.BuildExpressionInternal()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at SimpleInjector.InstanceProducer.BuildExpression()
--- End of inner exception stack trace ---
at SimpleInjector.InstanceProducer.BuildExpression()
at SimpleInjector.Advanced.DefaultConstructorInjectionBehavior.BuildParameter
Expression(ParameterInfo parameter)
at SimpleInjector.Registration.BuildParameterExpressionFor(ParameterInfo para
meter)
at SimpleInjector.Registration.<BuildNewExpression>b__1a(<>f__AnonymousTypef`
2 <>h__TransparentIdentifier18)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at SimpleInjector.Registration.BuildNewExpression(Type serviceType, Type impl
ementationType)
at SimpleInjector.Registration.BuildTransientExpression[TService,TImplementat
ion]()
at SimpleInjector.Lifestyles.TransientLifestyle.TransientLifestyleRegistratio
n`2.BuildExpression()
at SimpleInjector.InstanceProducer.BuildExpressionInternal()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at SimpleInjector.InstanceProducer.BuildExpression()
--- End of inner exception stack trace ---
at SimpleInjector.InstanceProducer.BuildExpression()
at SimpleInjector.Advanced.DefaultConstructorInjectionBehavior.BuildParameter
Expression(ParameterInfo parameter)
at SimpleInjector.Registration.BuildParameterExpressionFor(ParameterInfo para
meter)
at SimpleInjector.Registration.<BuildNewExpression>b__1a(<>f__AnonymousTypef`
2 <>h__TransparentIdentifier18)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at SimpleInjector.Registration.BuildNewExpression(Type serviceType, Type impl
ementationType)
at SimpleInjector.Registration.BuildTransientExpression[TService,TImplementat
ion]()
at SimpleInjector.Lifestyles.TransientLifestyle.TransientLifestyleRegistratio
n`2.BuildExpression()
at SimpleInjector.InstanceProducer.BuildExpressionInternal()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at SimpleInjector.InstanceProducer.BuildInstanceCreator(Object& createdInstan
ce)
at SimpleInjector.InstanceProducer.GetInstance()
--- End of inner exception stack trace ---
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.InstanceProducer.Verify()
--- End of inner exception stack trace ---
at SimpleInjector.InstanceProducer.Verify()
at SimpleInjector.Container.VerifyProducers(InstanceProducer[] producersToVer
ify)
at SimpleInjector.Container.ValidateRegistrations()
at SimpleInjector.Container.Verify()
谢谢你的帮助
编辑 - ThingManager 是入口点,如下所示:
public class ThingManager : IThingManager
{
private readonly IThingFactory thingFactory;
public ThingManager(IThingFactory thingFactory)
{
this.thingFactory = thingFactory;
}
public void Run(MyDto myDto)
{
var firstThing = thingFactory.GetThing(ThingType.ThingOne);
firstThing.Execute(myDto);
}
}
最佳答案
问题是由您的代码中的循环引用引起的:ThingFactory
取决于 IEnumerable<IThing>
, 这取决于 ThingOne
, 这取决于 ThingFactory
,这将关闭循环。
不幸的是由于 a bug在 Simple Injector 2.3 中,描述循环引用的真正错误被隐藏,并抛出一条表达能力较差(在本例中甚至不正确)的消息。此错误已在 Simple Injector 2.3.5 中得到修复.
尽管循环引用存在于您的代码库中,Verify
方法仅在注册装饰器时注意到此错误。内部ContainerControlledCollection<T>
导致注册的元素被预编译,这允许 InstanceProducer
注意循环的实例。没有 ContainerControlledCollection<T>
即使在解析类型时,集合的评估也更加延迟,这完全隐藏了这个错误。然而,您设计中的这个怪癖可能仍然会在以后引起各种问题。
对于即将推出的 Simple Injector 2.4 ContainerControlledCollection<T>
在 Verify()
的情况下实际上会更懒惰地提高性能不被调用(这对于具有深层对象图和包含许多项的集合的应用程序有意义),但这意味着即使使用装饰器,验证器也不会抛出异常。
Simple Injector 2.4 不抛出异常的行为其实是正确的(事实上 2.3 和 2.3.5 抛出异常可以被认为是一个错误),因为 Simple Injector 的目标是在构建对象时防止 stackoverflow 异常图(当调用 GetInstance
时)。由于 IEnumerable<T>
之后类型的创建被延迟使用(解析 IEnumerable<T>
不解析实例;只有迭代集合才解析),没有 stackoverflow 异常。
虽然在您的代码中使用循环引用可能会产生代码异味,但在您的代码中它可能只会导致代码中的递归(但不会导致 stackoverflow),这可能是预期的行为。
您仍然可能想要重新考虑设计,因为递归深度为 10(假设您有 10 个东西并调用工厂以获取列表中的下一个东西),这将触发创建 55 个东西(10 倍于第一个元素,9 个第二个元素,8 个第三个,... 1 个第十个元素),这可能不是您所期望的。
关于c# - 注册装饰器与注册 IEnumerable<T> 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18916981/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!