Пакет параметров — частичное решение проблемы распространения DTO
На мой взгляд, DTO - это боль, поскольку они имеют тенденцию распространяться в теневой домен. Это создает головную боль, когда вы решите реорганизовать свой сервисный слой.
Так почему бы просто не использовать типы dynamic
и забыть о DTO и строго типизированных параметрах маршрута? Ну, динамические значения очень удобны, но у них есть свои проблемы, в основном то, что вы не можете передать их методам расширения. Таким образом, проще правильно представить параметры маршрута, следовательно, привязку модели, следовательно, DTO и, следовательно, спагетти и глупые шляпы.
Итак, вот частичное решение, основанное на привязке модели Нэнси. Это значительно сокращает количество церемоний на уровне маршрута и помогает сдерживать раздражающее распространение DTO.
Базовый модуль Нэнси
public class _BaseModule : NancyModule
{
public class ParameterBag
{
// All the params used across all routes, GET and POST
public string UserName { get { return this.Value; } }
public string UserIds { get; set; }
public string UserId { get; set; }
public string Value { get; set; }
public int Skip { get; set; }
public int Take { get; set; }
}
public ParameterBag Params;
public _BaseModule(): this(""){}
public _BaseModule(string modulePath): base(modulePath)
{
Before += ctx =>
{
this.Params = this.Bind<ParameterBag>();
return null;
};
}
}
Класс ParameterBag
содержит все параметры, которые мне нужно связать со всеми всеми маршрутами. Поскольку Nancy будет заполнять свойства только в том случае, если найдет соответствующее поле в полезной нагрузке, вы можете просто добавить столько свойств в этот класс, сколько захотите, не заботясь о том, будут ли они использоваться данным маршрутом или нет.
Обратите внимание, как Binding происходит в хуке Before
. Это означает, что каждый маршрут (производный от _BaseModule
) автоматически привязывает любые совпадающие значения параметров к свойствам универсального класса ParameterBag
. Никакого специального вмешательства на уровне маршрута не требуется.
Результатом этого является предоставление обработчикам маршрутов строго типизированных значений параметров, которые можно просто использовать.
Модуль Нэнси
public class UserModule : _BaseModule
{
public UserModule()
{
// handlers go here
}
}
Пример обработчика маршрута
Get["/user/{userid}/username/available"] = _ =>
{
return Response.AsJson(new
{
// the username is a hidden value
// the userid comes from the url
value = Params.UserName,
valid = UserService.UserNameAvailable(Params.UserName, Params.UserId)
}
);
};
Пример использования
В приведенном ниже примере используется jqBootstrapValidation. Он показывает, как трюк с привязкой работает для данных параметров, предоставленных в URL-адресе и в составе полезной нагрузки ajax (см. атрибут value).
<input
type="text"
id="username"
name="username"
placeholder="User Name"
data-validation-ajax-ajax="/user/@user.id/username/available"
data-validation-ajax-message="This name has already been taken"
value="@user.UserName"
required>
person
biofractal
schedule
24.04.2013