Ответы пользователя admax - CodeHelper

admax

admax
Карма 2924
Имя Евгений
Возраст Неизвестно
Сайт Неизвестно
Twitter @codehelper_ru
Участвует в проекте 1118 дн., 14 час., 5 мин.
Последняя активность 419 дн., 6 час., 35 мин. назад
О себе ничего не указано

Ответы

Новые Лучшие
1
...
4
5
6
7
8
...
13
Перейти к вопросу →

Linq To DataSet дает одно серьезное преимущество — возможность писать запросы не в виде строки, а в виде кода на C#/VB. Это означает, что ошибки запроса будут найдены во время компиляции, а не во время выполнения. Кроме того работает автодополнение среды и статическая типизация.

Linq To Sql дает только удобный способ доступа к уже загруженному DataSet. При этом сами операции с данными выполняются при помощи ADO.NET. Если основное проседание производительности происходит на уровне базы данных (фактически уровень ADO.NET), то хочется верить, что применение linq to dataset никак не скажется на производительности (или скажется незначительно).

Если отойти от темы linq, то следует заметить, что применение DataSet для доступа к данным в серьезном приложении не совсем оправдано. DataSet`ы не дают возможности создать богатую предметную область с наследованием, полиморфизмом и прочими фишками. По сути DataSet — это прямое отображение таблицы базы данных. Но не решает (а скорее усугубляет) проблем несоответствия реляционной и объектной парадигмы.

Перейти к вопросу →

Нужно использовать класс VelocityEngineFactory. Это фабрика, которая принимает свойства в виде абстракций Spring.NET и создает экземпляры VelicityEngine, транслируя все характеристики фабрики в свойства NVelocity. То есть NVelocity конфигурируется не через extended properties, а через высокоуровневые классы Spring.NET (типа загрузчиков ресурсов).

Можно попробовать так:

var factory = new VelocityEngineFactory();
factory.ResourceLoader = ContextRegistry.GetContext();
factory.ResourceLoaderPath = "ScriptGeneratorTemplates";
var engine = factory.CreateVelocityEngine();
Перейти к вопросу →

Роберт К. Мартин, Джеймс В. Ньюкирк, Роберт С. Косс

Быстрая разработка программ. Принципы, примеры, практика. Agile Software Development. Principles, Patterns and Practices

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

Быстрая разработка программ. Принципы, примеры, практика

Перейти к вопросу →

Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес

Приемы объектно-ориентированного проектирования. Паттерны проектирования

Знаменитые паттерны GoF. Книга, которая произвела революцию в отрасли. И это при том, что (по признанию авторов) в ней нет ничего нового — только систематизация знаний и типовых подходов проектирования. Кроме самих паттернов, книга открывает глаза на основы объектно-ориентированного дизайна, принципы проектирования.

Приемы объектно-ориентированного проектирования. Паттерны проектирования

Перейти к вопросу →

Есть отличие, касающееся «ленивой» загрузки. Метод Load() никогда не возвращает null и выбрасывает исключение если соответствующий объект не найден. Но если разрешена ленивая загрузка, то Load() может вернуть proxy вместо реального объекта. Сама загрузка происходит при попытке доступа к свойствам прокси. Исключение также будет выбрашено не при вызове Load(), а при обращении к прокси. С другой стороны, Get() не может вернуть прокси, потому что метод должен проверить, существует ли загружаемый объект.

Если объект уже был загружен, и храниться в кеше сессии, то Load() вернет объект из кеша без обращения к базе данных, а Get() обратиться к базе чтобы проверить, существует ли объект.

Есть интересный трюк, основанный на методе Load() (из книги NHibernate in Action):

using(ISession session = sessionFactory.OpenSession()) {
    using( session.BeginTransaction() ) {
        Category parent = session.Load<Category>(anId);  1
        Console.WriteLine( parent.Id );                  2
        Category child = new Category("test");           3
        child.ParentCategory = parent;
        session.Save(child);                             4
        session.Transaction.Commit();
    }
}

Тут происходит следующее: 1 загружается объект Category с помощью метода Load() (подразумевается, что lazy-init=true). Так как Load() возвращает прокси, то обращение к базе не происходит. Далее, выводится идентификатор категории в консоль 2. Свойство Id заполняется также без обращения к базе, потому что идентификатор был передан в метод Load() 1. Затем создается дочерняя категория 3 и связывается с уже загруженной категорией. Сохранение категории 4 вызывает генерацию INSERT-запроса. В итоге мы получаем, что дочерняя категория была добавлена без загрузки родительской категории из базы данных, так как вся работа велась с прокси.

Перейти к вопросу →

По умолчанию клиент WCF использует настройки proxy, которые заданы в системе. То есть те, которые устанавливаются в Internet Explorer. Если требуется задать специфичные настройки proxy, то можно использовать параметр proxyAddress и указать, что не нужно использовать системные настройки (useDefaultWebProxy=false):

<basicHttpBinding>
  <binding name="MyClientBinding" proxyAddress="http://proxy:8080" useDefaultWebProxy="false">
  </binding>
</basicHttpBinding>

Можно также вынести эти настройки в конфигурацию binding:

<binding name="CommonBinding">
    <binaryMessageEncoding />
    <httpTransport proxyAddress="http://proxy:8080" useDefaultWebProxy="false" />
</binding>

Можно также определить глобальные настройки прокси для всех ендпойнтов:

<system.net>
  <defaultProxy useDefaultCredentials="true">
    <proxy bypassonlocal="False" proxyaddress="http://proxy:8080" />
  </defaultProxy>
</system.net>

Взято из статьи Configuring a proxy-server for WCF. Также в статье подмечена интересная деталь: если клиент работает с локальным сервером, то настройки прокси игнорируются и все запросы идут напрямую. Чтобы избежать такой ситуации нужно в адресе сервера писать не localhost, а имя машины.

Перейти к вопросу →

Официальное описание:

MVC Turbine — это плагин для ASP.NET MVC, который взаимодействует с нижележащим IoC-контейнером и автоматически разрешает зависимости для контроллеров, движков отображения (view engines), binder`ов, view engines, http-модулей и тд.

Заявленные фичи:

  • Темплейты решений Visual Studio 2008 для IoC-контейнеров
    • Ninject
    • Castle Windsor
    • StructureMap
    • Unity
  • Новый фреймворк времени выполнения для поддержки расширяемости
    • Blades (components) — автоматически регистрируемые компоненты, которые загружаются во время выполнения.
    • Представлены объекты Core Blades для определения основных runtime-объектов приложения ASP.NET MVC:
      • MvcBlade — для MVC-специфичных компонентов (Controllers, View Engines и тд).
      • WebBlade — для компонентов пространства имен System.Web components (IHttpModule и тд).
      • RoutingBlade — для компонентов, определяющих настройку роутинга.
    • RotorContext, который работает с Blades для настройки рантайма.
  • Автоматическая регистрация объектов View Engine: любой класс, реализующий IViewEngine регистрируется срвис-локатором и используется в качестве движка отображения.
  • Авто регистрация фильтров (MVC Filters) для поддержки constructor injection.
  • InferredViewResult для обработки неопределенных action`ов и возврата ошибки 404.
  • Работает с ASP.NET MVC на Mono

Сама идея проекта, конечно, выглядит очень привлекательно. И задачи решаются вполне актуальные. Но при близком расмотрении выявляются некоторые нюансы реализации:

  • Нет поддержки для Spring.NET (Это самое обидное)
  • Нет поддержки знаменитого Comon Service Locator (абстракция над всеми популярными IoC-контейнерами)
  • MVC Turbine определяет собственный синтаксис регистрации зависимостей в контейнере, что само по себе сомнительно, учитывая, что в проекте уже используется синтаксис какого-то из IoC-контейнеров.
Перейти к вопросу →

Вот перевод документации:

Callback

Callback — это метод, позволяющий пользователю определить делегат, который будет вызываться каждый раз при проверке взова метода на «ожидаемость». Это полезно, когда нужно провести сложную проверку параметров метода или когда параметры метода должны как-то взаимодействовать с контекстом теста.

То что нужно иметь в виду при использовании callback:

  • Делегат, который передается в метод callback, должен возвращать booltrue если аргументы метода прошли валидацию. Если же валидация не пройдена, верните false и Rhino Mocks отметит, что вызов метода не считается ожидаемым.
  • Тесты, использующие callback, легко могут стать трудночитаемыми. Поэтому пользуйтесь колбеками только в случае необходимости.
  • Делегаты callback могут (и, скорее всего, будут) вызваны несколько раз; имейте это в виду, когда пишете их код. Оберните необходимые действия в if ( firstTimeCalled ) { /*do work*/ } или другим способом убедитесь, что повторный вызов не будет иметь побочных эффектов.

Технические детали — чтобы callback считался вызвался корректно нужно чтобы он возвращал bool и принимал те же параметры, что и исходный метод. Для регистрации делегата используется код:

IProjectRepository repository = mocks.CreateMock<IProjectRepository>();
IProjectView view = mocks.CreateMock<IProjectView>();
Expect.Call(view.Ask(null,null)).Callback(new AskDelegate(DemoAskDelegateMethod)).Return(null);

Имейте в виду — внутри колбека нельзя изменить возвращаемое значение метода, поэтому нужно указать его явно (используя Return(...))

Do

Иногда бывает, что возврат статичного значения из заглушки неприемлемо для сценария тестирования. Для таких случаев используется метод Do чтобы добавить собственную логику генерации возвращаемого значения. Значение, возвращаемое делегатом метода Do будет считаться возвращаемым значением метода (любые исключения также также учитываются). Сигнатура делегата должна совпадать с сигнатурой исходного метода.

Обработчик Do вызывается только если соответствующий метод вызван. И он вызывается только один раз для этого метода. В этом отличие от Callback()

Перейти к вопросу →

Есть такие рекомендации для интерфейсов:

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

В общем, количество методов интерфейса скорее зависит от контекста, то есть от того, сколько всего сервисов в проекте, какие задачи они решают и тд

Перейти к вопросу →

С текущими мощностями компьютеров, по-моему, не стоит сильно беспокоиться о времени билда. Какая разница, билдица проект 2 секунды или 7 секунд? Если говорить о Visual Studio, то решение из 30 проектов строится довольно-таки быстро. То есть, я считаю, что при разбиении на проекты нужно в первую очередь руководствоваться принципами пакетирования, а не временем сборки. Вообще, все решение в виде одного-двух проектов — это очень радикально. В реальном проекте лучше найти компромисс. Так, можно начать проект, создавая столько проектов сколько кажется правильным (с точки зрения принципов пакетирования), а затем, если структура решения станет слишком запутанной, то объединить некоторые проекты в один.


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