Получаете ли вы 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>();
Обратите внимание, что это будет работать только в том случае, если вы извлекаете представление с помощью прямого вызова контейнера (расположение службы), поскольку это зависит от "Root.RequestedType". В зависимости от того, как вы планируете получать свои представления, вы можете пройтись по BuildStack в поисках View (вместо того, чтобы предполагать, что это всегда Root).