2009-10-27 2 views
0

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

class MyView 
{ 
    IPrompt prompt 
} 

class GenericPrompt : IPrompt 
{ 
    IValidator validator 
} 

class MyValidator : IValidator 
{ 
    bool Validate() {} 
} 

Как настроить StructureMap с DSL реестра, чтобы использовать только MyValidator при создании зависимостей для MyView. (И предположительно, используя BobsValidator при создании зависимостей для BobsView)

+0

Имеет ли BobsView также зависимость от IPrompt? Если нет, у вас нет проблем. Если это так, вы можете посмотреть в профилях. – KevM

ответ

1

Вы получаете MyView (и BobsView) из контейнера? Можем ли мы предположить, что все они возьмут экземпляр IPrompt?

Один из подходов - зарегистрировать все ваши валидаторы с именем, которое соответствует названиям вашего представления. Вы могли бы реализовать свой собственный сканер типа, который просто удаляет Validator суффикса:

public class ValidatorScanner : ITypeScanner 
{ 
    public void Process(Type type, PluginGraph graph) 
    { 
     if (!typeof (IValidator).IsAssignableFrom(type)) return; 
     var validatorName = type.Name.Replace("Validator", ""); 
     graph.AddType(typeof(IValidator), type, validatorName); 
    } 
} 

Теперь, если вы допускаете IPrompt всегда запрашиваться мнением, что следует, что соглашение об именах, реестр может выглядеть следующим образом:

public class ValidatorRegistry : Registry 
{ 
    public ValidatorRegistry() 
    { 
     Scan(scan => 
     { 
      scan.TheCallingAssembly(); 
      scan.With<ValidatorScanner>(); 
     }); 

     ForRequestedType<IPrompt>().TheDefault.Is.ConstructedBy(ctx => 
     { 
      var viewName = ctx.Root.RequestedType.Name.Replace("View", ""); 
      ctx.RegisterDefault(typeof(IValidator), ctx.GetInstance<IValidator>(viewName)); 
      return ctx.GetInstance<GenericPrompt>(); 
     }); 
    } 
} 

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

var view = container.GetInstance<MyView>(); 

Обратите внимание, что это будет работать только если вы retri вызывая свое мнение с помощью прямого вызова контейнера (местоположение службы), поскольку он зависит от «Root.RequestedType». В зависимости от того, как вы планируете получать свои взгляды, вы можете подойти к BuildStack, ищущему представление (вместо того, чтобы предполагать, что это всегда Root).

+0

Спасибо. Это привело меня к тому, что мне нужно. Любая подсказка, почему intellisense на ctx не работает? – JoshRivers

Смежные вопросы