Skip to content

Host.Transport-2.0.0: Releasing v2.0.0

Compare
Choose a tag to compare
@zarusz zarusz released this 01 Apr 16:57
· 129 commits to master since this release
  1. SMB uses Microsoft.Extensions.DependencyInjection.Abstractions at the core.
    1.2. Removed Unity and Autofac plugins.
    1.2. Repurpose the SlimMessageBus.Host.AspNetCore plugin to just configure the MessageBus.Current static accessor.
  2. Incorporated hybrid transport into the core transport implementation (#161).
  3. An implementation of IHostedService is registered that starts consumers when used with the .NET Generic Host.
  4. Support for requests that do not have a response type associated with it (new types IRequestHandler<TRequest>, IRequest).
  5. The IRequest<TResponse> is the new replacement for IRequestMessage<TResponse> - please migrate.
  6. Streamlined the bus configuration - several improvements to the services.AddSlimMessageBus(mbb => {}):
    6.1. The services.AddSlimMessageBus(mbb => { }) can be used multiple times and the end result will be additive (internally it uses services.TryAddTransient())
    6.2. The MessageBusBuilder is registered in the MSDI
    6.3. Incorporated services registration for MSDI inside .AddSlimMessageBus()- this helps to put all the bus and plugin setup in one place.
    6.4. The IMessageBusConfigurator has been removed - adding several services.AddSlimMessageBus(mbb => {}) allows achieving modularization.
    6.5. Separation of bus configuration (declaring producers, consumers) away from MSDI services registration - this allows registering interceptor plugins in the MSDI from introspecting the actual producers, consumers, and their settings.
    6.6. SMB can assume the consumer type of IConsumer<TMessage> and hence the .WithConsumer<SomeConsumer>() can be skipped most of the time.
    6.7. The provider configuration uses an action method (#163).
  7. Upgrade the underlying transport client libraries to the latest versions (Redis, Kafka, Azure Service Bus, Azure Event Hub).
  8. Kafka default header serializer (#157).
  9. [Host.Outbox] Registers publish/consume interceptors only for the message types for which the producer opted in for outbox, and for consumers that opted in for transaction scope (optimization).

Ad 1.1. & 2.

Uninstall packages:

  • SlimMessageBus.Host.Autofac
  • SlimMessageBus.Host.Unity
  • SlimMessageBus.Host.MsDependencyInjection
  • SlimMessageBus.Host.FluentValidation.MsDependencyInjection
  • SlimMessageBus.Host.Hybrid

Ad 3.

The request processing will be awaited during .Send(), however, no response will be returned. If an exception were to happen on the handler side the exception will be thrown by the .Send().

Consider the following example:

// The request has to use the IRequest interface
public class SomeRequest : IRequest
{
}

// The handler has to use IRequestHandler<T> interface
public class SomeRequestHandler : IRequestHandler<SomeRequest>
{
  public async Task OnHandle(SomeRequest request)
  {
    // no response returned
  }
}

// The request is declared on the bus builder (for the producer side)
mbb.Produce<SomeRequest>(x =>
{
  x.DefaultTopic("topic");
})

// The request handler is declared on the bus builder (for the consumer side)
mbb.Handle<SomeRequest>(x => x
    .Topic("topic") // Topic to expect the requests on
    //.WithHandler<SomeRequestHandler>()
    .KafkaGroup("some-consumer-group") // kafka provider specific
);

// Usage example for the producer side
await bus.Send(new SampleRequest());

Ad 8.

Old way:

services.AddSlimMessageBus((mbb, svp) =>
{
  mbb.Consume<CustomerCreatedEvent>(x => x
          .Topic(topic)
          .WithConsumer<CustomerCreatedEventConsumer>() // Change (1)
          .SubscriptionName("sub");  
  });
  mbb.WithSerializer(new JsonMessageSerializer()); // Change (2)
}, addConsumersFromAssembly: new[] { Assembly.GetExecutingAssembly() }); // Change (3)

New way:

services.AddSlimMessageBus(mbb =>
{
  mbb.Consume<CustomerCreatedEvent>(x => x
          .Topic(topic)
          // The line below is now optional (1)
          // .WithConsumer<CustomerCreatedEventConsumer>() // Not needed, the IConsumer<CustomerCreatedEvent> will be looked up in DI
          .SubscriptionName("sub");
  });
  mbb.AddServicesFromAssembly(Assembly.GetExecutingAssembly())); // (3)
  mbb.AddJsonMessageSerializer(); // requires SlimMessageBus.Host.Serialization.Json package // (2)
});

Also, the .AddServicesFromAssembly() will register both CustomerCreatedEventConsumer and IConsumer<CustomerCreatedEvent> service types in the MSDI.


Ad 6.7.

// before
mbb.WithProviderServiceBus(new ServiceBusMessageBusSettings(serviceBusConnectionString));
// after
mbb.WithProviderServiceBus(cfg =>
{
	cfg.ConnectionString = serviceBusConnectionString;
});

// before
mbb.WithProviderEventHub(new EventHubMessageBusSettings(eventHubConnectionString, storageConnectionString, storageContainerName));
// after
mbb.WithProviderEventHub(cfg =>
{
	cfg.ConnectionString = eventHubConnectionString;
	cfg.StorageConnectionString = storageConnectionString;
	cfg.StorageBlobContainerName = storageContainerName;
});

// before
mbb.WithProviderKafka(new KafkaMessageBusSettings(kafkaBrokers));
// after
mbb.WithProviderKafka(cfg =>
{
	cfg.BrokerList = kafkaBrokers;
}

// before
mbb.WithProviderRedis(new RedisMessageBusSettings(redisConnectionString));
// after
mbb.WithProviderRedis(cfg =>
{
	cfg.ConnectionString = redisConnectionString;
});

Ad 1.2.

Old way:

// Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  // Set the MessageBus provider, so that IMessageBus are resolved from the current request scope
  MessageBus.SetProvider(MessageBusCurrentProviderBuilder.Create().From(app).Build());
}

New way:

services.AddSlimMessageBus(mbb =>
{
  mbb.AddAspNet();
});
services.AddHttpContextAccessor(); // This is required for the SlimMessageBus.Host.AspNetCore plugin