I'm moving from MediatR to MassTransit to publish my domain events to a queue.
I'm using an interface IDomainEvent
in different domain events that implement such interface (in this case PersonCreated
and PersonPositionCreated
). Then I have an entity 'Person' with a list of IDomainEvent
in which I register all the domain events occurred. I Also have a consumer for each specific event.
After persist my entity, I want to iterate all the events of the entity and publish them to the queue.
// Event interface.
public class IDomainEvent
{
}
// Events.
public class PersonCreated : IDomainEvent
{
public int Id { get; set; }
}
public class PersonPositionCreated : IDomainEvent
{
public string Position { get; set; }
}
// Entity.
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Position { get; set; }
public List<IDomainEvent> Events { get; set; };
}
// Consumers.
public class PersonCreatedConsumer : IConsumer<PersonCreated>
{
public Task Consume(ConsumeContext<PersonCreated> context)
{
Debug.Print(context.Message.Id.ToString());
return Task.CompletedTask;
}
}
public class PersonPositionCreatedConsumer : IConsumer<PersonPositionCreated>
{
public Task Consume(ConsumeContext<PersonPositionCreated> context)
{
Debug.Print(context.Message.Position);
return Task.CompletedTask;
}
}
// My command.
//...
// Creates Person.
Person person = new Person(){ Id = 1, Name = "Alice", Position = "Developer" };
// Registers the events to the list.
person.Events.Add(new PersonCreated() { Id = person.Id });
person.Events.Add(new PersonPositionCreated() { Position = person.Position });
foreach (IDomainEvent personEvent in person.Events)
{
// This way, it publish an IDomainEvent and I don't want to use a IConsumer<IDoaminEvent> because I need specific consumers.
// How can I tell the bus that I sending the specific event and not the IDomainEvent?
//(I know that inside the iteration I'm dealing with IDomainEvent but it have access to the class that implement the interface).
// NOTE: That way works with MediatR specific handlers.
| |
\ /
\ /
\/
_bus.Publish(personEvent);
}
// Of course this two lines works!
//_bus.Publish<PersonCreated>(new PersonCreated() { Id = 1 });
//_bus.Publish<PersonPositionCreated>(new PersonPositionCreated() { Position = "Developer" });
//...
How can I tell the bus that I am sending the specific event and not the IDomainEvent? (I know that inside the iteration I'm dealing with IDomainEvent, but it has access to the class that implement the interface).
You should call:
_bus.Publish((object)personEvent);
By casting it to an object, MassTransit will call GetType()
and then publish to the exchange (and ultimately consumer) for the object type (aka, implemented message type).