Использование MassTransit в Xamarin - PullRequest
1 голос
/ 28 октября 2019

В настоящее время у меня есть приложение WPF, которое использует Autofac и MassTransit. Основное окно WPF представляет собой составной пользовательский интерфейс (раздел состояний, раздел команд и основной раздел), состоящий из различных элементов управления. Я сообщаю, что происходит с этими элементами управления, используя 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 между этими интерфейсами, чтобы модели представления иServiceBus регистрируется в Autofac.

Редактировать 1 Вот код, который регистрирует контейнер Autofac

MainActivity.cs вПроект Android Xamarin

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

Файл App.xaml.cs в основном проекте Xamarin

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

    }

1 Ответ

1 голос
/ 28 октября 2019

Для всех, кто сталкивался с этим. Просто помните, что ОЧЕНЬ важно убедиться, что вы запускаете сервисный автобус. Разница между моими приложениями WPF и Xamarin заключалась в том, что во время процесса начальной загрузки приложение WPF разрешало бы интерфейс IServiceBus и запускало его до запуска приложения.

После того, как я сделал то же самое в приложении Xamarin, все работалокак я и ожидал. Моим потребителям звонили с правильной информацией.

...