Отменить условное связывание на основе значения свойства - PullRequest
5 голосов
/ 28 марта 2011

У меня проблемы с определением привязок с помощью ninject.

Я нахожусь в стандартном приложении ASP.NET WebForms. Я определил обработчик http для вставки зависимостей в страницы и элементы управления (внедрение свойства).

Вот что я пытаюсь сделать:

Я создаю пользовательский контроль пользователя в выпадающем списке. Основываясь на значении перечисления в этом выпадающем списке, я хочу иметь возможность вставлять другой объект в свойство (то, что я пытаюсь сделать, немного сложнее, но ответа на это должно быть достаточно, чтобы заставить меня работать ).

Ответы [ 2 ]

10 голосов
/ 29 марта 2011

Условное связывание, основанное на значении свойства, не является хорошим проектом и даже невозможно (по крайней мере, для внедрения в конструктор), поскольку зависимости обычно создаются до того, как объект их получает. Что если собственность будет изменена позже? Предпочтительный способ - внедрить фабричный или фабричный метод, который запрашивает экземпляр у Ninject, и обменяться стратегией при инициализации и изменении значения свойства внутри.

public enum EntityType { A,B } 
public class MyControl : UserControl
{
    [Inject]
    public Func<EntityType, IMyEntityDisplayStrategy> DisplayStrategyFactory 
    { 
        get { return this.factory; }
        set { this.factory = value; this.UpdateEntityDisplayStrategy(); }
    }

    public EntityType Type 
    { 
        get { return this.type; } 
        set { this.type = value; this.UpdateEntityDisplayStrategy(); };
    }

    private UpdateEntityDisplayStrategy()
    {
        if (this.DisplayStrategyFactory != null)
            this.entityDisplayStrategy = this.DisplayStrategyFactory(this.type);
    }
}

Bind<Func<EntityType, IMyEntityDisplayStrategy>>
    .ToMethod(ctx => type => 
         type == ctx.kernel.Get<IMyEntityDisplayStrategy>( m => 
             m.Get("EntityType", EntityType.A));
Bind<IMyEntityDisplayStrategy>.To<AEntityDisplayStrategy>()
    .WithMetadata("EntityType", EntityType.A)
Bind<IMyEntityDisplayStrategy>.To<BEntityDisplayStrategy>()
    .WithMetadata("EntityType", EntityType.B)

Или добавьте действие активации и введите зависимость вручную. Но имейте в виду, что изменение свойства ограничения приведет к несовместимому состоянию.

OnActivation((ctx, instance) => 
    instance.MyStrategy = ctx.Kernel.Get<MyDependency>(m => 
        m.Get("MyConstraint", null) == instance.MyConstraint);
0 голосов
/ 02 мая 2014

То, что я использую (с Ninject 3 сейчас), немного отличается, но оно работает для меня. Я создаю массив зависимостей и позволяю им решать, принимают ли они обрабатывать запрос или нет. Например, если бы у меня был этот случай

public enum FileFormat
{
    Pdf,
    Word,
    Excel,
    Text,
    Tex,
    Html
}

public interface IFileWriter
{
    bool Supports(FileFormat format)

    ...
}

public class FileProcessor
{
    FileProcessor(IFileWriter[] writers)
    {
        // build a dictionary with writers accepting different formats 
        // and choose them when needed
    }
}

public class MyModule : NinjectModule
{
     public override void Load()
     {
         ...

         Bind<IFileWriter>().To<PdfFileWriter>();
         Bind<IFileWriter>().To<WordFileWriter>();
         Bind<IFileWriter>().To<TexFileWriter>();
         Bind<IFileWriter>().To<TextFileWriter>();
         Bind<IFileWriter>().To<HtmlFileWriter>();
     }
}

Надеюсь, это поможет!

...