Tworzenie abstrakcji nad MediatR

0

Czy warto tworzyć abstrakcję nad MediatR? Czy może jest to jedna z tych bibliotek, dla których nie warto, tak jak np. EF? A jeśli już tworzyć (bo projekt będzie duży), to jak? Przez pisanie interfejsów dziedziczących po interfejsach z MediatR i to ich implementowanie? Coś w stylu

public interface ICommandHandler<TRequest> : IRequestHandler<TRequest, Result> where TRequest : ICommand { }
public interface ICommand : IRequest<Result> { }

Do tego jakaś szyna opakowująca klasę Mediator, którą można by wstrzykiwać do kontrolerów.

3

Jeśli ma to sens to warto. Jeśli nie ma, to nie warto. Musisz sam sobie odpowiedzieć czy w Twoim projekcie taka abstrakcja będzie miała sens. Abstrakcja dla samej abstrakcji, bo tak było w jakimś tutorialu to jeden z częstszych błędów projektowania w ówczesnych projektach. W ogóle masz na myśli opakowanie całego frameworka czy jakichś jego części ? Jeśli części to pewnie znalazłeś już jakiś konkretny powód stworzenia tej abstrakcji.

0

MediatR ma wszystko to, czego potrzebuję, a przynajmniej tak mi się wydaje. No może definicje klas requestów są zbyt rozwlekłe, jeśli chce się zwracać jakiś typ generyczny z handlerów: public class XCommand : IRequest<RequestResult<YModel>>.

Ludzie piszą, że należy tworzyć warstwę abstrakcji nad bibliotekami, które mogą w przyszłości zostać zamienione na inne. Ale przecież na początku projektu nie wiadomo, czy do biblioteki, której planuje się używać, nie wyjdzie w przyszłości jakaś lepsza alternatywa, więc należałoby pisać abstrakcję do wszystkich, które są używane w wielu miejscach. Jak żyć? :/

4

No i przez takich ludzi powstała słynna abstrakcja na Entity Frameworku zwana repozytorium. Przy podmianie "core'owych" bibliotek powstanie wiele różnych innych problemów niż sam brak abstrakcji. Tego się po prostu prawie nigdy nie robi. Poza tym taką abstrakcje jest ciężko napisać lub jest to niemożliwe tak żeby przy podmianie biblioteki nie zaszła potrzeba robienia brzydkich hacków by wpiąć się w jej następce. Jedyny raz gdzie widziałem sens takiej abstrakcji to był sens biznesowy, gdzie jedno rozwiązanie było w chmurze (płatne) i nie wiadomo było, czy koszta sporo nie przewyższą kosztów utrzymywania darmowego odpowiednika. W tym przypadku wiadomo było, że może nastąpić podmiana. W przypadku biblioteki takiej jak Mediator nie widzę sensu takiej abstrakcji.

0

Jakie chcesz osiągnąć korzyści ze skorzystania z MediatR, bo jeżeli tylko dla zwiększenia loose coupling to może powinieneś się zastanowić nad innymi bardziej przystępnymi sposobami, wszystko zależy od złożoności projektu, być może taka abstrakcja nie jest potrzebna, ale jak najbardziej jest stosowana z powodzeniem. Myślę, że jednym z lepszych przykładów zastosowania MediatR to cqrs z event sourcing, bo miałem z tym doświadczenie, a poza tym to ciężko mi powiedzieć. W ogóle robisz to na poważnie, bo zwykle taką decyzje podejmuje cały team albo ktoś odpowiedzialny za projekt , kto miał z takimi rzeczami doświadczenie.

0

@Visual Code: Używam MediatR do CQRS we własnym projekcie.

0

@error91:

W ogóle po co ludzie używają Repo jeżeli nierzadko podmiana bazy ogranicza się do podmiany drivera?

1

@WeiXiao: Bardziej tutaj chodzi o argument podmiany ORM'a. Podmiana bazy to już w ogóle hardcore na produkcyjnej aplikacji, na pewno nie tylko podmiana drivera. Odpowiadając na pytanie to ludzie używają różnych wzorców nie mając pojęcia jaki problem dany wzorzec rozwiązuje.

0
error91 napisał(a):

@WeiXiao: Bardziej tutaj chodzi o argument podmiany ORM'a. Podmiana bazy to już w ogóle hardcore na produkcyjnej aplikacji, na pewno nie tylko podmiana drivera. Odpowiadając na pytanie to ludzie używają różnych wzorców nie mając pojęcia jaki problem dany wzorzec rozwiązuje.

W aplikacji podmiana drivera(no bo co jeszcze?) przy założeniu, że ten sam ORM, a na poziomie bazy export, odtworzenie schemy i jakoś przeniesienie danych :D

Wszystko chyba zależy z jakiej bazy na jaką - czasem jest łatwiej, a czasem trudniej :>

0
WeiXiao napisał(a):

@error91:

W ogóle po co ludzie używają Repo jeżeli nierzadko podmiana bazy ogranicza się do podmiany drivera?

Jeśli mowa o przypadkach gdzie stosują generyczne (lub nie) interfejsy, które tak naprawdę wystawiają dokładnie to samo na co pozwala czysty dostęp do kontekstu EF to faktycznie, jest to bez sensu. Natomiast jak najbardziej ma sens wyabstrachowanie EF, np. jeśli chcemy by nasz store/repository/cokolwiek dostarczał konkretnych kontraktów i zapobiegał samowolce w kodzie. Widok taki jak _context.SomeSet.Add(someObject) w różnych miejscach w kodzie jest dla mnie równie absurdalny co bezmyślne tworzenie repozytorium nie różniące się w zasadzie od czystego dostępu do kontekstu. Nie mówiąc już o stosowaniu zapytań na IQueryable gdzie popadnie (tutaj przydatne staje się użycie obiektów query które enkapsulują zapytania).

Co do sugestii odnośnie stosowania MediatR tylko po to by zwiększyć loose coupling- nie ma w tym nic złego i jest szeroko stosowane, a nazywa się to właśnie CQRS. Nie jest to CQRS na poziomie infrastruktury- gdzie moglibyśmy mieć oddzielny serwis do odczytu i zapisu- a CQRS w procesie. Nie zmienia to faktu że jest to właśnie CQRS które znaczenia ułatwia loose coupling, a poza tym pozwala na "odśmiecenie" kontrolerów. Dependency Inversion nie jest w żadnym razie alternatywą, a świetnym uzupełnień zastosowania MediatR. Zależności mogą zostać wstrzyknięte do handlerów.

0

@WeiXiao: No dokładnie to zależy. Przy zmianie z relacyjnej na relacyjną będzie mniej problemów niż z relacyjnej na jakiś NoSQL. Większość poza aplikacją, więc argument za repo, że abstrakcja nad ORM'em w czymś pomoże jest bez sensu bo masa większych problemów przy zmianie będzie poza aplikacją.

@Aventus: W większości przypadków "repozytorium" wygląda tak jak opisałeś w pierwszym zdaniu. Przynajmniej ja na takie trafiałem. Kod typu _context.SomeSet.Add(someObject) powinień być w serwisach aplikacyjnych i tyle. Jak wydzielisz samo _context.SomeSet.Add(someObject) to to jest właśnie ta niepotrzebna abstrakcja.

2
nobody01 napisał(a):

Ludzie piszą, że należy tworzyć warstwę abstrakcji nad bibliotekami, które mogą w przyszłości zostać zamienione na inne. Ale przecież na początku projektu nie wiadomo, czy do biblioteki, której planuje się używać, nie wyjdzie w przyszłości jakaś lepsza alternatywa, więc należałoby pisać abstrakcję do wszystkich, które są używane w wielu miejscach. Jak żyć? :/

Żyć trzeba pragmatycznie. Szanse na zmianę kluczowej w projekcie biblioteki są bliskie zeru. Nawet z "wydzieloną abstrakcją" nikt na to nie pójdzie, bo za duże ryzyko.
Abstrakcje powinny istnieć pomiędzy warstwami aplikacji, a wrapper na bibliotekę to nie jest abstrakcja.

WeiXiao napisał(a):

W ogóle po co ludzie używają Repo jeżeli nierzadko podmiana bazy ogranicza się do podmiany drivera?

Dwa powody:

  1. kult cargo;
  2. zawsze można powiedzieć, że się zna i praktykuje wzorce projektowe.

1 użytkowników online, w tym zalogowanych: 0, gości: 1