c# - 在 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();
}
}
解决方案
对于遇到此问题的任何其他人。请记住,确保启动服务总线非常重要。我的 WPF 和 Xamarin 应用程序之间的区别在于,在引导过程中,WPF 应用程序将解析 IServiceBus 接口并在应用程序启动之前启动它。
一旦我在 Xamarin 应用程序中做了同样的事情,一切都按我的预期工作。我的消费者被要求提供正确的信息。
推荐阅读
- kubernetes - Wireshark 跟踪 - 分析代理和服务之间的超时
- sharepoint-2013 - 在 Sharepoint 文档库中上传和保存文档时面临问题
- graphics - 我如何知道 AMD 显卡是否专用于 d3d11(或 dxgi)?
- android - 如何为 Recyclerview 的特定项目设置动画?
- node.js - 无法使用 Hyperledger Fabric 在我的链代码 nodejs 项目上安装 fabric-shim
- javascript - 当用户使用js或ts点击地图时,我们如何转换azure地图语言?
- python - Django:将“选择”从另一个数据库传递到 MultipleChoiceField
- java - POST request body cannot contain chinese characters in Java
- opengl - OpenGL,片段着色器:没有这样的统一命名
- css - 如何仅在左侧和右侧获得框阴影