Гость
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / AspNet Core. Как заинжектить текущий контроллер в класс-сервис ? / 25 сообщений из 177, страница 1 из 8
06.03.2019, 15:21
    #39783028
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Суть такая. Стараюсь держать логику в отдельных классах-сервисах. Однако пока не знаю как реализовать одну задумку.

В этом сервисе есть такой метод:
Код: c#
1.
Task<ActionResult<MyResult>>


Вариант с Task<MyResult> я отбросил, т.к. такой формат не позволяет сервису возвращать различные статусы, типа NotFound - придется делать какие-то оберточные классы имитирующие данный класс, а в контроллере их разворачивать в настоящий NotFound:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
public class MyController : MyBaseController
{
  public async Task<ActionResult<MyResult>> GetData([FromBody] MyParameters parameters)
  {
       var result = _myService.Getdata ();
	   
	   if (result is MyNotFound)
	   {	     	 
	     return NotFound (... перенести свойства из MyNotFound)
	   }
  }
}



Думаю так слишком неудобно. Поэтому решил, что сервис должен сразу сам возвращать ActionResult<MyResult>.
Однако возник следующий вопрос. В контроллере имеются виртуальные методы
Код: c#
1.
2.
public virtual NotFoundObjectResult NotFound(object value);
public virtual NotFoundResult NotFound();



Вот их мне бы и хотелось задействовать в сервисе. Но как ? Неужели придется в каждом методе предусматривать параметр для передачи ссылки на контроллер ?
Код: c#
1.
2.
3.
4.
5.
6.
7.
public class MyService 
{
   public async Task<ActionResult<MyResult>> GetData(ControllerBase controller, MyParameters parameters)
   {
     return controller.NotFound ();
   }   
}


Не красиво получается.

Можно ли в класс-сервис заинжектить контроллер, который обрабатывает текущий запрос, чтобы сделать код сервиса чище ?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
public class MyService 
{
   public MyService (ControllerBase controller)   << как заинжектить сюда ?
   {
     _controller = controller;
   }

   public async Task<ActionResult<MyResult>> GetData(MyParameters parameters)
   {
     return _controller.NotFound ();
   }   
}
...
Рейтинг: 0 / 0
06.03.2019, 15:36
    #39783034
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Тащить контроллер в сервис - спагетти, забудь.
ActionResult возвращать тоже не очень хорошо.

Не забывай, контроллер ты можешь унаследовать от своего базового контроллера и делай там какие хочешь универсальные хелперы, которые обрабатывают результат, возвращаемый сервисом
...
Рейтинг: 0 / 0
06.03.2019, 15:41
    #39783036
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCore
Код: c#
1.
return controller.NotFound ();


кроме того, смотри
Код: c#
1.
2.
3.
4.
    public virtual NotFoundResult NotFound()
    {
      return new NotFoundResult();
    }


Код: c#
1.
2.
3.
4.
5.
6.
7.
  public class NotFoundResult : StatusCodeResult
  {
    public NotFoundResult()
      : base(404)
    {
    }
  }


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  public class StatusCodeResult : ActionResult
  {
    public StatusCodeResult(int statusCode)
    {
      this.StatusCode = statusCode;
    }

    public int StatusCode { get; }

    public override void ExecuteResult(ActionContext context)
    {
      if (context == null)
        throw new ArgumentNullException(nameof (context));
      context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger<StatusCodeResult>().HttpStatusCodeResultExecuting(this.StatusCode);
      context.HttpContext.Response.StatusCode = this.StatusCode;
    }
  }



И вот ради этого ты хочешь нагородить херни с протаскиванием контроллера?
...
Рейтинг: 0 / 0
06.03.2019, 15:48
    #39783045
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Так как вы предлагаете решить проблему ?

Вы все таки склоняетесь к этой не-менее-спагетти-хрени ?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
public class MyController : MyBaseController
{
  public async Task<ActionResult<MyResult>> GetData([FromBody] MyParameters parameters)
  {
       var result = _myService.Getdata ();
	   
	   if (result is MyNotFound)
	   {	     	 
	     return NotFound (... перенести свойства из MyNotFound)
	   }
  }
}



Можно конечно в базовом контроллере сделать методы-хэлперы, куда и перенести код:
Код: c#
1.
2.
3.
4.
	   if (result is MyNotFound)
	   {	     	 
	     return NotFound (... перенести свойства из MyNotFound)
	   }



Но что-то мне так не нравится. Придется создать кучу всех этих прослоечных классов:
Код: c#
1.
2.
public virtual My_OkResult Ok();
public virtual My_NoContentResult NoContent();


много тоже левого кода выйдет.


Я уж лучше буду передавать в каждый метод сервиса параметр-контроллер. Просто чуть чуть не красиво. Но почище, чем создание десятка прослоечных классов и распарсивание их в контроллере.

Я бы вообще может попробовал сам создавать эти NotFoundObjectResult и NotFoundResult. Но, полагаю, это не возможно. Скорее всего контроллер туда подставляет много чего, например заголовки запроса и прочее. Поэтому без контроллера явно не обойтись.

Самое лучшее, конечно, тут было бы получить доступ к текущему контроллеру через DI. Или может если бы к ControllerBase был бы статически метод Current...
...
Рейтинг: 0 / 0
06.03.2019, 15:50
    #39783046
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Shocker.ProИ вот ради этого ты хочешь нагородить херни с протаскиванием контроллера?

Мне думалось, что там все гораздо сложнее. Как минимум должны вставляться какие-то флаги от запроса. Поэтому я хочу обязательно задействовать методы текущего контроллера.
...
Рейтинг: 0 / 0
06.03.2019, 15:51
    #39783047
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
ну а чего такого страшного в протаскивании контроллера ?

Возьмите вон методы расширения какого нибудь Linq. Там вон протаскивается IEnumerable везде и ничего :) Мне придется протащить контроллер в параметр, но вот думаю, может это меньшее из зол.
...
Рейтинг: 0 / 0
06.03.2019, 15:51
    #39783048
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreВариант с Task<MyResult> я отбросил, т.к. такой формат не позволяет сервису возвращать различные статусы, типа NotFound - придется делать какие-то оберточные классы имитирующие данный класс, а в контроллере их разворачивать в настоящий NotFound:На самом деле нормальный вариант - возвращай Task<ServiceResult<MyResult>>. В оболочке ServiceResult можешь себе наделать универсальных полей, типа сообщений об ошибках, статусов всяких и т.п., а на стороне контроллера спокойно анализировать результат каким-то универсальным методом.
...
Рейтинг: 0 / 0
06.03.2019, 15:56
    #39783052
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreСкорее всего контроллер туда подставляет много чего, например заголовки запроса и прочее. Поэтому без контроллера явно не обойтись.Я привел тебе код контроллера. Там НИЧЕГО нет, это просто медод-хелпер. Никаких флагов, ничего.

WaspNewCoreМожно конечно в базовом контроллере сделать методы-хэлперы, куда и перенести код:Это нормально


WaspNewCoreНо что-то мне так не нравится. Придется создать кучу всех этих прослоечных классов:Зачем? Все это NotFound и NoContent - всего лишь статусы. Не нужно создавать никаких классов, или можно использовать готовые.


WaspNewCoreну а чего такого страшного в протаскивании контроллера ?Если не понимаешь, что такое спагетти, тогда дерзай. Через годик поймешь на собственных шишках.
...
Рейтинг: 0 / 0
06.03.2019, 16:00
    #39783059
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
эм. ну тут явно я не вижу спагетти-кода.

Контроллер вызывает сервис и передает ссылку на себя, но не для того, чтобы сервис работал как-то с контроллером. Вот если бы он как-то активно его использовал, может вызывал даже какие-то его методы, и потом возвращал все это назад самому же контрллеру, то да, это был бы спагетти код.

Но тут контроллер будет передаваться исключительно для того, чтобы задействовать его хэлпер-методы, для создания различных видов результата. Я думаю это не спагетти :)
...
Рейтинг: 0 / 0
06.03.2019, 16:00
    #39783060
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreВы все таки склоняетесь к этой не-менее-спагетти-хрени ?тут нет никакого спагетти, контроллер зависит от сервиса, сервис не зависит от контроллера.

Спагетти - это когда у тебя всё зависит от всего

В идеале слой сервиса не должен зависеть от ASP.NET вообще и находиться в другой сборке
...
Рейтинг: 0 / 0
06.03.2019, 16:01
    #39783061
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreэм. ну тут явно я не вижу спагетти-кода.

Контроллер вызывает сервис и передает ссылку на себяВот именно это и есть спагетти. Взаимная ссылка двух классов друг на друга - один из смертных грехов ))
...
Рейтинг: 0 / 0
06.03.2019, 16:03
    #39783063
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreВозьмите вон методы расширения какого нибудь Linq. Там вон протаскивается IEnumerable везде и ничего :)Linq-метод зависит от IEnumerable, IEnumerable не зависит от Linq, понимаешь???
...
Рейтинг: 0 / 0
06.03.2019, 16:03
    #39783064
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreЯ уж лучше буду передавать в каждый метод сервиса параметр-контроллер
...
Рейтинг: 0 / 0
06.03.2019, 16:06
    #39783068
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Shocker.ProВ идеале слой сервиса не должен зависеть от ASP.NET вообще и находиться в другой сборке+1
ТС, сервис это бизнес логика и чисто шарп код.
А контроллер может быть в библиотеках вебСервера Х. Или Y.
...
Рейтинг: 0 / 0
06.03.2019, 16:19
    #39783082
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Если подумать, то может даже и нет тут спагетти. Какие тут у нас зависимости по сути ?

MyController -> BaseController
MyService -> BaseController

Обе сущности зависят от BaseController а не друг от друга. Сервис будет использовать не методы MyController, а методы BaseController. Тут нет цикличных ссылок. Я думаю это принципиально.
К тому же, этот контроллер будет использоваться совсем немножно. Просто как маленький хэлпер :)

А предложенное решение с ServiceResult мне, все же, не нравится. Нужно будет многое учесть и накодить. Боюсь может получится слишком переусложненно. И все это можно решить простой передачей ссылки на базовый контроллер.

Я бы, все же, предпочел инжектить контроллер в сервис. Получилось бы аспектное программирование некое. Но раз такого нет, то предпочту передавать ссылку на контроллер.
...
Рейтинг: 0 / 0
06.03.2019, 16:24
    #39783087
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreНо раз такого нет, то предпочту передавать ссылку на контроллер.Упорный. Ну ладно, своих шишек набить полезно.
...
Рейтинг: 0 / 0
06.03.2019, 16:35
    #39783097
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Зато ваше решение попахивает огромным дублированием кода :)
https://refactoring.guru/ru/smells/duplicate-code
...
Рейтинг: 0 / 0
06.03.2019, 16:43
    #39783105
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Дублирования никакого не вижу. Будут вызываться те же методы контроллера, только не сервисом, а самим контроллером. Я же не предлагаю повторять методы контроллера в сервисе - это как раз вредно, потому что методы работают в контексте запроса/ответа/контроллера и т.п., а сервис, как я сказал выше, в идеале не должен зависеть вообще от ASP.NET.

Лень на начальном этапе написать десяток дополнительных строчек впоследствии оборачивается тысячами лишних строк или неделями рефакторинга.
...
Рейтинг: 0 / 0
06.03.2019, 16:54
    #39783115
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCoreЗато ваше решение попахивает огромным дублированием кода :)
https://refactoring.guru/ru/smells/duplicate-code показал бы. Или лень?
...
Рейтинг: 0 / 0
06.03.2019, 16:58
    #39783119
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Petro123,

что показал ?
...
Рейтинг: 0 / 0
06.03.2019, 16:59
    #39783121
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCorePetro123,

что показал ?дублирование на 2 страницы
...
Рейтинг: 0 / 0
06.03.2019, 17:03
    #39783126
WaspNewCore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
Petro123,

ServiceResult, в моей интерпретации приведенной изначально, это некий прослоечный класс. Я думал сделать их кучу, а Shocker.Pro
предлагает просто объединить в один класс, но с кучей свойств, как я понимаю, собранных со всех классов типа NotFoundResult, OkResult. Затем возвращать их из сервиса в контроллер, где некий метод будет анализировать этот объект и, в зависимости от заполнения свойств, создавать уже реальные Result'ы.

Ну вот все это какое-то завуализованное и усложненное дублирование получается. Т.к. появится логика по парсингу ServiceResult с последующим созданием соответствующих result'ов. Уж лучше тогда как я предлагал, насоздавать MyNotFoundResult, MyOkResult и просто их преобразовывать в классы из Aspnet.


Мне не нравится это решение. Я лучше при своем останусь.
...
Рейтинг: 0 / 0
06.03.2019, 17:11
    #39783131
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCore,
Можно и так:
// добавляем контекст MobileContext в качестве сервиса в приложение
services.AddDbContext<MobileContext>(options =>
options.UseSqlServer(connection));
...
Рейтинг: 0 / 0
06.03.2019, 17:12
    #39783133
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
WaspNewCore,
И будет EF контроллере и сервисный слой не нужен))
...
Рейтинг: 0 / 0
06.03.2019, 21:45
    #39783249
handmadeFromRu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AspNet Core. Как заинжектить текущий контроллер в класс-сервис ?
ТС ты путаешь причинно следственные связи, дублирования нет.
...
Рейтинг: 0 / 0
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / AspNet Core. Как заинжектить текущий контроллер в класс-сервис ? / 25 сообщений из 177, страница 1 из 8
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]