This project is read-only.

Simple Injector with NServiceBus

Dec 29, 2014 at 8:17 PM
I've seen that earlier this year some activity was done on integrating Simple Injector with NServiceBus.

I've tried using this GitHub repo as it looked pretty complete. https://github.com/dotnetjunkie/NServiceBus.SimpleInjector

But I get an error :

The best overloaded method match for 'SimpleInjector.Container.RegisterInitializer<object>(System.Action<object>)' has some invalid arguments and the stack trace is :

at CallSite.Target(Closure , CallSite , Object , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
at Argentiere.PATrading.Core.SimpleInjectorObjectBuilder.ConfigureProperty(Type component, String property, Object value) in c:\Development\Workspaces\Argentiere.PATrading\Main\Argentiere.PATrading\Argentiere.PATrading.Core\SimpleInjector\SimpleInjectorObjectBuilder.cs:line 123
at NServiceBus.ObjectBuilder.Common.ComponentConfig.NServiceBus.ObjectBuilder.IComponentConfig.ConfigureProperty(String name, Object value) in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\ObjectBuilder\Common\ComponentConfig.cs:line 20
at NServiceBus.ObjectBuilder.Common.ComponentConfig1.NServiceBus.ObjectBuilder.IComponentConfig<T>.ConfigureProperty(Expression1 property, Object value) in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\ObjectBuilder\Common\ComponentConfig.cs:line 36
at NServiceBus.Configure.RegisterContainerAdapter(IContainer container) in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\Configure.cs:line 75
at NServiceBus.Configure..ctor(SettingsHolder settings, IContainer container, List`1 registrations, PipelineSettings pipeline) in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\Configure.cs:line 32
at NServiceBus.BusConfiguration.BuildConfiguration() in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\BusConfiguration.cs:line 238
at NServiceBus.Bus.Create(BusConfiguration configuration) in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\Bus.cs:line 17
at Argentiere.PATrading.WebApp2.NServiceBusConfig.Register(Container container) in c:\Development\Workspaces\Argentiere.PATrading\Main\Argentiere.PATrading\Argentiere.PATrading.WebApp2\App_Start\NServiceBusConfig.cs:line 56
at Argentiere.PATrading.WebApp2.Startup.Configuration(IAppBuilder app) in c:\Development\Workspaces\Argentiere.PATrading\Main\Argentiere.PATrading\Argentiere.PATrading.WebApp2\Startup.cs:line 27

I'm just wondering if this is a problem with my setup or whether anyone has successfully integrated NServiceBus with Simple Injector ?

Here's my bootstrap code :

var container = new Container();

IoCConfig.Register(container);
NServiceBusConfig.Register(container);

container.Verify();

and the error occurs when I call :

busConfig.UseContainer(new SimpleInjectorObjectBuilder(container));


Thanks

John
Dec 29, 2014 at 8:54 PM
Hi John,

Steven is away on holiday at the moment so I will do what I can to help. Are you able to provide or upload enough code for me to reproduce this?
Dec 29, 2014 at 9:26 PM
Thanks for a quick response, let me quickly put together something I can share on GitHub - is that ok ?

I'll post back the repo url here - should be less than an hour. It won't be a working NServiceBus as such as the problem occurs before the Bus is up and running.

The area of code which is failing is this one :
        Delegate action = Expression.Lambda(actionType,
            Expression.Assign(
                Expression.Property(parameter, property),
                Expression.Constant(value)),
            parameter)
            .Compile();

        ((dynamic)this.Container).RegisterInitializer((dynamic)action);
It's something to do with the action definition but looking at the values it looks ok (it's trying to register the NServiceBus Container to point at the SimpleInjectorObject builder.
Dec 29, 2014 at 9:43 PM
So this demo project shows the error I'm getting. I hope it's not something stupid :-(

https://github.com/johnkattenhorn/NServiceBusSimpleInjectorTesting.git

Thanks in advance for any help.
Dec 29, 2014 at 9:56 PM
Hi John,

I can't probably do much from here, but it seems to me that I never tested this ComfigureProperties method. I tried to do a shortcut using dynamic typing, but that doesn't seem to work at all.

You probably need to change that code to use the .NET reflection API to allow RegisterInitializer<T>(Action<T>) to be called.
Dec 29, 2014 at 10:20 PM
OK, I'll do some digging into the reflection API tomorrow to see what I can find out; I'm nearing the edge of my experience in this area.

I should still be able to use the compiled action though shouldn't I ?

Am I right in thinking I just need reflections give me back <T> for the RegisterInitializer<T> ?

Don't worry too much as your on holiday, if needs be I'll jump back to Autofac for a couple of weeks and work on this as a side project. I've only recently migrated from Autofac to Simple Injector when I saw how much faster it was :-) Great work :-)
Dec 29, 2014 at 10:40 PM
You probably need something like:
// find RegisterInitializer<T>(Action <T>)
var m = (
from method in typeof (Container).GetMethods ()
where method.Name.StartsWith ("RegisterInitializer")
where method.GetParamers().Length == 1
select method).
Single();

m.MakeGenericMethod (component)
.Invoke(container, delegate);
Dec 30, 2014 at 8:10 AM
I've made the change as suggested by dot_NET_Junkie and it does get a bit further although it still doesn't work. It now fails as it seems to be trying to add to the container after its locked.

I've checked some anything simple and couldn't seen anything, I'm wondering if the Action being defined on RegisterInitializer it actually running rather than just being defined with the code I've created.

Anyway's I've checked in the latest changes into both the fork of the original work and my test project. I really need to get something out of the door but I wont give up on this so I'll come back to it in a couple of weeks if someone does beat me to it.