Подтвердить что ты не робот

Разрешение классов без регистрации их с помощью Castle Windsor

Возьмите следующую бесполезную программу:

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer unityContainer = new UnityContainer();
        IWindsorContainer windsorContainer = new WindsorContainer();

        Program unityProgram = unityContainer.Resolve<Program>();
        Program castleProgram = windsorContainer.Resolve<Program>();
    }
}

UnityContainer вернет мне экземпляр программы, где, поскольку контейнер Windsor будет вызывать исключение ComponentNotFoundException.

Я могу видеть аргументы для обоих типов поведения и не возражаю против того, что у меня получится, однако Prism V2 Drop 8 (последний на момент написания) полагается на поведение Unity внутри, запрашивая классы, которые не были зарегистрированы.

Вместо того, чтобы находить и регистрировать все эти классы для Prism, я бы скорее просто заставил Windsor вести себя как Unity. Я ничего не нашел в google, чтобы помочь мне сделать это (хотя моя терминология может быть неправильной), а документация Windsor довольно плохая...

Может ли кто-нибудь предложить решение этой проблемы?

4b9b3361

Ответ 1

Windsor в настоящее время не поддерживает это, и он по дизайну. Причиной является то, что вы должны явно регистрировать типы, которые вам нужны, чтобы вы не получили неправильно сконфигурированный объект.

Однако есть вероятность, что в ближайшем будущем в какой-то момент будет добавлен крючок для создания незарегистрированного типа, поскольку это необходимо для интеграции интеграции WCF. (Edit - добавлено в v2.1 - посмотрите ILazyComponentLoader s)

В любом случае, независимо от ленивых загрузчиков компонентов, лучше всего использовать свободный API для пакетного регистрации всех типов из сборки, соответствующей вашим необходимым критериям. Это не намного больше кода, и вы будете лучше спать по ночам.

Используйте ленивые загрузчики, только если у вас действительно недостаточно информации при запуске (в корне вашего состава), чтобы определить, какие компоненты вам понадобятся.

Ответ 2

Windsor не поддерживает это из коробки, но вы можете создавать методы расширения для этого:

static class WindsorExtensions
{
    public static object ResolveType(this IWindsorContainer container, Type type)
    {
        if ( type.IsClass && !container.Kernel.HasComponent(type) )
            container.Kernel.AddComponent(type.FullName, type, LifestyleType.Transient);
        return container.Resolve(type);
     }

     public static T ResolveType<T>(this IWindsorContainer container)
     { return (T)ResolveType(container, typeof(T)); }
}

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer unityContainer = new UnityContainer();
        IWindsorContainer windsorContainer = new WindsorContainer();

        Program unityProgram = unityContainer.Resolve<Program>();
        Program castleProgram = windsorContainer.ResolveType<Program>();
    }
}

Ответ 3

Krzysztof не бойтесь ссылаться на свой собственный блог здесь. http://devlicious.com/blogs/krzysztof_kozmic/archive/2009/11/16/castle-windsor-lazy-loading.aspx

Кроме того, я нашел эту простую реализацию полезной в моем приложении WPF, удалите строковое ограничение и вы близки к общему случаю

public class ViewModelLoader : Castle.MicroKernel.Resolvers.ILazyComponentLoader {
    public IRegistration Load(string key, Type service)
    {
        if (service == null)
            return null;
        if (service.Name.EndsWith("ViewModel", StringComparison.CurrentCultureIgnoreCase))
            return Component.For(service).Named(key);
        else
            return null;
    }
}