Строковый выбор строго необходим? Можно ли вместо этого, чтобы все реализации IView в одной и той же «области» реализовали выделенный интерфейс, производный от IView? Затем вы можете использовать WindsorContainer.ResolveAll () (передав свой региональный IView как T) для разрешения реализаций для рассматриваемого региона (или вы можете использовать один из преобразователей коллекции для выполнения внедрения конструктора).
В общем, пытаясь сделать что-то подобное с Виндзором, я прилагаю все усилия, чтобы использовать систему типов (и ее поддержку Виндзор), прежде чем прибегать к решениям на основе строк.
Обновление: поскольку мы подтвердили, что в этом случае необходим выбор по строке, лучшее решение, которое я вижу, - это просто проверить список обработчиков в ядре, удовлетворяющих службе IView, а затем отфильтровать исполнителей, где регион (определенный с помощью атрибута) соответствует тому, что мы хотим, а затем разрешите этих разработчиков. Это кажется немного хакерским, но если вы согласны с прямой ссылкой на контейнер в вашей реализации IViewFactory, это, похоже, работает нормально. Ниже приведен успешный тестовый пример, демонстрирующий решение.
[Test]
public void Test()
{
using (var factory = new ViewFactory())
{
var regionOneViews = factory.GetAllViewsInRegion("One");
Assert.That(regionOneViews, Is.Not.Null);
Assert.That(regionOneViews, Has.Length.EqualTo(2));
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneA>());
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneB>());
var regionTwoViews = factory.GetAllViewsInRegion("Two");
Assert.That(regionTwoViews, Is.Not.Null);
Assert.That(regionTwoViews, Has.Length.EqualTo(1));
Assert.That(regionTwoViews, Has.Some.TypeOf<RegionTwoA>());
}
}
}
public interface IViewFactory
{
IView[] GetAllViewsInRegion(string regionName);
}
public class ViewFactory : IViewFactory, IDisposable
{
private readonly WindsorContainer _container;
public ViewFactory()
{
_container = new WindsorContainer();
_container.Register(
Component.For<IView>().ImplementedBy<RegionOneA>(),
Component.For<IView>().ImplementedBy<RegionOneB>(),
Component.For<IView>().ImplementedBy<RegionTwoA>()
);
}
public IView[] GetAllViewsInRegion(string regionName)
{
return _container.Kernel.GetHandlers(typeof (IView))
.Where(h => IsInRegion(h.ComponentModel.Implementation, regionName))
.Select(h => _container.Kernel.Resolve(h.ComponentModel.Name, typeof (IView)) as IView)
.ToArray();
}
private bool IsInRegion(Type implementation,
string regionName)
{
var attr =
implementation.GetCustomAttributes(typeof (RegionAttribute), false).SingleOrDefault() as RegionAttribute;
return attr != null && attr.Name == regionName;
}
public void Dispose()
{
_container.Dispose();
}
}
public interface IView {}
[Region("One")]
public class RegionOneA : IView {}
[Region("One")]
public class RegionOneB : IView {}
[Region("Two")]
public class RegionTwoA : IView {}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RegionAttribute : Attribute
{
private readonly string _name;
public RegionAttribute(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
}
}
person
Stuart Lange
schedule
27.02.2012