Multiple Decorator pattern in castle-windsor

2019-04-20 00:14发布

问题:

We are in the process of redesigning some legacy software to be more testable and have decided upon Dependency-Injection and Castle.Windsor to help us.

First, our goal: * A number of decorators that all work on a data stream. * Multiple combinations of the decorators are possible and the root nodes in each case can be required to get data from different places.

Technically, our design is as follows:

interface IUpdateableValue<T> 
{
  T Get();
};

We have e.g. three sets of data to be retrieved with a number of components, all implementing IUpdateableValue() (Pseudo-code):

JsonParser(
    Decompressor(
        Decrypter(decryptionKey
            FileCache(filename, 
                HttpWebDownloader(url))))

XmlParser(
    Decompressor(
        Decrypter(decryptionKey2
            FileCache(filename2, 
                HttpWebDownloader(url2))))

I'm having trouble getting out design to fit into a DI-framework like Castle-Windsor. I suspect some of it could be handled by named instances, but this seems smelly for this usage.

The idea is that the "user" of e.g. the JsonParser and XmlParser instances don't know (or care) whether data comes from a HttpUrl, a file or magically pulled out of a hat.

I'm thinking there is something wrong in our design, but unsure how to fix it.

Any ideas on how to progress?

回答1:

With Castle Windsor you can implicitly configure decoraters by registering them in the correct order. You need to register the outer decorater first:

container.Register(Component
  .For<IUpdateableValue>()
  .ImplementedBy<JsonParser>());
container.Register(Component
  .For<IUpdateableValue>()
  .ImplementedBy<Decompressor>());
container.Register(Component
  .For<IUpdateableValue>()
  .ImplementedBy<Decrypter>());
...

When you resolve IUpdateableValue Caste Windsor will automatically wire up the dependencies, so they are nested correctly.