Как зарегистрировать декоратор, чтобы иметь возможность разрешить decoree - PullRequest
0 голосов
/ 24 октября 2018

Я использую Autofac.Я пытаюсь зарегистрировать 2 класса с одним и тем же интерфейсом, используя шаблон декоратора.

public interface IDoable
{
    string Do();
}

public class Decoree : IDoable
{
    public string Do()
    {
        return "decoree";
    }
}

public class Decorator : IDoable
{
    public IDoable InnerDecoree { get; set; }

    public Decorator(IDoable doable)
    {
        this.InnerDecoree = doable;
    }

    public string Do()
    {
        return InnerDecoree.Do() + "decorator";
    }
}

Я хотел бы использовать контейнер для разрешения двух типов для 2 разных случаев:

  • IDoable, где я ожидаю, что этот экземпляр будет экземпляром Decorator
  • и для конкретного Decoree, где мне действительно нужно разрешить конкретный Decoreeэкземпляр.

Единственный способ, которым я могу достичь этого, - использовать следующий код:

[Fact]
public void Both()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<Decoree>()
           .Named<IDoable>("decoree")
           .SingleInstance();

    builder.RegisterType<Decoree>() // but this is not right I'd like to register it on line above somehow...
        .AsSelf()
        .SingleInstance(); 

    builder.RegisterType<Decorator>()
           .Named<IDoable>("decorator")
           .SingleInstance();

    builder.RegisterDecorator<IDoable>(
            (c, inner) => c.ResolveNamed<IDoable>("decorator", TypedParameter.From(inner)), "decoree")
            .As<IDoable>();

    var container = builder.Build();

    Assert.IsType<Decoree>(container.Resolve<Decoree>());
    Assert.False(container.IsRegistered<Decorator>());
    Assert.IsType<Decorator>(container.Resolve<IDoable>());


    var decoree = container.Resolve<Decoree>();
    var decorator = container.Resolve<IDoable>();
    var doable = ((Decorator)decorator).InnerDecoree;

    Assert.Same(decoree, doable); // FALSE :(

}

Дело в том, что я бы очень хотел, чтобы последнийутверждение, чтобы быть правдой :) так что это тот же самый экземпляр.

В основном мой вопрос таков: возможно ли зарегистрировать тип в обоих направлениях, используя с именами и type ?

1 Ответ

0 голосов
/ 24 октября 2018

Поскольку вы не указываете область в своей регистрации, вы получаете различный экземпляр Decoree каждый раз, когда он разрешается.Я бы попробовал что-то вроде

builder.RegisterType<Decoree>()
       .Named<IDoable>("decoree").SingleInstance();

Кроме того, вам может понадобиться объединить две ваши регистрации типа Decoree:

builder.RegisterType<Decoree>()
       .Named<IDoable>("decoree")
       .AsSelf()
       .SingleInstance();
...