В относительно простом приложении (т.е. IoC не предлагать), к примеру если написать
internal class Program {
static public typename var = new typename();
static internal void Main(string[] args) {
...
}
}
}
Чем это вредно? К примеру, в серверной части распределенного приложения, почему бы не организовать таким образом мапперы? Какие альтернативы?
P.S. Ногами не бить
P.P.S. Большая просьба — не начинать опять спорить, почему "вот так нельзя", а то опять переростет в выяснение отношений. Скажите, как бы вы сделали в подобной ситуации?
Здравствуйте, Ivan Danilov, Вы писали:
ID>Начал читать рядом про Singleton... ниасилил
ID>В относительно простом приложении (т.е. IoC не предлагать), к примеру если написать
[cut]
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, Ivan Danilov, Вы писали:
ID>>Начал читать рядом про Singleton... ниасилил
ID>>В относительно простом приложении (т.е. IoC не предлагать), к примеру если написать К>[cut]
К>Относительно простое — это сколько строк? 10, 20?
Здравствуйте, Ivan Danilov, Вы писали:
ID>Начал читать рядом про Singleton... ниасилил ID>В относительно простом приложении (т.е. IoC не предлагать), к примеру если написать
IoC не такой страшный как кажется Попробуйте, вдруг, понравится
ID>
ID> internal class Program {
ID> static public typename var = new typename();
ID> static internal void Main(string[] args) {
ID> ...
ID> }
ID> }
ID>}
ID>
ID>Чем это вредно? К примеру, в серверной части распределенного приложения, почему бы не организовать таким образом мапперы? Какие альтернативы?
Если посмотреть на .NET то, там куча вещей реализована с подобным подходом. Например, классы Roles и Membership работают только с default провайдером. Про генерируемые классы сеттингов — тут лучше вообще молчать
ID>P.P.S. Большая просьба — не начинать опять спорить, почему "вот так нельзя", а то опять переростет в выяснение отношений. Скажите, как бы вы сделали в подобной ситуации?
Если приложение простое, а слишком сильно заморачиваться не хочется... то, сделайте утилитный класс typenameFactory с методом getTypenameInstance — никто вам про этот Singleton и не вспомнит или следуйте по аналогии с Roles и Membership.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, Ivan Danilov, Вы писали:
ID>>Ну пусть будет до 100 Кб сорцов
К>Оригинально, и для такого проекта IoC тебе кажется сильно накладным подходом? К>Можешь раскрыть мысль почему?
Немного про общую архитектуру сервера.
0. Отдельная сборка Protocol, содержащая интерфейсы для взаимодействия с клиентом и вспомогательные сериализуемые классы, которые передаются по сети.
1. Слой Services, который содержит классы, открываемые через Remoting пользователю. Через этот слой клиент логинится, делает запросы, получает ответы итп. Фактически служит барьером между безопасными вызовами и "непроверенными". Оперирует объектами из Protocol.
2. Для реализации функциональности после проверки валидности сервисы обращаются к слою Controllers. В этом слое находятся классы, реализующие бизнес-логику, т.е. они активно общаются с Business Entities и Data Access Components.
3. Business Entities — фактически, классы содержат набор полей и свойств. Больше там ничего нет. Для удобства взаимодействия с БД, все классы реализуют интерфейс IBusinessEntity, определяющий поле ID.
4. Data Access Components — получение/сохранение данных из/в БД и кэширование.
Так вот мне не понятно, зачем реализовывать IoC и запихивать в каждый контроллер возможность задавать DAC, если они даже не предвидятся для изменения? С статической public переменной (фактически, глобальной) все выглядит проще и удобнее...
Чтобы не возникало недоразумений по поводу терминологии, под IoC я понимаю то, что написано здесь
К>Юнит-тестов и моков в проекте нет?
Есть юнит-тесты, но пока немного. Моки отсутствуют.
Здравствуйте, TK, Вы писали:
TK>IoC не такой страшный как кажется Попробуйте, вдруг, понравится
Может быть, я плохо понимаю, что такое IoC — но хоть убейте, не вижу, к каким преимуществам в данном случае эта технология приведет, кроме небольшого увеличения кода...
Здравствуйте, Ivan Danilov, Вы писали:
ID>Так вот мне не понятно, зачем реализовывать IoC и запихивать в каждый контроллер возможность задавать DAC, если они даже не предвидятся для изменения? С статической public переменной (фактически, глобальной) все выглядит проще и удобнее...
Похоже, то небольшое количество юнит-тестов не тестируют контроллеры, ибо я себе слабо представляю, как можно протестировать такой вот код:
public static class DataAccess
{
public static WhateverDataAccessObject WhateverDataAccessObject = new WhateverDataAccessObject();
}
public class WhateverController : Controller
{
public Foo CalculateFoo()
{
return DataAccess.WhateverDataAccessObject.GetFoo() * 5;
}
}
не имея под рукой готовой БД со всем необходимыми данными. Аргумент?
Вас, само собой, никто IoC не заставляет использовать -- помилуйте. Однако же с ним гораздо удобнее, чем с глобальной переменной (или каким-то синглтоном).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
HgLab: Mercurial Server and Repository Management for Windows
Здравствуйте, Нахлобуч, Вы писали:
Н>Похоже, то небольшое количество юнит-тестов не тестируют контроллеры, ибо я себе слабо представляю, как можно протестировать такой вот код:
Н>
H><skipped>
Н>
Н>не имея под рукой готовой БД со всем необходимыми данными. Аргумент?
Хм. Подставить мок и вправду будет трудно...
Н>Вас, само собой, никто IoC не заставляет использовать -- помилуйте. Однако же с ним гораздо удобнее, чем с глобальной переменной (или каким-то синглтоном).
Предположим, есть десяток WhateverDataAccessObject. Объяснять через IoC каждому контролеру, где искать подставленный объект, да еще для каждого интерфейс писать? На удобнее не похоже...
====
Пока писал, думал
Вы имеете в виду, использовать static class DataAccess в качестве Service Locator'а?
Здравствуйте, Ivan Danilov, Вы писали:
ID>Может быть, я плохо понимаю, что такое IoC — но хоть убейте, не вижу, к каким преимуществам в данном случае эта технология приведет, кроме небольшого увеличения кода...
Основной аргумент — упрощается тестирование. Тестировать код завязанный на синглтоны бывает не очень удобно (особенно, если разделение unit тесты/интеграционные тесты)
ID>Если поясните на примере — будет просто отлично
Код может выглядеть примерно так:
internal class Program {
static public typename var = new typename();
static internal void Main(string[] args) {
using (DependencyContainer cnt = new DependencyContainer(config))
{
cnt.GetComponent<Application>().Run();
}
}
}
}
internal class Application
{
// контейнер сам найдет реализацию IMapper, создаст объект и передаст его в конструкторpublic Application(IMapper mapper) { ; }
// IoC контейтерpublic IContainer Container { get; set; }
// Опциональный компонент. Если контейнер найдет реализацию ILogger то, инициализирует это свойствоpublic ILogger Logger { get; set; }
public void Run()
{
// Из контейнера можно запрашивать доп. сервисы
IBoo boo = Container.GetComponent<IBoo>();
}
}
Основные плюсы в том, что нет необходимости отслеживать руками все необходимые зависимости между компонентами. Например, реализация IMapper может зависеть еще от каких-то других компонент... но, в коде этого указывать не надо — контейнер сможет найти все необходымые зависимости по конфигурационной информации. т.е. основное приемущество — код становится менее связанным. следовательно, потом его проще будет развивать и поддерживать.
Сам код раздувается мало, если даже не сказать, что становится меньше — т.к. создание/управление жизнью многих "вспомогательных" компонент будет взято на себя контейнером
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Ivan Danilov, Вы писали:
ID>Предположим, есть десяток WhateverDataAccessObject. Объяснять через IoC каждому контролеру, где искать подставленный объект, да еще для каждого интерфейс писать? На удобнее не похоже...
Это не так сложно и муторно, как кажется на первый взгляд. Преимущества в конечном итоге значительно перевешивают.
ID>Вы имеете в виду, использовать static class DataAccess в качестве Service Locator'а?
Да любой статический Service Locator -- тот же синглтон-вид-в-профиль, от которого так просто не избавиться.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
HgLab: Mercurial Server and Repository Management for Windows
Здравствуйте, Нахлобуч, Вы писали:
Н>Здравствуйте, Ivan Danilov, Вы писали:
ID>>Предположим, есть десяток WhateverDataAccessObject. Объяснять через IoC каждому контролеру, где искать подставленный объект, да еще для каждого интерфейс писать? На удобнее не похоже...
Н>Это не так сложно и муторно, как кажется на первый взгляд. Преимущества в конечном итоге значительно перевешивают.
ID>>Вы имеете в виду, использовать static class DataAccess в качестве Service Locator'а?
Н>Да любой статический Service Locator -- тот же синглтон-вид-в-профиль, от которого так просто не избавиться.
Здравствуйте, Ivan Danilov, Вы писали:
ID>Предположим, есть десяток WhateverDataAccessObject. Объяснять через IoC каждому контролеру, где искать подставленный объект, да еще для каждого интерфейс писать? На удобнее не похоже...
Писать интерфейс вас никто не заставляет — можно сделать абстрактный класс. хотя, даже и его можно не делать
Объяснять тоже может быть не особенно сложно. Просто, в конфигурации говорите явно что и где надо использовать. Например:
Здравствуйте, Ivan Danilov, Вы писали:
ID>Понял, что не хватает теоретической подготовки. Потому что не понимаю, как все это сможет заработать ID>Можно какую-то ссылку на статью/литературу по DependencyContainer? Похоже, у Фаулера слишком уж упрощенно.
Я бы посмотрел на готовые примеры/реализации — обычно, там уже есть и готовые примеры использования и описание тех или иных возможностей. Мне больше приглянулся http://www.castleproject.org/container/index.html как с наиболее человечный
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Я бы посмотрел на готовые примеры/реализации — обычно, там уже есть и готовые примеры использования и описание тех или иных возможностей. Мне больше приглянулся http://www.castleproject.org/container/index.html как с наиболее человечный
Спасибо за ссылку. А насколько надежна приведенная реализация, Вы не в курсе? Или это было только для примера "как должно выглядеть"?
Здравствуйте, Ivan Danilov, Вы писали:
ID>Спасибо за ссылку. А насколько надежна приведенная реализация, Вы не в курсе? Или это было только для примера "как должно выглядеть"?
Я считаю, что надежная — лично мне с проблемами столкнуться не пришлось. В любом случае, есть JIRA по которой можно сделать свои выводы.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Я бы посмотрел на готовые примеры/реализации — обычно, там уже есть и готовые примеры использования и описание тех или иных возможностей. Мне больше приглянулся http://www.castleproject.org/container/index.html как с наиболее человечный
А какие ещё рассматривали? Spring.NET?
Не могли бы вкратце привести плюсы castle по сравнению с остальными?
Здравствуйте, Curufinwe, Вы писали:
TK>>Я бы посмотрел на готовые примеры/реализации — обычно, там уже есть и готовые примеры использования и описание тех или иных возможностей. Мне больше приглянулся http://www.castleproject.org/container/index.html как с наиболее человечный
C>А какие ещё рассматривали? Spring.NET? C>Не могли бы вкратце привести плюсы castle по сравнению с остальными?
Да, Spring.NET тоже рассматривал. Лично мне Spring показался каким-то монструозным и перегруженным лишними деталями. у Castle основной плюс — проста и расширяемость.