HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Large message population design

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
messagelargedesignpopulation

Problem

We are designing a small framework to create and send messages to external parties as a result of internal events. I am reasonably happy with the design, but I am wandering if it can be further improved.

The external messages are large and complex and involve getting data from different areas in the system and are sent asynchronously when the internal event happens. A single internal event can cause multiple external messages to be sent.

The internal event (incomingMessage) contains some of the information required to populate the message, and that is provided to the message sending framework, but additional information is required to be retrieved from the database through a potentially expensive query.

The MessageBuilder class builds the messages resulting from the internal event with the help of a list of IMessageContentProvider, which can provide content for different parts of the message. These are passed in through the constructor.

```
public interface IMessageBuilder
{
IEnumerable Build(TIncoming incomingMessage);
}
public class MessageBuilder : IMessageBuilder where TOutgoing : class, new()
{
private readonly IMessageContentProvider[] contentProviders;

public MessageBuilder(IMessageContentProvider[] contentProviders)
{
this.contentProviders = contentProviders;
}

public IEnumerable Build(Project project, IServiceBusResolver serviceBusResolver, TIncoming incomingMessage)
{
TOutgoing outgoingMessage = BuildOutgoingMessage(project, serviceBusResolver, incomingMessage);

return outgoingMessage != null ? new[] { outgoingMessage } : null;
}

protected virtual TOutgoing BuildOutgoingMessage(Project project, IServiceBusResolver serviceBusResolver, TIncoming incomingMessage)
{
TOutgoing outgoingMessage = new TOutgoing();

foreach (IMessageContentProvider contentProvider in contentProviders)
{
contentProvider.Populate(incomingMessage, re

Solution

public IEnumerable Build(Project project, IServiceBusResolver serviceBusResolver, TIncoming incomingMessage)
{        
    TOutgoing outgoingMessage = BuildOutgoingMessage(project, serviceBusResolver, incomingMessage);

    return outgoingMessage != null ? new[] { outgoingMessage } : null;
}


Why should this return an IEnumerable ? This just doesn't make sense at all. BuildOutgoingMessage() is only building one object.

The BuildOutgoingMessage() method doesn't use the serviceBusResolver parameter. If this is because it is only for overriding in a derived class, you should consider to add some documentation for this case.

The MessageBuilder class states that it implements IMessageBuilder but it doesn't implement its method.

Code Snippets

public IEnumerable<object> Build(Project project, IServiceBusResolver serviceBusResolver, TIncoming incomingMessage)
{        
    TOutgoing outgoingMessage = BuildOutgoingMessage(project, serviceBusResolver, incomingMessage);

    return outgoingMessage != null ? new[] { outgoingMessage } : null;
}

Context

StackExchange Code Review Q#75095, answer score: 3

Revisions (0)

No revisions yet.