【问题标题】:Using MassTransit in Xamarin在 Xamarin 中使用 MassTransit
【发布时间】:2019-10-28 15:33:51
【问题描述】:

我目前有一个使用 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();
        }

    }

【问题讨论】:

  • 我不太清楚问题出在哪里——你是说你在应用程序的其他地方发布了 IRipWidthChanged 消息并且它工作正常,但不是吗?在我看来,这里有很多东西需要解压,我们可能需要更多信息:尤其是设置端点和总线的代码。我在这里看到的一个问题是您没有(也不能)在属性设置器中等待。尝试使调用同步(但是您最好在 WPF 中这样做),在发布期间可能会出现问题?
  • 在 WPF 中,当总线发布消息时,我的消费者会像我期望的那样被调用。在 Xamarin 应用程序中,当视图模型发布消息时,我的使用者没有被调用。我的视图模型和使用者在 WPF 和 Xamarin 项目之间共享。

标签: c# xamarin autofac masstransit


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2017-11-18
    • 2023-03-25
    • 1970-01-01
    • 2022-06-13
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    相关资源
    最近更新 更多