Collections 用Castle Windsor装饰系列中的每件物品

Collections 用Castle Windsor装饰系列中的每件物品,collections,castle-windsor,decorator,Collections,Castle Windsor,Decorator,假设我有一个具有多个基本实现的接口: interface IPrinter { void Print(); } class Printer1 : IPrinter { public void Print() { Console.WriteLine(GetType()); } } class Printer2 : IPrinter { public void Print() { Console.WriteLine(

假设我有一个具有多个基本实现的接口:

interface IPrinter
{
    void Print();
}

class Printer1 : IPrinter
{
    public void Print()
    {
        Console.WriteLine(GetType());
    }
}

class Printer2 : IPrinter
{
    public void Print()
    {
        Console.WriteLine(GetType());
    }
}
我还有一个decorator实现:

class ModifyingPrinter : IPrinter
{
    private readonly IPrinter _printer;

    public ModifyingPrinter(IPrinter printer)
    {
        _printer = printer;
    }

    public void Print()
    {
        Console.Write("Modified ");
        _printer.Print();
    }
}
最后,我有一个需要接口集合的服务:

class Service
{
    private readonly IEnumerable<IPrinter> _printers;
    public Service(IEnumerable<IPrinter> printers)
    {
        _printer = printer;
    }

    public void Print()
    {
        foreach (var printer in _printer)
        {
            printer.Print();
        }
    }
}
我已尝试按如下方式注册这些类:

var container = new WindsorContainer();

container.Kernel.Resolver.AddSubResolver(
    new CollectionResolver(container.Kernel, true));

container.Register(Component.For<IPrinter>()
                            .ImplementedBy<ModifyingPrinter>()
                            .LifestyleTransient());
container.Register(Component.For<IPrinter>()
                            .ImplementedBy<Printer1>());
container.Register(Component.For<IPrinter>()
                            .ImplementedBy<Printer2>());

container.Register(Component.For<Service>());
温莎的
CollectionResolver
似乎提供了
IPrinter
的所有实现中的一个(这是可以理解的),而不是认识到
ModifyingPrinter
是一个装饰器,并使用它包装其他两个实现

我的问题:是否有办法注册这些类,以便集合只包含修饰的基本实现


我在某个地方的另一篇帖子中读到,我可以创建一个拦截器,并用拦截器注册
Printer1
Printer2
,但如果可以,我希望保持装饰器模式。

我看到了两种实现预期结果的方法:

  • 使用a并将
    Print
    方法包装到装饰行为中。这感觉像是一种逻辑行为,因为您可能不想创建一个没有预期行为的
    IPrinter
    ,而是一种装饰行为
  • 使用在预期打印机周围新建装饰打印机的方法来解析iPrinter。我担心这可能有点复杂,因为如果你想从基于约定的配置中获益,你必须过滤掉装饰器。但它应该能满足你的需要

事实证明,卡斯尔。温莎不能做我想做的事。我尝试创建一个新的解析器来处理这个场景,但没有走多远

最后,我重组了一个真正的工厂来装饰班级

class PrinterModifierFactory : IPrinterModifierFactory
{
    private Func<IPrinter, IPrinter> _decorate;
    private IEnumerable<IPrinter> _printers;

    public PrinterModifierFactory(Func<IPrinter, IPrinter> decorate,
                                  IEnumerable<IPrinter> printers)
    {
        _decorate = decorate;
        _printers = printers;
    }

    public IEnumerable<IPrinter> GetAll()
    {
        return _printers.Select(_decorate);
    }
}
答案是在我的架构中更加明确

Modified Printer1
Printer1
Printer2
class PrinterModifierFactory : IPrinterModifierFactory
{
    private Func<IPrinter, IPrinter> _decorate;
    private IEnumerable<IPrinter> _printers;

    public PrinterModifierFactory(Func<IPrinter, IPrinter> decorate,
                                  IEnumerable<IPrinter> printers)
    {
        _decorate = decorate;
        _printers = printers;
    }

    public IEnumerable<IPrinter> GetAll()
    {
        return _printers.Select(_decorate);
    }
}
class Service
{
    private readonly IEnumerable<IPrinter> _printers;
    private IPrinterModifierFactory factory;

    public Service(IPrinterModifierFactory factory)
    {
        _factory = factory;
    }

    public void Print()
    {
        _Initialize();

        foreach (var printer in _printers)
        {
            printer.Print();
        }
    }

    void _Initialize()
    {
        if (_printers != null) return;

        _printers = factory.GetAll().ToList();
    }
}
container.Register(Component.For<IPrinterModifierFactory>()
                            .ImplementedBy<PrinterModifierFactory>());
Func<IPrinter, IPrinter> decorator = p => new ModifyingPrinter(p);
container.Register(Component.For<Func<IPrinter, IPrinter>>()
                            .Instance(decorator));