I am using an interface to send message to a handler using NServicebus. Below is the interface:
interface IDeliveryTarget
{
public DeliveryType DeliveryType { get; }
public string DocumentId { get; set; }
}
Child Classes Email and Fax:
class EmailTarget : IDeliveryTarget
{
public DeliveryType DeliveryType => DeliveryType.Email;
public int DocumentId {get;set;}
public string MessageBody { get; set; }
public string[] Recepients { get; set; }
public string Subject { get; set; }
}
class FaxTarget : IDeliveryTarget
{
public DeliveryType DeliveryType => DeliveryType.Email;
public int DocumentId {get;set;}
public string FaxNumber { get; set; }
public string FaxUserName { get; set; }
public string Organization { get; set; }
public string Subject { get; set; }
}
I send List<IDeliveryTarget>
from handler as below:
context.Publish(new UploadSuccess
{
DeliveryTargets = new List<IDeliveryTarget>()
}
This list has many Email and Fax inputs.
Handled in another Saga as below:
public async Task Handle(UploadSuccess message, IMessageHandlerContext context)
But here the UploadSuccess message has only properties defined in IDeliveryTarget interface but Email and Fax specific properties are missing.
I except Email and Fax properties to be present for further processing. Please guide.
CodePudding user response:
An alternative solution to what @MindSwipe mentioned is to have dedicated properties on the event for each of the concrete types ie.:
context.Publish(new UploadSuccess
{
EmailTargets = new List<EmailTarget>(),
FaxTargest = new List<FaxTarget>();
}
This will allow you to access concrete types' properties in a handler without the need for casting.
CodePudding user response:
You need to cast the items in DeliveryTarget
to a concrete implementation of your interface, those properties are still there, they're just hidden to intellisense because you have a variable of type IDeliveryTarget
which doesn't declare those properties you want.
Do something like this:
public async Task Handle(UploadSuccess message, IMessageHandlerContext ctx)
{
foreach (IDeliveryTarget target in message.DeliveryTargets)
{
if (target is EmailTarget emailTarget)
{
Console.WriteLine($"Got email target with subject {emailTarget.Subject}");
}
else if ( ... )
}
}
This becomes cumbersome with lots of implementations, I'd suggest you add a method like Handle
to the IDeliveryTarget
interface and use polymorphism to shorten that to:
public async Task Handle(UploadSuccess message, IMessageHandlerContext ctx)
{
foreach (IDeliveryTarget target in message.DeliveryTargets)
await target.Handle();
}