safonovea
- Вопросы
- Ответы
Имя | Евгений Сафонов |
Возраст | Неизвестно |
Сайт | Неизвестно |
Неизвестно | |
Участвует в проекте | 1104 дн., 11 час., 41 мин. |
Последняя активность | 491 дн., 20 час., 15 мин. назад |
Ответы
Перейти к вопросу →
Это зависит непосредственно от самого атрибута. Если он был определен с примененным к нему атрибутом AttributeUsageAttribute
, свойство Inherited
которого установлено в true
, то он будет применен ко всем наследникам.
Вот пример:
[AttributeUsege(AttributeTargets.Method, Inherited = true)]
public class SomeAttribute : Attribute
{
}
public class SomeClassBase
{
[SomeAttribute]
protected virtual void DoSomething();
}
public class SomeDerivedClass : SomeClassBase
{
// К этому методу атрибут SomeAttribute применен
protected override void DoSomething(){};
}
Перейти к вопросу →
Прежде чем ответить на все вопросы, предлагаю выяснить назначение и принципы действия каждого из паттернов.
DAO
Итак, паттерн DAO (Data Access Object) получил особо широкое распространение и применение в мире J2EE. Его прямое предназначение — абстрагировать и инкапсулировать доступ к источнику данных. DAO управляет соединением с источником данных для получения и записи данных.
В классическом варианте DAO содержит только стандартные CRUD-методы. Клиент вызывает эти методы получая или передавая в качестве аргумента так называемый DTO (Data Transfer Object).
По сути, DAO является реализацией слоя отображения реляционных данных в объекты и наоборот. Именно здесь сосредотачивается решение проблемы, известной как "Object-relational impedance mismatch".
Repository
Рассмотрим теперь паттерн Repository. Repository выступает в роли посредника между слоем домена и слоем отображения реляционных данных. Он выполняет роль коллекции объектов домена в оперативной памяти. Таким образом, репозиторий представляет собой более высокий уровень абстракции над слоем отображения данных.
Repository является ориентрованным на модель предметной области, в то время как DAO больше ориентирован на источник данных. Это означает, что Repository может содержать методы, возвращающие объекты предметной области, удовлетворящие какому-либо заданному критерию, а также содержать логику конструирования запросов к нижележащему слою (собственно DAO).
Объекты, запрашиваемые у репозитория, могут иметь довольно сложную структуру. Например, объект Employee может содержать ссылку на объект Organization. Для того, чтобы обеспечить корректную работу по сохранению и загрузке подобных объектов репозиторию может понадобиться один или несколько DAO.
Выводы
Что же мы имеем в итоге? Выходит, что вопрос о взаимоисключающем использовании паттернов Repository и DAO несколько некорректен. Эти решения можно задействовать в связке. Применяя Repository как коллекцию объектов в памяти, мы можем поместить DAO на более низкий уровень и инкапсулировать в нем логику обращения к источнику данных. Важно помнить об обязанностях каждого из решений.
Ниже приведу краткий список тезисов, характеризующих различия между Repository и DAO:
- DAO инкапсулирует доступ к источнику данных
- DAO является реализацией слоя объектно-реляционного отображения
- DAO более ориентирован на источник данных
- Repository представляет более высокий уровень абстракции
- Repository выполняет роль коллекции объектов домена в памяти
- Repository ориентирован на модель предметной области
Перейти к вопросу →
Строго типизированные HTML-хелперы. Кроме того, они теперь возвращают не String, а MvcHtmlString.
Updated:
Вот список:
- DisplayFor()
- DisplayTextFor()
- EditorFor()
- CheckBoxFor()
- HiddenFor()
- PasswordFor()
- RadioButtonFor()
- TextBoxFor()
- LabelFor()
- DropDownListFor()
- ListBoxFor()
- TemplateFor()
- TextAreaFor()
- ValidationMessageFor()
Как видно, все хелперы заканчиваются суффиксом For (хотя это и не является обязательным условием). Все они принимают в качестве аргумента объект типа Expression<Func<TModel, TValue>>
. Т.е. лямбда-выражение, где TModel обычно представляет тип, которым строго типизирован View. Кроме того, некоторые хелперы принимают еще аргументы, специфичные для конкретного элемента (например IEnumerable<SelectListItem>
для DropDownListFor()
)
Использование довольно просто:
Есть класс:
public class RegisterModel
{
[DisplayName("User name")]
public string UserName { get; set; }
[DisplayName("Email address")]
public string Email { get; set; }
[DisplayName("Password")]
public string Password { get; set; }
[DisplayName("Confirm password")]
public string ConfirmPassword { get; set; }
}
Далее в строго типизированном этим классом виде пишем:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcApplication2.Models.RegisterModel>" %>
...
<%= Html.LabelFor(m => m.UserName) %>
<%= Html.TextBoxFor(m => m.UserName) %>
<%= Html.ValidationMessageFor(m => m.UserName) %>
Пример взят из создаваемого по-умолчанию проекта ASP.NET MVC 2 (с некоторыми упрощениями)
Перейти к вопросу →
В состав Spring.NET 1.3 (думаю, что и в более ранние версии тоже) входит набор шаблонов для ReSharper (File Templates и Live Templates). Live Templates помимо прочего содержат несколько заготовок для работы с файлами xml-конфигурации. В моем дистрибутиве (Spring.NET-1.3.0.exe, скачан с http://www.springsource.com/download/community) эти заготовки несколько отличаются от описанных в документации и выглядят следующим образом:
odctor
- определение аргумента конструктораodef
- определение нового объектаodprop
- определение свойства объекта
Для того, чтобы их установить нужно в VS выбрать меню ReSharper->Live templates, в появившемся окне нажать кнопку "Import" и выбрать файл spring_r#_live-templates.xml, расположенный в каталоге dev-support\resharper каталога установки Spring.NET. После этого в xml-файле конфигурации набираем любой из приведенных выше сниппетов и нажимаем Tab.
Кроме того ReSharper поддерживает автодополнение для значения трибута type
. Используемая комбинация клавиш — Shift+Alt+Space. Насколько я понял, доступны только .NET типы и типы, определенные в той же сборке, в которую включен редактируемый конфигурационный файл (если кто-то знает как заставить "видеть" типы из других сборок, пожалуйста поделитесь). Также (по Alt+Enter) есть возможность добавить имя сборки, в которой находится тип.
Перейти к вопросу →
Можно попробовать logview4net
Перейти к вопросу →
Примерно также, как и в случае перегрузки обычных методов:
public string this [int number]
{
get {...}
set {...}
}
public string this [string key]
{
get {...}
set {...}
}
Перейти к вопросу →
Не думаю, что на этот вопрос есть однозначный ответ (типа "рекомендуемое количество методов в интерфейсе равно 7, но в особо запутанных случаях можно увеличить до 9" :)). Наверное, как обычно, следует руководствоваться принципами Single Responsibility и Separation of concerns.
Перейти к вопросу →
Коротко говоря, PDB (program database) файлы содержат отладочную информацию и информацию о состоянии проекта, которую использует Visual Studio (например, в процессе отладки). Для развертывания и использования приложения конечным пользователем эти файлы совершенно не нужны.
Подробнее можно почитать в MSDN
Перейти к вопросу →
В статье "ASP.NET MVC Action Filter - Caching and Compression" предлагается создать ActionFilter и перекрыть его метод OnActionExecuted следующим образом:
using System;
using System.Web;
using System.Web.Mvc;
public class CacheFilterAttribute : ActionFilterAttribute
{
public int Duration
{
get;
set;
}
public CacheFilterAttribute()
{
Duration = 10;
}
public override void OnActionExecuted(FilterExecutedContext filterContext)
{
if (Duration <= 0) return;
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
}
}
Затем можно применить фильтр к экшену:
[CacheFilter(Duration = 60)]
public void Category(string name, int? page)
Перейти к вопросу →
Да, можно. Для этого необходимо просто перечислить нужные значения через запятую.
<... SomeProperty="SomeValue1, SomeValue2, SomeValueN" />