Configuring NServicebus 4.7 with a predefined Autofac container

487 views Asked by At

I'm a bit at a loss here. I'm developing a hosted NServicebus (v4.7) windows service and using Autofac (v3.5) to do my own type resolution. Given the NServicebus documentation I thought it was possible to add my own container in NServicebus's endpoint configuration. However no matter what I do, I can't get it to work. My current endpointconfig is the following:

using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using Autofac;
using HyFlo.Base;
using NServiceBus;
using NServiceBus.ObjectBuilder.Autofac;
using NServiceBus.ObjectBuilder.Common.Config;

namespace HyFlo.Service
{
    /// <summary>
    ///     EndpointConfig
    /// </summary>
    public class EndpointConfig : IConfigureThisEndpoint, INeedInitialization, AsA_Publisher
    {
        public void Init()
        {
            TraceWriter.Info("Scannning for Hyflo assemblies .. ");

            var hyfloAssemblies = Directory.GetFiles(Directory.GetCurrentDirectory(), "Hyflo.*.dll",
                                                     SearchOption.TopDirectoryOnly);

            TraceWriter.Info("Initializing Autofac with assemblies .. ");
            try
            {
                var builder = new ContainerBuilder();
                Assembly[] allAssemblies = hyfloAssemblies.Select(Assembly.LoadFile).ToArray();
                builder.RegisterAssemblyTypes(allAssemblies).AsImplementedInterfaces().InstancePerLifetimeScope();
                IContainer container = builder.Build();

                TraceWriter.Trace(
                    String.Format(
                        "Found {0} assembl{1}. Configuring NServicebus to use Autofac preinitialized with these assembl{1} ..",
                        allAssemblies.Count(), allAssemblies.Count() == 1 ? "y" : "ies"));

                Configure.With().UsingContainer(new AutofacObjectBuilder(container));
            }
            catch (Exception ex)
            {
                TraceWriter.Trace(String.Format("Exception occurred during initialization. Exception is: {0}\n{1}",
                                                ex.Message, ex.StackTrace));
            }

            TraceWriter.Info("Initializing database en msmqsubscription .. ");

            string databusBasePath = ConfigurationManager.AppSettings["DataBusBasePath"] ?? "";

            TraceWriter.Trace(String.Format("Setting Databus's basepath to '{0}' ..", databusBasePath));
            Configure.With().FileShareDataBus(databusBasePath);

            Configure.With().MsmqSubscriptionStorage();
        }
    }
}

This code itself works however when the NServicebus initialisation continues an exception pops up:

Failed to execute installers: System.InvalidOperationException: Cannot configure properties for a type that hasn't been configured yet: NServiceBus.Un icast.UnicastBus at NServiceBus.ObjectBuilder.Autofac.AutofacObjectBuilder.ConfigureProperty(Type component, String property, Object value) in c:\BuildAgent\work\1b 05a2fea6e4cd32\src\NServiceBus.Core\ObjectBuilder\Autofac\AutofacObjectBuilder.cs:line 0 at NServiceBus.ObjectBuilder.Common.CommonObjectBuilder.ConfigureProperty[T](String propertyName, Object value) in c:\BuildAgent\work\1b05a2fea6e4c d32\src\NServiceBus.Core\ObjectBuilder\Common\CommonObjectBuilder.cs:line 110 at NServiceBus.Unicast.Config.FinalizeUnicastBusConfiguration.RegisterMessageOwnersAndBusAddress(IEnumerable'1 knownMessages) in c:\BuildAgent\work \1b05a2fea6e4cd32\src\NServiceBus.Core\Unicast\Config\FinalizeUnicastBusConfiguration.cs:line 57 at NServiceBus.Unicast.Config.FinalizeUnicastBusConfiguration.FinalizeConfiguration() in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\U nicast\Config\FinalizeUnicastBusConfiguration.cs:line 24 at NServiceBus.Configure.<>c__DisplayClass23`1.b__20(Type t) in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\Configu re.cs:line 555 at System.Collections.Generic.List'1.ForEach(Action'1 action) at NServiceBus.Configure.ActivateAndInvoke[T](Action'1 action, Nullable'1 thresholdForWarning) in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceB us.Core\Configure.cs:line 561 at NServiceBus.Configure.Initialize() in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\Configure.cs:line 361 at NServiceBus.Hosting.Windows.Installers.WindowsInstaller.RunInstall() in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Hosting.Windows\Inst allers\WindowsInstaller.cs:line 38

No matter what I do, for some reason NServicebus's initialisation can't continue. It looks like my own Autofac container isn't properly configured in NServicebus by using the Configure.With().UsingContainer() method but I've tried all kind of options but every time it boils down to the same exception that is being thrown. Any ideas what I'm doing wrong here?

2

There are 2 answers

3
Daniel Marbach On

Try changing the code like this:

Configure configure = Configure.With();
// rest of container initialization
configure.AutofacBuilder(container);
// other stuff
configure.FileShareDataBus(databusBasePath);
configure.MsmqSubscriptionStorage();

and see if it works.

4
Richard Flapper On

I found the answer to the problem. I scanned pretty much all DLL's to be included in Nservicebus's Autofac container. This also includes the DLL that contains the endpointconfig. Now when I exclude the DLL containing the endpoint, all goes well. I've now isolated pretty much all classes from the endpointconfig-DLL except for the message handlers. And now all goes well!