Здравствуйте.
Типичное легко-расширяемое веб приложение(интернет магазин/форум/блог/каталог/веб сервис по обработке какихх-то данных):
Приложение разделено на две части:
1.FE html+js+css
2.BE asp.net webservices
Хоститься на одном вебсайте-ip адресе, но вебсервисы — под-приложение. FE показывает html страничку и по необходимости дергает методы вебсервисов .
FE — может писаться на ангуляре/кастомного js/__подставить свое.
BE.
Базовый контроллер, содержит информацию о сессии, о пользователе и информацию которая нужна в почти во всех запросах на сервер. От базового контрллера будут унаследованы практически все контроллеры.
Аттрибут `exception` — это "фильтр", который перехватывает все exceptions, логирует и если нужно возвращает клиенту сеарилизованную ошибку в json или HTTP CODE.
[exception]
public class baseController : ApiController
{
public session session { get; internal set; }
public domain.servicemodels.user.user user{ get; internal set; }
}
Пример типичного контроллера.
"фильтр" `auth` говорит, что только аутентифицированные пользователи могут вызывать данный контроллер.
"фильтр" `authorz` — говорит какие роли должны быть у этого пользователя, что бы он мог вызвать контроллер.
аттрибут service — говорит что только HTTP POST запрос может быть выполнен к этому методу; т.к. PUT,DELETE -это недоработки/костыли HTTP протокола, в реальной жизни они ненужны, все запросы к сервисам будут идти только через POST, буд-то мы создаем еще один уровень в сетевой моделе OSI. HTTP GET нужен только для браузеров для скачивания html или js, тоже недостаток HTTP протокола, можно было бы спокойно жить с одним POST, отсылая еще как параметр время жизни данных, которые отдал сервер.
В теле контроллера, идет базовая обработка кода, по необходимости, достаются нужные конфиги, конвертируются входящие параметры в нужные объекты.
[auth]
public class carController : baseController
{
[authorz(roles.user,roles.admin)]
[service]
public rr delete(car car)
{
var s = new carservice();
return s.delete(car, this.user);
}
}
Каждый метод контроллера, будет возращать код ошибки/кастомной ошибки с описанием.
public enum responce_codes
{
// Action was handled well, without errors
success = 0,
// HTTP parameters(from body|url) not valid
bad_request = 400,
unauthorized = 401,
forbidden=403,
internal_server_error = 500,
...
}
public class error {
public string name { get; set; }
public string message { get; set; }
}
public class rr : error
{
public responce_codes code { get; set; }
public IEnumerable<error> errors { get; set; }
}
Типичный сервис с бизнес логикой.
В метод `delete` передаются данные, которые будут проверены: базовая валидация, потом запросы к бд, какая-то логика, конвертация прокси/адаптером классом в объект — Responce для клиента, в котором не будет содержаться лишних данных.
В блоке `using (var context = new xcontext())` -создает соединение с бд, достаются необходимые данные, обрабатываются и закрывается соединение.
`invalid_data_exception` — кастомное исключение, которое будет обрабатываться в `exception` фильтре
public class carservice
{
public rr delete(servicemodels.car.car car, servicemodels.user.user user)
{
var date = DateTime.UtcNow;
if (user.shop == null || car == null)
{
throw new invalid_data_exception();
}
using (var context = new xcontext())
{
var carsmanager = new carsmanager(context);
var usersmanager = new usersmanager(context);
var carproxy = new carproxy();
var update_car = carsmanager
.list_by_shop_not_deleted(user.shop.id)
.FirstOrDefault(x=>x.id==car.id);
if (update_car==null)
{
throw new invalid_data_exception();
}
...
update_car.deletedate = date;
carsmanager.update(update_car);
context.SaveChanges();
return new rr();
}
}
}
Все никакого лишнего кода, все красиво, все работает,
мы всегда знаем что в каждый метод сервиса будут переданы только те данные/конфиги, которые ему нужны для выполнения логики, потом будет проверка входящих данных, а после, если нам надо, а не при каждом request|responce, будет создано соединени с бд/диском, а ты только клепай контроллеры да методы.
Где можно применить Dependency Injection что бы упростить себе жизнь?