Отменить условное связывание на основе значения свойства
У меня проблемы с определением привязок с помощью ninject.
Я нахожусь в стандартном приложении ASP.NET WebForms. Я определил обработчик http для вставки зависимостей в страницы и элементы управления (внедрение свойства).
Вот что я пытаюсь сделать:
Я создаю пользовательский пользовательский контроль combobox. Основываясь на значении перечисления в этом комбинированном ящике, я хочу иметь возможность вставлять другой объект в свойство (то, что я пытаюсь сделать, немного сложнее, но ответа на это должно быть достаточно, чтобы заставить меня работать).
2 ответа
Условное связывание, основанное на значении свойства, не является хорошим проектом и даже невозможно (по крайней мере, для внедрения в конструктор), поскольку зависимости обычно создаются до того, как объект их получает. Что если свойство будет изменено позже? Предпочтительный способ - внедрить фабричный или фабричный метод, который запрашивает экземпляр у 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);
То, что я использую (с 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>();
}
}
Надеюсь, это поможет!