В относительно простом приложении (т.е. 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 основной плюс — проста и расширяемость.
Здравствуйте, ryf, Вы писали:
TK>>Есть несколько готовых сравнений Castle Project and Spring.Net — Part II (правда, оно за 2005-й год и кое-что уже поменялось), Castle vs Spring.NET
ryf>А castle вообще развивается? посмотрел у них на сайте последний релиз от ноября 2006 года.
Есть changeLog с ежедневной активностью http://fisheye3.cenqua.com/changelog/castleproject что касается выхода релизов то, это больше вопрос религии... кто-то любит их делать раз в месяц, а кто-то по завершении каких либо больших прорывов...
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Да, Spring.NET тоже рассматривал. Лично мне Spring показался каким-то монструозным и перегруженным лишними деталями. у Castle основной плюс — проста и расширяемость.
Да, у меня тоже сложилось похожее впечатление
TK>Есть несколько готовых сравнений Castle Project and Spring.Net — Part II (правда, оно за 2005-й год и кое-что уже поменялось),
Неплохое сравнение, правда, несколько смущает то, что его автор — главный разработчик Castle
Здравствуйте, Ivan Danilov, Вы писали:
ID>Чем это вредно? К примеру, в серверной части распределенного приложения, почему бы не организовать таким образом мапперы? Какие альтернативы?
я ваших слов не понимаю, но чем плохи глоб. переменные — сказать могу. вот к прмеру я пишу архиватор. можно сделать глобальные переменные для текущего архива, выполняемой команды, процесса выполгнения. работает вроде отлично. затем я делаю графическую оболочку, возможность выполнения азадний в бэграунде и "всё смешалось в доме Облонских". есть арзив, открытый в GUI, есть обрабатываемый одной bg командой, и другой. есть параллельно выполняемые процессы упаковки и распаковки (например, при обновлении солид архива) — а состояние у них одно на двоих? в общем, это мешает скалировать приложение, включать его как часть более общей системы, где таких объектов может потребоваться создать несколько
вторая проблема — если выполнение процедуры зависит не только от её параметров, то задачу труднее отлаживать, тестировать, больше вероятность того, что она "отвалится" от незначительных изменений типа изменения порядка вызовов или порпуска вызова в какой-то редкой ситуации
Здравствуйте, TK, Вы писали:
TK>Я бы посмотрел на готовые примеры/реализации — обычно, там уже есть и готовые примеры использования и описание тех или иных возможностей. Мне больше приглянулся http://www.castleproject.org/container/index.html как с наиболее человечный
Еще вопрос, больше технического плана: конструкторы сервисов, регистрируемых в Remoting, вызываются извне. То есть через параметры конструктора при помощи IoC-контейнера передать экземляры нужных ему контроллеров не выйдет. Как тут выкрутиться?
ID>Еще вопрос, больше технического плана: конструкторы сервисов, регистрируемых в Remoting, вызываются извне. То есть через параметры конструктора при помощи IoC-контейнера передать экземляры нужных ему контроллеров не выйдет. Как тут выкрутиться?