Castle Windsor - warunkowe wstrzykiwanie zależności

Castle Windsor - warunkowe wstrzykiwanie zależności
AL
  • Rejestracja:ponad 15 lat
  • Ostatnio:3 miesiące
0

Mam sobie solucję, która zawiera między innymi dwa projekty.

  1. Backend - logika biznesowa, context DB (nazwijmy go DBContextBE) dziedziczący po DbContext z którego korzysta logika biznesowa.
  2. API - tutaj znajduje się drugi context DB (nazwijmy go DBContextAPI) dziedziczący po DbContext z którego korzystają niektóre metody w tym projekcie.

Natomiast po stronie backendu (projekt punkt 1) jest adapter EF zawierający metody zapisu, aktualizacji czy tworzenia obiektów modeli bazy danych.
Po stronie API część metod z kontrolera odwołuje się do lokalnej logiki i DBContextAPI, a część metod do logiki z backendu (punkt 1) gdzie potrzebny jest DBContextBE.
I tutaj mam problem. Jak zarejestrować po stronie API dany context DB w zależności od tego, która logika jest w danym momencie używana?
Np. odpalam metodę z kontrolera API, która korzysta z logiki na backendzie gdzie operujemy na DBContextBE i gdy jest używana metoda z klas backendowych to rejestruję DBContextBE gdyż w konstruktorze adaptera EF oczekiwany jest obiekt klasy DBContext.

Kopiuj
public void Install(IWindsorContainer container, IConfigurationStore store)
        { 
            container.Register(Component.For<IDbContextAdapter>()
                .ImplementedBy<EfDbContextAdapter>()
                .LifestyleTransient());
           
            //Odpalam metodę wykorzystującą logikę z backendu to do EfDbContextAdapter potrzebuję wstrzyknąć DBContextBE
            container.Register(Component.For<DbContext>()
                .ImplementedBy<DBContextBE>()
                .LifestyleTransient());
            
             //Odpalam metodę wykorzystującą logikę z API to do EfDbContextAdapter potrzebuję wstrzyknąć DBContextAPI
            container.Register(Component.For<DbContext>()
                .ImplementedBy<DBContextAPI>()
                .LifestyleTransient());
}

Jak to uwarunkować? A w zasadzie jak poznać na etapie rejestracji, że w danym momencie jest uruchamiana dana metoda?

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 20 godzin
  • Lokalizacja:Wrocław
2

Zrób fabrykę, która będzie zwracała odpowiedni obiekt, w zależności od warunków
.Albo lepiej użyj różnych typów, a nie jednego.


Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
Gworys
  • Rejestracja:około 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:139
0

Taka fabryka oparta na swich'u zazwyczaj łamie open/closed principle.

Ja bym wolał zarejestrować implementacje IDictionary, która by działała jak IIndex z Autofac'a.

Potem robisz sobie kompozyt, który wybiera kontekst na podstawie argumentu z dictionary.


Unhandled Exception: System.MissingMethodException: Constructor on type 'System.Exception' not found.
edytowany 1x, ostatnio: Gworys
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 20 godzin
  • Lokalizacja:Wrocław
2
Gworys napisał(a):

Potem robisz sobie kompozyt, który wybiera kontekst na podstawie argumentu z dictionary.

Czyli fabrykę.


Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
Zobacz pozostałe 35 komentarzy
somekind
Ja nie używam inwektyw. Wcześniej myślałem, że mam doczynienia z jakimś gówniarzem 22-24 lata. Ale Ty masz 32 lata! Ogarnij się wreszcie, najwyższy czas. I wróć do społeczności, gdy dojrzejesz.
NN
32 haha.... No ładne masz urojenia na mój temat.... Poza tym z tych twoich postów typu ``Tyle lat pracuje w branży i uważam, że nie ma nic lepszego od MediaR na handler'achMożna się tylko śmiać jeszcze jak tego broniłeś, hahha. Albo Nie masz repozytorium to nie masz DDD` hahaha. A teraz ponownie wystawiasz się na pośmiewisko.....
NN
Może sprawdź, w słowniku co to jest inwektywa, bo wydaje mi się, że nie wiesz. A poza tym sam prowokowałeś konfrontacje ze mną, no więc...
NN
Domyślam się że @Adam Boduch podziela poziom swoich moderatorów i wiernie im kibicuje... :)
G3
@somekind: Tak rzeczywiście nie mam się czym przejmować tylko jakimś świniakiem, który żyje w sztucznej hierarchii i swoją tożsamość buduje w wirtualnej przestrzeni. Smutne, że jesteś taki słabym...
AL
  • Rejestracja:ponad 15 lat
  • Ostatnio:3 miesiące
0

Panowie nie wiem co tu się odpikoliło, ale generalnie jeszcze średnio łapię Wasze specjalistyczne określenia. Najlepiej jak byście mogli mi podrzucić jakiś przykład.
Co nieco już programuje i sporo rzeczy mi się udało zrobić, głównie bazując na przykładach ze stacka czy innych, ale nie są mi znane jeszcze wszystkie zagadnienia, które mógłbym z kimś przedyskutować face tu face. Dlatego też chyba potrzebuję aby ktoś mi wytłumaczył jak krowie na rowie.
Co to znaczy zrobić fabrykę zwracającą odpowiedni obiekt?
Ta fabryka będzie operowała rejestracją w windsorze?
I teraz nie bardzo wiem jak sprawdzić z poziomu windsora, który context jest używany.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 20 godzin
  • Lokalizacja:Wrocław
2

Możesz sobie napisać klasę jak ta:

Kopiuj
public class DbContextProvider
{
    private DbContext dbContextApi, dbContextBe;

    public DbContextProvider(DBContextAPI dbContextApi, DBContextBE dbContextBe)
    {
        this.dbContextApi = dbContextApi;
        this.dbContextBe = dbContextBe;
    }	
	
    public DbContext CreateContext()
    {
        if(warunek API)
            return this.dbContextApi;
        else if (warunek BE)
            return this.dbContextBe;
		
        throw new Exception();
    }
}

Potem ją skonfigurować w Windsorze i wstrzykiwać do klas potrzebujących DbContextu.

Ale czemu nie wstrzykiwać DBContextAPI i DBContextBE tam gdzie potrzebne, zamiast oba konfigurować jako DBContext?


Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
edytowany 4x, ostatnio: somekind
M5
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:6
0

Nie ma żadnego profitu z tego, że wstrzykujesz te konteksty do tego prvaidera, mniejsza z tym, że jest to słaba nazwa.

Poza tym łamiesz OCP każda próba rozszerzenia klasy "provaidera" będzie się łączyła dopisywaniem kolejnego ifa i dopisywania nowego parametru do konstruktora.

Opcja Gworysa jest o wiele lepsza. Mało tego też bym się wnerwił na jego miejscu.

I niby czym się różni ta fabryka na ifach od tej na switchu.?

edytowany 1x, ostatnio: Mimik59
SO
M5
Niestety pomyliłeś mnie z tym panem...
SO
Być może :P A tak swoją drogą jak tak bardzo nie podoba ci się rozwiązanie @somekind to pokaż jak byś to zrobił zgodnie z koncepcją Gworysa. Wtedy każdy będzie mógł popatrzeć na dwie implementacje i sam zdecydować co jest lepsze i w jakiej sytuacji :)
M5
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:6
0

to pokaż jak byś to zrobił zgodnie z koncepcją Gworysa. Wtedy każdy będzie mógł popatrzeć na dwie implementacje i sam zdecydować co jest lepsze i w jakiej sytuacji :)

Domyślam się, że chodzi w uproszczeniu mniejwięcej o coś takiego:

Kopiuj
//contener IOC
builder.RegisterType<Context<DbAPI>>().Keyed("arg1");
builder.RegisterType<Context<DbBE>>().Keyed("arg2");

//Gdzieś w logice
Dictionary.Key("arg1").Context()

No i....

edytowany 3x, ostatnio: Mimik59
M5
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:6
0

No to, że Ty na myśl fabryka myślisz switch albo service locator to już nie jest nasz problem, nie jest to też problem rozwiązywalny na forum programistycznym.

Moim zdaniem to, co ktoś sobie myśli na myśl Fabryka to nie istotne, bo to tylko wysokopoziomowy interfejs za fabryką może być cokolwiek. Jakaś fasada, service locator, whatever...

@somekind To mistrz wykorzystywania homonimy. Prowadzi debaty z poziomem co najmniej dzisiejszych liderów PO, lecz wiedzy technicznej dalej mu brakuje...

Zobacz pozostałe 2 komentarze
M5
Jakie multi konto...? ktoś kogoś zaczepia, obraża ? Gdzie?
M5
W sumie to raczej ty mnie zaczepiasz...
M5
Ktoś poczuł się obrażony.? :D
SO
Czemu miałbym poczuć się obrażony, jeśli w żadnej wypowiedzi do mnie nie nawiązywałeś?
M5
No wiesz... Niechcę dostać bana jak @Gworys :D
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 20 godzin
  • Lokalizacja:Wrocław
0
Mimik59 napisał(a):

Nie ma żadnego profitu z tego, że wstrzykujesz te konteksty do tego prvaidera, mniejsza z tym, że jest to słaba nazwa.

Pewnie, że nie ma. Dlatego napisałem, że tak można zrobić, ale żeby tego nie robić.

Poza tym łamiesz OCP każda próba rozszerzenia klasy "provaidera" będzie się łączyła dopisywaniem kolejnego ifa i dopisywania nowego parametru do konstruktora.

Owszem. Jeśli komuś nie podoba się łamanie OCP, to zawsze może sobie napisać mądrzej:

Kopiuj
public class DbContextProvider
{
    private CleverDbContext[] contexts;

    public DbContextProvider(CleverDbContext[] contexts)
    {
        this.contexts= contexts;
    }   

    public CleverDbContext CreateContext()
    {
        foreach (var ctx in this.contexts)
             if (ctx.CanBeUsed(/*pewnie jakieś parametry*/)
                 return ctx;

        throw new Exception();
    }
}

Ale to dalsze bredzenie w overengineering, podczas gdy tak naprawdę rozwiązywany jest tu chyba problem X/Y, a prawidłowym i działającym rozwiązaniem jest niebindowanie tych kontekstów do klasy bazowej, bo skoro nie są używane zamiennie, to żadnego pożytku z takiej konfiguracji nie ma.

I niby czym się różni ta fabryka na ifach od tej na switchu.?

No generalnie tym, że w ifach można mieć wyrażenia logiczne, a w switchu nie. (Chyba jednak usunięcie Newbie było złym pomysłem, skoro takie pytania się pojawiają.)

Domyślam się, że chodzi w uproszczeniu mniejwięcej o coś takiego:

Kopiuj
//contener IOC
builder.RegisterType<Context<DbAPI>>().Keyed("arg1");
builder.RegisterType<Context<DbBE>>().Keyed("arg2");

//Gdzieś w logice
Dictionary.Key("arg1").Context()

No tak, magiczne stringi są tak bardzo lepsze niż ify. :)

Opcja Gworysa jest o wiele lepsza. Mało tego też bym się wnerwił na jego miejscu.

Ja na jego miejscu też bym się wkurzył, że ktoś pisze z jego komputera i twierdzi, że nie jest nim.

PS, dużo jest Was tam, w środku?


Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
M5
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:6
0

No generalnie tym, że w ifach można mieć wyrażenia logiczne, a w switchu nie. (Chyba jednak usunięcie Newbie było złym pomysłem, skoro takie pytania się pojawiają.)

Gdybyś nie żył w średniowieczu wiedziałbyś, że to nieprawda.

case Apple apple when apple.Color == Color.Brown:

Poza tym, nie wiem co to ma wspólnego z tematem, pewnie odwrucenie uwagi.

f (ctx.CanBeUsed(/pewnie jakieś parametry/)

No a tutaj pewnie będzie magiczny int.? Ablo magiczny parametr.

No tak, magiczne stringi są tak bardzo lepsze niż ify. :)

Brak nawiązania do tematu, kolejne odwrócenie uwagi.
Może sobie nawet magicznego boolena tam wpisać. Co mnie to obchodzi.?

Ja na jego miejscu też bym się wkurzył, że ktoś pisze z jego komputera i twierdzi, że nie jest nim.

PS, dużo jest Was tam, w środku?

Jak to się dzieje, że ty ich wszędzie widzisz.?

Ps. sprawdź czy czasem jakiś Gworys ci się nie schował pod łóżkiem.

Ale to dalsze bredzenie w overengineering, podczas gdy tak naprawdę rozwiązywany jest tu chyba problem X/Y,

Twoje rozwiązanie wymaga stworzenia większej ilości obiektów, Więc tym bardziej jest overengineering'iem.

edytowany 1x, ostatnio: Mimik59
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 20 godzin
  • Lokalizacja:Wrocław
0
Mimik59 napisał(a):

case Apple apple when apple.Color == Color.Brown:

Poza tym, nie wiem co to ma wspólnego z tematem, pewnie odwrucenie uwagi.

No ja też nie wiem, co ten kod ma do rzeczy, na pewno nie rozwiązuje aktualnego problemu.

No a tutaj pewnie będzie magiczny int.? Ablo magiczny parametr.

Nie wiem, nie znam reguł wyboru odpowiedniego kontekstu. Te zna tylko autor wątku, jego pytaj.

Fafnasty raz powtarzam - najlepiej użyć rejestracji typów, fabryka jest możliwym, ale prawdopodobnie nie najlepszym rozwiązaniem tego problemu.


Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
M5
Przegrałeś, idę spać :P
au7h
Jak dobrze, że trzymam się z dala od C# (niby podobny do Javy), obrzydza mnie ta technologia tak jak cały visual studio ;p
M5
Mnie też obrzydza VS i ten durny marketing MS.
M5
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:6
0
somekind napisał(a):
Mimik59 napisał(a):

case Apple apple when apple.Color == Color.Brown:

No ja też nie wiem, co ten kod ma do rzeczy, na pewno nie rozwiązuje aktualnego problemu.

Wypowiedź, do której nawiązuje też nie. No i co z tego.?

Fafnasty raz powtarzam - najlepiej użyć rejestracji typów, fabryka jest możliwym, ale prawdopodobnie nie najlepszym rozwiązaniem tego problemu.

Fafnasty raz powtarza, że taka fabryka, jaką proponowałeś, jest błędnym rozwiązaniem.

Uciekasz od tego faktu a sam sprowokowałeś kłótnie, która odnosi się do tematu owej fabryki na swichach czy tam ifach.

Czyli po prostu mataczysz, ponieważ nie jesteś wartościowym użytkownikiem tego forum a tym bardziej moderatorem z którym warto się liczyć.

edytowany 2x, ostatnio: Mimik59
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)