我目前正在从事一个项目,该项目允许第三方参与我们产品的消息代理。任务是提供这些第三方可以使用的库。我希望能够将Mass Transit或NServiceBus与其打包在一起,但我想将这些细节隐藏在接口后面。
我已经这样隐藏了服务总线本身...
public class MyServiceBus : IServiceBus {
private readonly MassTransit.IBus _bus;
private readonly MassTransit.IBusControl _busControl;
public PanelSawServiceBus(MassTransit.IBus bus, MassTransit.IBusControl busControl) {
_bus = bus;
_busControl = busControl;
}
public Task PublishAsync<T>(T message, CancellationToken token = default(CancellationToken)) where T : class =>
_bus.Publish(message, token);
public Task SendAsync<T>(T message, CancellationToken token = default(CancellationToken)) where T : class =>
(_bus as ISendEndpointProvider)?.Send(message, token);
public Task StartAsync() => _busControl.StartAsync();
public Task StopAsync() => _busControl.StopAsync();
}
不应允许供应商发布/发送消息,而应该仅是消耗者。如何隐藏消息的使用方式,以便可以打包服务总线库,而不能公开后台使用的库?
编辑1 使用大众运输消费一条消息
public class MyConsumer : IConsumer<SomeMessage> {
public Task Consume(ConsumeContext<SomeMessage> ctx) => Task.CompletedTask;
}
在创建服务总线实例的引导过程中,您可以定义您的使用者(Mass Transit将在为您发送消息时构造它们)。
var busControl = Bus.Factory.CreateUsingInMemory(config => {
config.ReceiveEndpoint("queue_name", endpointCfg => {
endpointCfg.Consumer<MyConsumer>();
}
};
我希望包装器执行的操作是允许开发人员说“使用队列工厂,我想用 this 队列名称构造一个实例,这是实现类型的名称消费者接口隐藏了总线技术的接口。”我只是不知道我是否可以隐藏消费者。
答案 0 :(得分:0)
如果我的理解正确,那么您希望避免将代码耦合到NServiceBus或MassTransit,并且不想公开正在使用的代码。
首先,去耦:
通过定义自己的IServiceBus
接口,您已经完成了部分工作。只要您的库仅依赖于该接口,而不依赖于任何实现,就不应耦合到任何一个。
为了确保避免这种耦合,我将具体的实现保存在单独的项目/库中。您的“核心”域也不应直接引用。如果您可以在没有任何具体实现的情况下对代码进行单元测试,则可以在实现之间自由切换。
发布库时,您可以发布核心库的组成以及所选接口的实现。
然后,隐藏使用的实现:
至于不公开使用NServiceBus
还是MassTransit
,则不能。如果有人引用您的库,并且该库依赖于其中一个软件包,则他们也必须添加该软件包。假设您的库是为NuGet打包的,则该软件包将显示其依赖性。