首页 > 解决方案 > 在 Xamarin 中使用 MassTransit

问题描述

我目前有一个使用 Autofac 和 MassTransit 的 WPF 应用程序。WPF 主窗口是由不同控件组成的复合 UI(状态部分、命令部分和主要部分)。我通过使用 MassTransit 和 InMemory 传输来传达这些控件的情况。

当用户键入特定文本框时,我会发布“IRipWidthChanged”事件。该事件的消费者将其拾取并在 WPF 中执行它的工作就好了。

查看模型

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());
    }
}

消费者

public task Consume(ConsumeContext<IRipWidthChanged> ctx) => Task.Run(() =>
    _viewModelFactory.Construct<ICommandsViewModel>().UpdateRipWidth(ctx.Message.NewRipWidth)
);

当调用“RipWidthString”属性的设置器时,总线会发布消息,但从未调用过我的使用者。我添加了故障和其他机制,以查看是否发生了其他事情但没有被调用。

我还使用相同的代码在这些前端之间设置我的 Autofac 容器,以便在 Autofac 中注册视图模型和 ServiceBus。

编辑 1 这是注册 Autofac 容器的代码

Android Xamarin 项目中的 MainActivity.cs

void RegisterDependencies() {
    App.Register<IMessageBox, AndroidMessageBox>();
    App.Register<IPopupMessage, AndroidPopupMessage>();
    App.Register<SemiAutoPage>();
    App.Register<CommandsControlViewModel>();
    App.BuildContainer();
}

Xamarin 核心项目中的 App.xaml.cs 文件

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();
}

以及设置和注册 MassTransit 总线的代码

ServiceBusModule.cs Autofac 模块

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();
        }

    }

标签: c#xamarinautofacmasstransit

解决方案


对于遇到此问题的任何其他人。请记住,确保启动服务总线非常重要。我的 WPF 和 Xamarin 应用程序之间的区别在于,在引导过程中,WPF 应用程序将解析 IServiceBus 接口并在应用程序启动之前启动它。

一旦我在 Xamarin 应用程序中做了同样的事情,一切都按我的预期工作。我的消费者被要求提供正确的信息。


推荐阅读