Как заставить GetObjectsOfType искать объекты, определенные в xml-файле настроек контейнера? - CodeHelper

Как заставить GetObjectsOfType искать объекты, определенные в xml-файле настроек контейнера?

1

Вот создаем контекст:

var cxt = ContextRegistry.GetContext();
GenericApplicationContext context = new GenericApplicationContext(cxt);

При этом у нас в xml-настройках определено несколько объектов. Все они отлично просматриваются в объекте cxt.ObjectFactory и соответственно в context.ParentContext.ObjectFactory. Предположим, что после этого мы воспользуемся методом GenericApplicationContext.RegisterObjectDefinition для регистрации нового объекта в контейнере. Он уже попадает в context.ObjectFactory, а не в context.ParentContext.ObjectFactory.

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

var objects = context.GetObjectsOfType(serviceType).Values;

В итоге оказалось, что подобным образом можно получить только объекты из context.ObjectFactory. Т.е., если искомые объекты были описаны в xml-файле настроек контейнера, то они попадут в context.ParentContext.ObjectFactory и не будут найдены данным методом.

Да, наверняка можно эти объекты можно как-то получить, но к сожалению я ограничен методом GetObjectsOfType. Товарище разработчике, как же заставить его искать определенные в xml объекты?

Новые ответы


0

В общем, такой поиск может выглядеть так:

public static class ExtensionMethods
{
    private static void GetAllInstancesRecursive(IApplicationContext context,
                                                 Type serviceType,
                                                 ref ICollection<object> result)
    {
        if (context == null) return;

        foreach (object o in context.GetObjectsOfType(serviceType).Values)
        {
            result.Add(o);
        }

        GetAllInstancesRecursive(context.ParentContext, serviceType, ref result);
    } 

    public static IEnumerable<object> GetObjectsOfTypeRecursive(this IApplicationContext context, 
                                                                     Type serviceType)
    {
        ICollection<object> result = new Collection<object>();
        GetAllInstancesRecursive(context, serviceType, ref result);
        return result;
    }
}
0

Можно получить их в два этапа — сначала из самого контекста, потом из родительского:

var objects = context.GetObjectsOfType(serviceType).Values;
var objectsFromParent = context.ParentContext.GetObjectsOfType(serviceType).Values;

Можно вообще не использовать иерархию контекстов. То есть создать только GenericApplicationContext и тогда все объекты будут объявлены только в нем. При этом сам контекст будет заполняться как-то так:

GenericApplicationContext ctx = new GenericApplicationContext();
XmlObjectDefinitionReader reader = new XmlObjectDefinitionReader(ctx);
reader.LoadObjectDefinitions("assembly://Spring.Core.Tests/Spring.Context.Support/contextB.xml");
reader.LoadObjectDefinitions("assembly://Spring.Core.Tests/Spring.Context.Support/contextC.xml");
reader.LoadObjectDefinitions("assembly://Spring.Core.Tests/Spring.Context.Support/contextA.xml");
ctx.Refresh();
//..
// И дальше собственные объявления
GenericApplicationContext.RegisterObjectDefinition(/*...*/);
0

Наверное никак. В общем-то все логично. ParentContext заполняется из xml, а регистрация из кода идет непосредственно в GenericApplicationContext, который является контейнером сам по себе. Так что метод GetObjectsOfType ищет только там, где он вызван.

Хотя... с другой стороны данный метод определен в классе AbstractApplicationContext, где определено так же и свойство ParentContext. Почему бы этому методу не искать рекурсивно во всех ParentContext'ах?

Или все же возможно сконфигурировать контейнер для такого поиска?


v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.