2

I'm building a plugin component for Dynamics CRM 2015. Because we're deploying to CRM Online, the plugin has to be a single signed DLL - we can't deploy additional DLLs alongside it and we can't put anything in the GAC, so I'm using ilmerge.exe to merge and sign my assemblies into a single DLL.

Problem is that, as far as I can see, EasyNetQ/RabbitMQ aren't sending any messages when they're ilmerged. I can reproduce this locally, so it's not a CRM environment issue.

I've got three DLLs

  • MyPlugin.dll
  • EasyNetQ.dll
  • RabbitMQ.Client.dll

If I reference these DLLs separately in my test code and invoke .Execute() on my plugin code, everything works beautifully

I have a post-build step:

$(SolutionDir)packages\ilmerge.2.14.1208\tools\ilmerge.exe /out:$(TargetDir)MyPlugin.Ilmerged.dll /keyfile:$(TargetDir)plugin_key.snk $(TargetDir)EasyNetQ.dll $(TargetDir)RabbitMQ.Client.dll $(TargetDir)MyPlugin.dll

This spits out a single signed DLL, MyPlug.Ilmerged.dll, that (in theory!) contains EasyNetQ, RabbitMQ and my plugin code. Everything compiles just fine. If I remove the individual DLL references from my test code and add a single reference to this ILMerged assembly, it compiles fine, and the code doesn't throw any exceptions - I just don't get any messages appearing on the queue.

Might this be related to the assembly binding redirect that EasyNetQ is using to resolve RabbitMQ? Or something? I'm completely stumped as to how ILMerge could be causing it to fail silently without actually throwing any errors or anything.

Dylan Beattie
  • 53,688
  • 35
  • 128
  • 197

1 Answers1

3

OK, I've switched on the ConsoleLogger and turns out the messages ARE being published - but they're being published to a different exchange, because the qualified type name of my messages is being changed by the ILMerge step

ILMerged:

DEBUG: Declared Exchange: MyPlugin.CrmEntityChange:MyPlugin.Ilmerged type:topic, durable:True, autoDelete:False, delayed:False DEBUG: Published to exchange: 'MyPlugin.CrmEntityChange:MyPlugin.Ilmerged', routing key: 'person.crm2015.changed', correlationId: '094fbde9-f7a3-4884-82d7-8a1792e38d6e'

Unmerged:

DEBUG: Declared Exchange: MyPluginCrmEntityChange:MyPlugin type:topic, durable:True, autoDelete:False, delayed:False DEBUG: Published to exchange: 'MyPlugin.CrmEntityChange:MyPlugin', routing key: 'person.crm2015.changed', correlationId: 'e41b4360-04c8-4210-917a-17540d41f3ce'

So what's happening is that my publisher is sending messages of type MyPlugin.Ilmerged.CrmEntityChange but my subscriber is listening for MyPlugin.CrmEntityChange - and since nothing is ever subscribing to MyPlugin.Ilmerged.CrmEntityChange messages, no queue is being created on the host and the messages are just being discarded.

The solution - well, my solution - is to modify the post-build step so that the ILMerged DLL has the same name as the assembly containing my message types. This does mean that you end up with two different DLLs both called MyPlug.dll - one is the ILMerged assembly that gets deployed into CRM and the other is the reference assembly used by the subscriber - but since these assemblies should never be deployed onto the same system, I'm prepared to take the risk.

Dylan Beattie
  • 53,688
  • 35
  • 128
  • 197