【发布时间】: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