Pereiti prie turinio

Inversion of Control ir Repository pattern


Rekomenduojami pranešimai

Sveiki, darau ce tokia programa savo malonumui ir truputi uzsstrigau. Taigi turiu "Visual Studio solution" kuri turi savije 3 atskirus layer'ius ((projektus)Presentation, Domain, Persistence). Kiekvienas layeris patalpintas i savo assembly.

Presentation ir Persistence layeris referencina Domain layeri.

 

Presentation layer:

WPF application, turi keleta texto ivedimo lauku (Name, Surname ir t.t.) kurie subindinti su atitinkamomis property ir kai vartotojas paspaudzia migtuka (CreateAccount). ViewModel'ije kvieciamas sitas metodas.

http://i61.tinypic.com/25aj6g0.jpg

 

accountRepository siame metode yra Interface fieldas IAccountRepository kuris atrodo sitaip:

 

http://i58.tinypic.com/s6jgow.jpg

 

Persistence layer:

Inheretina Interface IAccountRepository ir implementuoja jo metoda.

 

http://i62.tinypic.com/becy8m.jpg

 

As noriu kviesti savo IAccountRepository Interface metoda ir taip pasiustu sukurta Account'a i Persistence layeri o ten account'as butu ivestas i duomenu baze. Kadangi Domain layeris savije nereferencina nei Persistence nei Presentation layerio truputi pastrigau sitoje vietoje ir neismastau kaip pasiusti duomenis. Dabar jei viska darau pagal taip kaip ce nupastinau tai gaunu "NullReferenceException" ties 'accountRepository.SaveAccount(account);

 

Visas kodas ce: https://github.com/Donatasinfo/AutoDeals

PS. Jei kasnors ce nesavo vietoje irgi noretusi isgirsti komentaru. Isanksto dekoju uz atsakymus.

 

 

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Aš tai tingiu atsakinėti į kvailus klausimus, bet supaprastinsiu klausimą, kad kitiems norintiems būtų paprasčiau susigaudyti, nes turi nuostabų talentą prirašyti daug š ir nieko nepasakyti:

 

"Kodėl kviečiant uninitialized objekto metodą (t.y. object = null) gaunu NullReferenceException?"

Redagavo Deviltry
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Kas yra NullReferenceException as zinau, esme ta, kad as ce viska initializines (matomai ne) bet man trace nieko neparodo, InnerException = null. Tikrai neklausciau jei nebuciau isbandes. Man idomu ties kuria vieta ten null nes as pvz i accountRepository.SaveAccount(account); vietoi account buvau irases (new Account{name = ir t.t.}) Vistiek gaudavau null. O klausimas tai ce nekvailas. As nekalusiau delko gaunu null, sita pats issiaiskinsiu as klausiau kaip man nusiusti duomenis per interface i kita projekta (repository layer) jeigu mano repository priklauso nuo domain (domain neturi reference i repository o duomenis siunciami turi buti is jo).

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Kas yra NullReferenceException as zinau, esme ta, kad as ce viska initializines (matomai ne) bet man trace nieko neparodo, InnerException = null. Tikrai neklausciau jei nebuciau isbandes. Man idomu ties kuria vieta ten null nes as pvz i accountRepository.SaveAccount(account); vietoi account buvau irases (new Account{name = ir t.t.}) Vistiek gaudavau null. O klausimas tai ce nekvailas. As nekalusiau delko gaunu null, sita pats issiaiskinsiu as klausiau kaip man nusiusti duomenis per interface i kita projekta (repository layer) jeigu mano repository priklauso nuo domain (domain neturi reference i repository o duomenis siunciami turi buti is jo).

Per interfeisą tu nieko nenusiųsi, interfeisas tik aprašo, kokius metodus turės klasė, kuri tą interfeisą implementina.

 

Pas tave null ne account, o pats accountRepository. Nes tu jį tik declarini ir niekada nieko jam nei prisikiri, nei jį inicializuoji, tavo accountRepository yra null. Ant šitos "SaveAccount" eilutės užsidedi breakpointą, nes čia klaida pareina, ir pasiinspectini kintamuosius.

 

Blogai mokaisi. Nėkiek nesuprasdamas IoC iškart pradedi daryti kažkokį darbą. Reikėjo nuo šito pradėti: http://pastebin.com/zeD35wdz

 

19 eil. apsirašai savo Repository interfeisą

 

24 ir 32 eil. - dvi skirtingos to interfeiso implementacijos - viena darbui su MS SQL duomenų baze, kita - su Postgre SQL.

 

40 eil. - kokia Worker klasė, kuri dirbs su IRepository. Tai reiškia ne su interfeisu, o su pačia implementacija. Tad 9 ir 11 savo Worker klasei paduodame ne interfeisą (var repo = new IRepo() waaat, net nesikompiliuotų), o klasę, kuri tą intefeisą implementuoja - t.y. new MSSQLRepo() ar new PostgreSQLRepo().

 

IRepo repository turi vistiek būti normali klasė. Vien parašyti IInterface neužtenka, vistiek turi jam priskirti naują ar egzistuojančią klasę su 'new RealiKlasė()', magiškai niekas ten neatsiras.

 

Kaip matai naudojami Interfeisai tam, kad būtų labai lengva pakeisti didelę posistemę - pereini nuo vienos duomenų bazės prie kitos = parašai naują IRepo implementaciją, visų Worker klasių kaitalioti nereikia.

 

Realiam gyvenime interfeisai naudojami dėl testavimo, kad būtų lengva paduoti savo mock'ą, tokios rimtos implementacijos vargiai kada besikeičia

 

Tei va, dabar arba rankomis savo RegistrationFormViewModel konstruktoriuje ( https://github.com/Donatasinfo/AutoDeals/blob/master/AutoDeals.Presentation/ViewModels/RegistrationFormViewModel.cs#L22 ) prirašai accountRepository = new AccountRepository(), arba susikonfigūruoji kokį dependency injectorių, kad į IRepo automatiškai injectintų tavo AccountRepository klasę. Mano laikais populiariausi buvo Ninject ir CastleWindsor. Tačiau dabar darbe visą laiką rašome paprastesnius home made injectorius, nes šitie turi labai labai daug nereikalingo bloat ir noticable performance hit.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Per interfeisą tu nieko nenusiųsi, interfeisas tik aprašo, kokius metodus turės klasė, kuri tą interfeisą implementina.

 

Pas tave null ne account, o pats accountRepository. Nes tu jį tik declarini ir niekada nieko jam nei prisikiri, nei jį inicializuoji, tavo accountRepository yra null. Ant šitos "SaveAccount" eilutės užsidedi breakpointą, nes čia klaida pareina, ir pasiinspectini kintamuosius.

 

Blogai mokaisi. Nėkiek nesuprasdamas IoC iškart pradedi daryti kažkokį darbą. Reikėjo nuo šito pradėti: http://pastebin.com/zeD35wdz

 

19 eil. apsirašai savo Repository interfeisą

 

24 ir 32 eil. - dvi skirtingos to interfeiso implementacijos - viena darbui su MS SQL duomenų baze, kita - su Postgre SQL.

 

40 eil. - kokia Worker klasė, kuri dirbs su IRepository. Tai reiškia ne su interfeisu, o su pačia implementacija. Tad 9 ir 11 savo Worker klasei paduodame ne interfeisą (var repo = new IRepo() waaat, net nesikompiliuotų), o klasę, kuri tą intefeisą implementuoja - t.y. new MSSQLRepo() ar new PostgreSQLRepo().

 

IRepo repository turi vistiek būti normali klasė. Vien parašyti IInterface neužtenka, vistiek turi jam priskirti naują ar egzistuojančią klasę su 'new RealiKlasė()', magiškai niekas ten neatsiras.

 

Kaip matai naudojami Interfeisai tam, kad būtų labai lengva pakeisti didelę posistemę - pereini nuo vienos duomenų bazės prie kitos = parašai naują IRepo implementaciją, visų Worker klasių kaitalioti nereikia.

 

Realiam gyvenime interfeisai naudojami dėl testavimo, kad būtų lengva paduoti savo mock'ą, tokios rimtos implementacijos vargiai kada besikeičia

 

Tei va, dabar arba rankomis savo RegistrationFormViewModel konstruktoriuje ( https://github.com/D...iewModel.cs#L22 ) prirašai accountRepository = new AccountRepository(), arba susikonfigūruoji kokį dependency injectorių, kad į IRepo automatiškai injectintų tavo AccountRepository klasę. Mano laikais populiariausi buvo Ninject ir CastleWindsor. Tačiau dabar darbe visą laiką rašome paprastesnius home made injectorius, nes šitie turi labai labai daug nereikalingo bloat ir noticable performance hit.

 

Dekui, tikrai padejai. Perdaug ilgai man sitas strigo. As jau kai declarinau interface ir nepriskyriau jam jokios klases tas jau atrode keista, buvo aisku, kad turi priskirti ta klase kuri inheretina IAccountRepository. Tik niekaip neisgalvojau kaip ta padaryti jei neturiu reference i persistence layer'i. As visada zinojau apie dependency injectorius, man idomu kaip jie veikia, nenoriu naudoti to ko nesuprantu. Kas del sito app tai ce as siaip retkarciais dadedu kanors, bet rasau del mokinimosi tikslu sau :)

Redagavo highontrance
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

  • Prisijunk prie bendruomenės dabar!

    Uždarbis.lt nariai domisi verslo, IT ir asmeninio tobulėjimo temomis, kartu sprendžia problemas, dalinasi žiniomis ir idėjomis, sutinka būsimus verslo partnerius ir dalyvauja gyvuose susitikimuose.

    Užsiregistruok dabar ir galėsi:

    ✔️ Dalyvauti diskusijose;

    ✔️ Kurti naujas temas;

    ✔️ Rašyti atsakymus;

    ✔️ Vertinti kitų žmonių pranešimus;

    ✔️ Susisiekti su bet kuriuo nariu asmeniškai;

    ✔️ Naudotis tamsia dizaino versija;

    ir dar daugiau.

    Registracija trunka ~30 sek. ir yra visiškai nemokama.

  • Naujausios temos

  • Karštos temos

×
×
  • Pasirinkite naujai kuriamo turinio tipą...