0

I am trying to re-use the service registrations in an assembly that I use through a few services in my solution. I follow the example listed from the NServiceBus website to implement the solution. When following that, unless I add the IWantCustomInitialization interface, my Init method (and IoC container implementation) appears not to function. When I have that interface implemented, I get exceptions (listed in SO questions here and here). I can't seem to get it to work that there are no exceptions AND the dependencies in my MessageHandler are being populated properly. Here is my current EndpointConfig implementation.

[EndpointSLA("00:00:30")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, UsingTransport<Msmq>, INeedInitialization {
    public void Init() {
        Configure.With().ObjectBuilderAdapter();
    }
}
public class ObjectBuilderAdapter : IContainer {
    readonly IDependencyInjector injector;

    public ObjectBuilderAdapter(IDependencyInjectionBuilder dependencyInjectionBuilder) {
        injector = dependencyInjectionBuilder.Create(); //This method does all the common service registrations that I am trying to re-use
        //injector.RegisterType<ExtractIncomingPrincipal, PrincipalExtractor>();
    }

    public void Dispose() {
        injector.Dispose();
    }

    public object Build(Type typeToBuild) {
        return injector.Resolve(typeToBuild);
    }

    public IContainer BuildChildContainer() {
        return new ObjectBuilderAdapter(new DependencyInjectorBuilder());
    }

    public IEnumerable<object> BuildAll(Type typeToBuild) {
        return injector.ResolveAll(typeToBuild);
    }

    public void Configure(Type component, DependencyLifecycle dependencyLifecycle) {
        injector.RegisterType(component);
    }

    public void Configure<T>(Func<T> component, DependencyLifecycle dependencyLifecycle) {
        injector.RegisterType(component);
    }

    public void ConfigureProperty(Type component, string property, object value) {
        if (injector is AutofacDependencyInjector) {
          ((AutofacDependencyInjector)injector).ConfigureProperty(component, property, value);
        } else {
            Debug.WriteLine("Configuring {0} for property {1} but we don't handle this scenario.", component.Name, property);
        }
    }

    public void RegisterSingleton(Type lookupType, object instance) {
        injector.RegisterInstance(lookupType, instance);
    }

    public bool HasComponent(Type componentType) {
        return injector.IsRegistered(componentType);
    }

    public void Release(object instance) { }
}

public static class Extensions { public static Configure ObjectBuilderAdapter(this Configure config) { ConfigureCommon.With(config, new ObjectBuilderAdapter(new DependencyInjectorBuilder())); return config; } }

Note: When I use the INeedInitialization interface, I get the ComponentNotRegisteredException when it's looking for IStartableBus.

Community
  • 1
  • 1
Flea
  • 1,490
  • 2
  • 19
  • 43

1 Answers1

0

When you are trying to swap the built in container, then you need to implement IWantCustomInitialization in the same class that implements IConfigureThisEndpoint.

You can use your own container and register all your types in there and tell NSB to use that container.

For example:

 public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    public void Init()
    {
        var container = new ContainerBuilder().Build();
        Configure.With()
            .AutofacBuilder(container);
    }
}
Indu Alagarsamy
  • 449
  • 2
  • 4
  • Simply changing this to IWantCustomInitialization resuls in the error noted in this SO question posted previously. (http://stackoverflow.com/questions/18536774/nservicebus-fails-to-process-message-the-requested-service-nservicebus-imperso) – Flea Sep 04 '13 at 21:10
  • I added in the implementation of the ObjectBuilderAdapter above because, though your solution works (by using the built-in AutofacBuilder), I am not sure why the exceptions are occurring with using my ObjectBuilderAdapter as per the the documentation here (http://support.nservicebus.com/customer/portal/articles/852357-containers). There must be something that the AutofacBuilder (and other builders) is doing to register those dependencies. My suspicion is that there is a base class that does a couple registrations that my class could benefit from inheriting from. – Flea Sep 05 '13 at 14:02
  • I think the root of this comes in that the NServiceBus.ObjectBuilder.Autofac.AutofacObjectBuilder class calls ContainerBuilder.Build() from AutoFac that, by default, performs autoregistration based on reflectively loading assemblies. I am not doing that in my solution but, rather, manually registering dependencies with AutoFac. – Flea Sep 05 '13 at 14:14
  • I was incorrect on that assumption. I have ContainerBuilder.Build in my wrapped implementation as well. – Flea Sep 05 '13 at 19:02