I currently have a WPF app that utilizes Autofac and MassTransit. The main WPF window is a composite UI (a state section, commands section, and a main section) composed of different controls. I communicate what is going on with these controls by using MassTransit and the InMemory transport.
As a user types into a particular text box I publish an "IRipWidthChanged" event. The consumer for that event picks it up and does its thing in WPF just fine.
View Model
private string _ripWidthString;
public string RipWidthString {
get => _ripWidthString;
set => {
if (_ripWidthString == value) return;
FirePropertyChanged();
FirePropertyChanged(nameof(ClearValuesButtonEnabled));
_bus.PublishAsync(new RipWidthChanged.Builder() { NewRipWidth = value }.Build());
}
}
Consumer
public task Consume(ConsumeContext<IRipWidthChanged> ctx) => Task.Run(() =>
_viewModelFactory.Construct<ICommandsViewModel>().UpdateRipWidth(ctx.Message.NewRipWidth)
);
When the "RipWidthString" property's setter is called the bus publishes the message but my consumer is never called. I've added faults and other mechanisms to see if something else is happening but nothing is getting called.
I'm also using the same code to setup my Autofac container between these front-ends so the view models and the ServiceBus is getting registered in Autofac.
Edit 1 Here is the code that registers the Autofac container
MainActivity.cs in Android Xamarin project
void RegisterDependencies() {
App.Register<IMessageBox, AndroidMessageBox>();
App.Register<IPopupMessage, AndroidPopupMessage>();
App.Register<SemiAutoPage>();
App.Register<CommandsControlViewModel>();
App.BuildContainer();
}
App.xaml.cs file in Xamarin core project
private static void SetupDiContainer() {
_builder.RegisterModule(new ViewModelModule());
_builder.RegisterModule(new ServiceBusModule());
_builder.RegisterModule(new FactoriesModule());
_builder.RegisterModule(new ValidationModule());
_builder.RegisterModule(new FileSystemModule());
_builder.RegisterModule(new DataConversionModule());
_builder.RegisterType<NullLoggingService>().As<ILoggingService>();
_builder.RegisterType<MassTransitCommandExecutor>()
.As<ICommandExecutionService>()
.SingleInstance();
_builder.Register(ctx => ServiceFactory.Construct<IPanelSawService>(IPAddress.Parse("192.168.1.12"), 5001))
.As<IPanelSawService>();
_builder.Register(ctx => ServiceFactory.Construct<IMachineStateService>(IPAddress.Parse("192.168.1.12"), 5001))
.As<IMachineStateService>();
}
//...
public static void BuildContainer() {
SetupDiContainer();
_diContainer = _builder.Build();
}
And the code that sets up and registers the MassTransit bus
ServiceBusModule.cs Autofac Module
public class ServiceBusModule : Module {
protected override void Load(ContainerBuilder builder) {
builder.AddMassTransit(x => {
x.AddConsumers(
typeof(StateChangedConsumer),
typeof(CutCompletedConsumer),
typeof(SettingsConsumer),
typeof(ExceptionConsumer)
);
x.AddBus(context => Bus.Factory.CreateUsingInMemory(busConfig => {
busConfig.ReceiveEndpoint("panelsaw_queue", cfg => {
cfg.ConfigureConsumers(context);
});
}));
});
builder.Register(ctx => new PanelSawServiceBus(ctx.Resolve<IBus>(), ctx.Resolve<IBusControl>()))
.As<IServiceBus>()
.SingleInstance();
}
}
To anybody else who comes across this. Just remember it is VERY important to make sure you start the service bus. The difference between my WPF and Xamarin apps were that during the bootstrapping process the WPF app would resolve the IServiceBus interface and start it before the app would launch.
Once I did the same thing in the Xamarin app everything was working as I expected it to. My consumers were being called with the correct information.