3
votes

We use NServiceBus.Host.exe to host our service and the assembly for our endpoint is located in the same folder with NServiceBus.Host.exe. Under the main folder we have a subfolder containing assemblies that are needed for our processes handling the messages. The problem we have is that when NServiceBus.Host.exe loads it finds the assemblies from the subfolder but can't load them and crashes with an error:


Unhandled Exception: Magnum.StateMachine.StateMachineException: Exception occurred in Topshelf.Internal.ServiceController1[ [NServiceBus.Hosting.Windows.WindowsHost, NServiceBus.Host, Version=3.0.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c]] during state Initial while handling OnStart ---> Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type WindowsHost, key "MyPoint.BusMessageEndPoint, MyPoint, Version=4.3.0.0, Culture=neutral, PublicKeyToken=null" ---> System.IO.FileNotFoundException: Could not load file or assembly 'MyAssembly, Version=4.3.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) at System.Reflection.Assembly.Load(String assemblyString) at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at NServiceBus.Hosting.GenericHost..ctor(IConfigureThisEndpoint specifier, String[] args, IEnumerable1 defaultProfiles,String endpointName, IEnumerable1 scannableAssembliesFullName) in c:\NServiceBus-NServiceBus-3.3.5-0\src\hosting\NServiceBus.Hosting\GenericHost.cs:line 145 at NServiceBus.Hosting.Windows.WindowsHost..ctor(Type endpointType, String[] args, String endpointName, Boolean runOtherInstallers, Boolean runInfrastructureInstallers, IEnumerable1 scannableAssembliesFullName) in c:\NServiceBus-NServiceBus-3.3.5-0\src\hosting\NServiceBus.Hosting.Windows\WindowsHost.cs:line 31 at NServiceBus.Hosting.Windows.HostServiceLocator.DoGetInstance(Type serviceType, String key) in c:\NServiceBus-NServiceBus-3.3.5-0\src\hosting\NServiceBus.Hosting.Windows\HostServiceLocator.cs:line 41 at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in :line 0


It seems that the host finds the assemblies in some way but can't load them. I haven't found any way to tell the host not to look inside the subfolder. Everything works fine if I move the assemblies from the subfolder to the mainfolder (in the same folder where the NServiceBus.Host.exe is) but that makes our structure very untidy and this subfolder way worked just fine with NServiceBus 2.6 - now after upgrading to 3.3.5 we have a problem.

Is there some way to block subfolders from the hosts load - or if the host finds the assemblies in the subfolder why can't it load them? That would solve our problem too.

Many thanks if someone can help me with this.


I'll add my comments to the answers here, if I can clarify our case a bit. Thanks for the answers!

The assemblies in the subfolder are not needed to be loaded by NSericeBus.Host.exe - they are loaded from our message endpoint assembly (which is loaded by NServiceBus.Host) by using MEF.

In NServiceBus 2.6 the assemblies in the subfolder either were not loaded by NServiceBus.Host or it could handle them and now is not able to do so. The load crashes before I can affect what it loads. In debug the crash happens before the Configure.With() happens so I can't tell NServiceBus to dismiss the subfolder.

2
I am having the exact same issue, we deploy additional MEF plugins in a /plugin folder. Did you just end up putting all the files in the same place?Rob Bird
@RobBird I ended up putting the additional plugins in a folder outside the NServiceBus host folder and load them from there. I tested with all the plugins in the NServiceBus folder but that slowed the subscriber so much I had to remove them. I wish I could put the plugins in a subfolder in the NServiceBus host folder since that would be so much neater installation but couldn't get that working so this is the next best solution for our environment.user2459400

2 Answers

0
votes

You can't have those necessary assemblies in a subfolder. I wasn't aware that this worked in 2.6 but if so it was probably unintended. I do know that somewhere in there the method used to load assemblies was changed so that we could use Configure.With() in all instances and not have to decide between .With() and .WithWeb when self-hosting. Perhaps this is a side-effect of that change.

In any case, why does it matter if the main deployment directory is "untidy"? I would think this would just complicate deployment scenarios to try to make it look prettier and certainly wouldn't add any business value.

1
votes

If you enable custom initialization via the IWantCustomInitialization interface, the .With() method has options to provide a specific directory or a list of assemblies or types.