I am using simpleinjector 2.3.0.0 and .net 4.5.
I have been trying to register a Factory which has a dependency on a IEnumerable, and an instance of a Thing, plus a unitofwork decorator. (among other things)
Here is my factory:
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));
}
}
and here is my implementation of 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;
}
}
my registration for this is
container.RegisterAll<IThing>(
from tp in typeof (IThing).Assembly.GetExportedTypes()
where !tp.IsAbstract
where typeof (IThing).IsAssignableFrom(tp)
select tp);
container.Register<IThingFactory , ThingFactory>();
This works absolutely fine and I can verify the container without exceptions.
However when I also add the following registration to the container I get an exception
container.RegisterDecorator(typeof(ICommandHandler<,>),
typeof(UnitOfWorkDecorator<,>));
The decorator is a Nhibernate UnitOFWork which manages an Nhibernate transaction(not that this matters)(which following this pattern 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
}
So anyway, when I add the decorator, I get the following exception. when I call
container.Verify();
Yet when I removed the decorator registration all is fine again.
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.
Stacktrace:
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()
Thanks for your help
Edit - ThingManager is the entry point and looks like this:
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);
}
}