Авторегистрация типов в IoC контейнере
От: Аноним  
Дата: 08.10.09 04:55
Оценка:
Для начала для тех кто не знаком с темой — есть контейнер, можно все перечислить руками и вызвать регистрацию для типов явным образом — container.Register<...>(...), а можно задав некие правила (convention over configuration) осуществить авторегистрацию типов.
В разных контейнерах это если реализовано вообще, то по разному. Где-то (по ссылкам см. примеры кода конфигурации авторегистрации) хуже как например в Castle, где-то более удачно, как например в Structure Map или в этом расширении Unity). Некоторые контейнеры не поддерживают авторегистрации вообще.

С одной стороны авторегистрация выглядит хорошо — т.к. с меньшим количеством кода можно зарегистрировать все типы которые нужны (или как-то отмечены — например аттрибутами итд) без явного перечисления этих типов (что особенно хорошо когда bootstrapper с кодом регистрации не знает ничего о конечных типах — только о интерфейсах, типы динамически загружаются из внешней сборки например).
С другой стороны, как и любая конвеция авторегистрация делает неявно то, что на момент написания конфигурационных правил было ок, а завтра стало приводить к ошибкам в результате появления новых типов удовлетворяющих описанной конвенции, но не планируемые разработчиком к регистрации например, итд.


Итак, авторегистрация — good or evil?
Re: Авторегистрация типов в IoC контейнере
От: gimalay  
Дата: 08.10.09 09:37
Оценка: +1
А>Итак, авторегистрация — good or evil?

Evil!

Главное в DI не увлекаться до той степени когда нужна авторегистрация....

Как мне кажеться
Re: Авторегистрация типов в IoC контейнере
От: akarinsky Россия  
Дата: 08.10.09 11:43
Оценка:
Зла особого пока не наблюдал. Гибкость слегка понижается, особенно при тестировании, но решается тем не менее легко.
IoC-контейнер самодельный, но принцип неизменен.

        [Test]
        public void RegisterServiceByMetadataServiceImplementation()
        {
            var types = new List<Type> {typeof (PrintingServiceImpl1)};
            var configurator = new MetadataServiceRegistryConfigurator(types);

            var registry = new ServiceRegistry(configurator);

            var service = registry.GetService<IPrintingService>();

            Assert.IsNotNull(service);
        }


А так выглядит имплементация нашего сервиса:

    internal class PrintingServiceImpl1 : IPrintingService, IPrintSettingsService, IDisposable
    {
        [ServiceDependency]
        public IPrintSettingsService Settings { get; set; }

        public void Print(string text)
        {
            throw new NotImplementedException();
        }            
    }


Довольно удобно, согласитесь.
На опушке за околицей мужики строили коровник.
Работали споро и весело. Получалось х**во.
Re[2]: Авторегистрация типов в IoC контейнере
От: akarinsky Россия  
Дата: 08.10.09 21:32
Оценка:
Ой, лопухнулся слегка. Вот так выглядит имплементация сервиса

    [ServiceImpl(typeof(IPrintingService))]
    internal class PrintingServiceImpl1 : IPrintingService
    {
        [ServiceDependency]
        public IPrintSettingsService Settings { get; set; }

        public void Print(string text)
        {
            throw new NotImplementedException();
        }            
    }



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

[ServiceImpl(typeof(IPrintingService), "test")]
На опушке за околицей мужики строили коровник.
Работали споро и весело. Получалось х**во.
Re: Авторегистрация типов в IoC контейнере
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 08.10.09 23:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Итак, авторегистрация — good or evil?


Я в своём расширении к Unity
Автор: koandrew
Дата: 17.08.09
подхожу к вопросу, так сказать, с противоположной стороны — выясняю, можно ли разрулить зависимость непосредственно в момент запроса на неё. Это избавляет от необходимости бегать по либам и регистрировать типы (что очень небыстро и способно сильно увеличить время загрузки), и отложить принятие решения о том, какой тип будет создан, до момента, когда он реально понадобится. Накладные расходы на матчинг по правилам легко нивелируются кэшированием результатов лукапа + динамическими методами для создания, позволяет реализовать поддержку нестандартных способов создания объекта (к примеру, фабрики) и передать туда какую-либо контекстную информацию, неизвестную на момент регистрации. К тому же, возможности такого подхода куда выше...
[КУ] оккупировала армия.
Re[2]: Авторегистрация типов в IoC контейнере
От: Аноним  
Дата: 09.10.09 02:25
Оценка:
K>Я в своём расширении к Unity
Автор: koandrew
Дата: 17.08.09
подхожу к вопросу, так сказать, с противоположной стороны — выясняю, можно ли разрулить зависимость непосредственно в момент запроса на неё. Это избавляет от необходимости бегать по либам и регистрировать типы (что очень небыстро и способно сильно увеличить время загрузки), и отложить принятие решения о том, какой тип будет создан, до момента, когда он реально понадобится. Накладные расходы на матчинг по правилам легко нивелируются кэшированием результатов лукапа + динамическими методами для создания, позволяет реализовать поддержку нестандартных способов создания объекта (к примеру, фабрики) и передать туда какую-либо контекстную информацию, неизвестную на момент регистрации. К тому же, возможности такого подхода куда выше...


А кто выбирает LifetimeManager с которым будет зарегистрирован запрашиваемый тип (и в общем случае все его зависимости)? Если вызывающий код, то это не хорошо.
Как происходит ресолвинг именованых регистраций: container.Resolve<IEmailService>("Smtp")?
Re[3]: Авторегистрация типов в IoC контейнере
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 09.10.09 05:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А кто выбирает LifetimeManager с которым будет зарегистрирован запрашиваемый тип (и в общем случае все его зависимости)? Если вызывающий код, то это не хорошо.

Нет никакой проблемы реализовать некую систему правил, которые будут вычисляться в момент создания объекта и определять LifetimeManager.

А>Как происходит ресолвинг именованых регистраций: container.Resolve<IEmailService>("Smtp")?

Концептуально так.
[КУ] оккупировала армия.
Re[4]: Авторегистрация типов в IoC контейнере
От: Аноним  
Дата: 11.10.09 22:38
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, Аноним, Вы писали:


А>>А кто выбирает LifetimeManager с которым будет зарегистрирован запрашиваемый тип (и в общем случае все его зависимости)? Если вызывающий код, то это не хорошо.

K>Нет никакой проблемы реализовать некую систему правил, которые будут вычисляться в момент создания объекта и определять LifetimeManager.

А где будут задаваться эти правила?

А>>Как происходит ресолвинг именованых регистраций: container.Resolve<IEmailService>("Smtp")?

K>Концептуально так.
Ну так как это для вашего подхода происходит/будет происходить? Вот есть у меня IEmailService и реализации: EmailService1 и EmailService2.
Если я регистрирую все заранее (явно или авторегистрацией), то могу проименовать регистрации так, что по container.Resolve<IEmailService>("Smtp") будет резолвиться EmailService1, а по container.Resolve<IEmailService>("Pop3") — EmailService2.

В общем, с "некой системой правил" задаваемой и выполняющейся там где в классическом случае выполняется явная регистрация/авторегистрация ваш подход может быть и может существовать. Но по моему он добавляет еще больше неявности чем авторегистрация, т.к. еще больше скрывает конвенцию.
Re[5]: Авторегистрация типов в IoC контейнере
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 12.10.09 01:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А где будут задаваться эти правила?

Где только фантазии хватит

А>Ну так как это для вашего подхода происходит/будет происходить? Вот есть у меня IEmailService и реализации: EmailService1 и EmailService2.

А>Если я регистрирую все заранее (явно или авторегистрацией), то могу проименовать регистрации так, что по container.Resolve<IEmailService>("Smtp") будет резолвиться EmailService1, а по container.Resolve<IEmailService>("Pop3") — EmailService2.

Нет никаких проблем сделать так же.

А>В общем, с "некой системой правил" задаваемой и выполняющейся там где в классическом случае выполняется явная регистрация/авторегистрация ваш подход может быть и может существовать. Но по моему он добавляет еще больше неявности чем авторегистрация, т.к. еще больше скрывает конвенцию.

Конвенция абсолютно идентична.

Вы, видимо, не вполне понимаете, о чём это я. При моём подходе можно сделать 100% того, что может сделать авторегистрация, плюс ещё многое из того, что авторегистрация сделать не может. Например, при запросе объекта доступна контекстная информация (вплоть до стека вызова), на основании которой можно принимать какие-то решения относительно создания объекта, можно на лету сгенерировать прокси и подсунуть его вместо запрашиваемого объекта, и многое другое...
[КУ] оккупировала армия.
Re: Авторегистрация типов в IoC контейнере
От: Keith  
Дата: 19.10.09 12:03
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Итак, авторегистрация — good or evil?


Смотря с какими целями — все можно, если осторожно
Я вот сейчас думаю сделать авторегистрацию классов разных слоев приложения, чтобы при добавлении не забывать добавлять руками регистрацию. Т.е. есть набор DAO классов для каждой entity, есть набор сервисов для каждой entity, есть набор презентеров для каждого окна. Каждый набор классов лежит в своем неймспейсе. Мне было бы удобно регистрировать их автоматически по неймспейсу и никаких негативных последствий я не вижу, кроме как некоторую "магичность" и возможное затруднение у разработчика, который может после меня поддерживать такой код, но это маловероятно в моем случае, а против "магичности" я ничего не имею, если она практична

ps Прошу прощения что поднимаю тему не первой свежести, просто сейчас столкнулся с аналогичным вопросом в текущем проекте.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Авторегистрация типов в IoC контейнере
От: Аноним  
Дата: 31.10.09 07:52
Оценка:
K> Смотря с какими целями — все можно, если осторожно
K> Я вот сейчас думаю сделать авторегистрацию классов разных слоев приложения, чтобы при добавлении не забывать добавлять руками регистрацию. Т.е. есть набор DAO классов для каждой entity, есть набор сервисов для каждой entity, есть набор презентеров для каждого окна. Каждый набор классов лежит в своем неймспейсе. Мне было бы удобно регистрировать их автоматически по неймспейсу и никаких негативных последствий я не вижу, кроме как некоторую "магичность" и возможное затруднение у разработчика, который может после меня поддерживать такой код, но это маловероятно в моем случае, а против "магичности" я ничего не имею, если она практична

А каким контейнером вы пользуетесь?
Re[2]: Авторегистрация типов в IoC контейнере
От: dotidot Россия  
Дата: 31.10.09 09:21
Оценка:
Здравствуйте, Keith, Вы писали:
K> а против "магичности" я ничего не имею, если она практична
магичность легко убирается аннотацией класса например @AutoRegister с соответсвующей докой (ну в дотнете [AutoRegister] или как то так )
Причем если забыть такую штуку, то контейнер сможет ругнутся, в отличие если просто в доке это указывать
Re[3]: Авторегистрация типов в IoC контейнере
От: Keith  
Дата: 04.11.09 14:56
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>А каким контейнером вы пользуетесь?


Какая разница каким контейнером пользуюсь именно я?
Но раз уж спросили, то Spring.NET.
Если нужен только контейнер, то многие считают, что Spring.NET слишком "тяжел" и предлагают Unity Application Block.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.