0

Initially I needed only one queue to be created by the MessageQueueFactory:

container.RegisterSingleton<IMessageQueueFactory>(() => {
    var uploadedWaybillsQueuePath = ConfigurationManager
        .AppSettings["msmq:UploadedDocumentsQueuePath"];
    return new MessageQueueFactory(uploadedWaybillsQueuePath);
});

Now that requirements have changed there's a need to support several queues.

The simplest thing I can do here is to add other paths (stored in app.config) to the factory's constructor and provide methods for each queue:

container.RegisterSingleton<IMessageQueueFactory>(() => {
    var uploadedDocsQueuePath = ConfigurationManager
        .AppSettings["msmq:UploadedDocumentsQueuePath"];
    var requestedDocsQueuePath = ConfigurationManager
        .AppSettings["msmq:RequestedDocumentsQueuePath"];

    return new MessageQueueFactory(
        uploadedWaybillsQueuePath,
        requestedDocsQueuePath
    );
});

interface IMessageQueueFactory {
    MessageQueue CreateUploadedDocsQueue();
    MessageQueue CreateRequestedDocsQueue();
}

Is it a poor design? How can it be refactored?

1
  • What do you mean by "poor?" Do you have any specific criteria? – Robert Harvey Jun 7 '16 at 14:54
1

You could have separate classes for each queue and inject those, instead of injecting the factory. Your design as described here does not need a factory beyond the IoC-container as the type of queue can be determined at compile-time.

Classes that need access to the queue can simply request an IUploadedDocsQueue or IRequestedDocsQueue as constructor parameter. The actual implementation of those interfaces could be done by a single class that wraps the builtin MessageQueue and implements both interfaces, or by a single abstract class that wraps the MessageQueue and is inherited by two concrete classes that implement said interfaces.

This design adheres more to the Single Responsability Principle than the design outlined here. When you need to add another queue to your current design, you must change the factory. With a class-per-queue, you simply add another class. Using the interfaces also allows you to mock and unittest your code much more easily, I doubt you can effectively mock the builtin MessageQueue class...

0

Looks largely ok to me. There's nothing to say that a factory should only have one method for creation.

The Gang-of-Four book specifically has examples in which a factory creates families of objects (I think the example were GUI widgets for different platforms e.g. Motif windows/buttons vs. OpenLook windows/buttons or similar). From the book (and the link above):

This is an Abstract Factory. A regular factory creates concrete objects of one type. An abstract factory creates concrete objects of varying types, depending on the concrete implementation of the factory itself. Its ability to focus on not just concrete objects, but entire families of concrete objects "distinguishes it from other creational patterns, which involve only one kind of product object" (pp51).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.