Black Friday Black Friday
Black Friday výprodej! Až 80 % extra bodů zdarma! Více informací zde
Avatar
Luboš Hnědý:16. září 16:47

Zdravím programuji v .net mvc a používám v EF a DI. Mám zaregistrovaný DBContext. Musím tedy používat metodu Dispose? S DB komunikuj přes managery(repo­sitory, services). Managery také načítam přes DI, přes konstruktor.Takže mám například metodu IQueryable<Model> GetAll(). Její provolání nedělám přímo v controlleru, mám takzvané buildery, které si poté vrátím přes DependencyResolve. Moje otázka je zda mám po provolání zavolat metodu Dispose(myslím, že vím jak funguje, ale nejsem si na 100% pokud mi to někdo osvětlí budu rád :) ), která provolá dispose nad DBContect. Předem díky za jakoukoli radu.

Zkusil jsem: Hledat na internetu, ale jde o dost specifický problém.

Chci docílit: Moje otázka je zda mám po provolání zavolat metodu Dispose.

 
Odpovědět 16. září 16:47
Avatar
Luboš Satik Běhounek
Autoredaktor
Avatar
Odpovídá na Luboš Hnědý
Luboš Satik Běhounek:16. září 17:18

Ten DBContext ti mezi různýma requestama zůstává nebo pro kazdej request vytvaris novej?

Nahoru Odpovědět 16. září 17:18
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Luboš Satik Běhounek
Luboš Hnědý:17. září 7:42

Děkuji ti za odpověď.
Mělo by mi zůstávat stejný, protože si ho předávám přes konstruktor a mám ho v DI. Funguje mi to zhruba takhle:
Mám abstraktní třídu BaseManager - zde mám obecný metody jako GetAll(), Delete() atd.
Mám zde následující kód.

public abstract class BaseManager<TEntity, TContext> : IBaseManager<TEntity> where TEntity : class where TContext : DbContext, new()
{
public BaseService(TContext con)
{
     Con = con;
}

public TContext Con { get; }

A následné použití.

public partial class TestManager : BaseManager<Test, StoreUrbanDBContext>, ITestManager
   {
       public AdvertisementService(DBContext con) : base(con)
       {

       }
   }

   public partial interface ITestManager : IBaseManager<Test>
   {

   }

A takhle si to předám u každýho manageru. Takže by to měl být jeden objekt ne? A to dispose mi ten objekt vlastně uvolní, takže je muj dotaz nesmysl?

Editováno 17. září 7:42
 
Nahoru Odpovědět 17. září 7:42
Avatar
Luboš Satik Běhounek
Autoredaktor
Avatar
Odpovídá na Luboš Hnědý
Luboš Satik Běhounek:17. září 10:50

Pokud ti DB zustava porad otevrena, tak idealni by bylo ten Dispose tam mit (aby se spojeni ukoncilo spojeni treba pri zavirani aplikace apod.), ale nevolat ho nikde rucne, kdyz vlastne to pripojeni zustava mezi pozadavkama.

Nahoru Odpovědět  +1 17. září 10:50
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Luboš Satik Běhounek
Luboš Hnědý:17. září 12:17

Aha chápu! Jenom se teda ještě radši zeptám. Co tedy přesně dělá ten Dispose? U každého objektu něco jiného? U čtení ze souboru například soubor zavře a u DB například ukončí spojení? A ten Dispose se mi automaticky spustí při zavření aplikace? Nebo to musím dodělat?

 
Nahoru Odpovědět 17. září 12:17
Avatar
Luboš Satik Běhounek
Autoredaktor
Avatar
Odpovídá na Luboš Hnědý
Luboš Satik Běhounek:17. září 12:46

Dispose je volano budto kdyz ho nekdo zavola rucne, to je treba i na konci bloku using https://docs.microsoft.com/…ng-statement a nebo kdyz ten objekt maze GC (tam se vola Finalize, ve kterem ten Dispose musis zavolat a nebo muzes pouzit SafeHandle, viz https://docs.microsoft.com/…ting-dispose ).

Jeho ukolem je vycistit vsechny unmanaged data, ktery ta trida vytvorila - pozavirat vsechny otevrene soubory, spojeni do DB, handly na vsechno mozny :) , pripadne treba uvolnit unmanaged pamet, ...
pokud neco takovyho ta trida pouzivala.

Editováno 17. září 12:47
Nahoru Odpovědět 17. září 12:46
https://www.facebook.com/peasantsandcastles/
Avatar
Martin Petrovaj
Překladatel
Avatar
Martin Petrovaj:17. září 13:35

Pokiaľ používaš Dependency Injection, podľa mňa by si sám Dispose volať nemal. To by mal riešiť DI kontajner, v žiadnom prípade nie ty.

Nahoru Odpovědět 17. září 13:35
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Martin Petrovaj
Luboš Hnědý:17. září 14:57

Oběma děkuji za odpověď. Chápu tedy, že metodu Dispose nemám nikdy používat. A mám si ji tedy doprogramovat?
V té třídě BaseManager? Zhruba nějak podle této stránky? - https://docs.microsoft.com/…ting-dispose

 
Nahoru Odpovědět 17. září 14:57
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Luboš Hnědý
Martin Petrovaj:17. září 15:16

Nie že by si nemal Dispose nikdy používať. Toto je jednoducho problém toho, keď sa stavia mrakodrap a my už ideme robiť 5. poschodie, keď na 3. ešte ani nie sú všetky podpery hotové.

Dispose implementujú triedy, ktoré pracujú s tzv. unmanaged resources (napríklad spojenia k súborom, otvorené spojenia po sieti, občas rôzne buffery atď., proste hocičo, čo garbage collector neuprace sám). Je potom nepísanou povinnosťou kódu, ktorý potom s týmito triedami pracuje, aby sa o zavolanie tejto metódy postaral. To sa väčšinou robí tým, že sa s takýmito objektami jednoducho pracuje v using bloku, manuálne sa Dispose volá málokedy.

Tvoj problém je ale v tom, že nie tvojou zodpovednosťou je zavolať na databázovom kontexte Dispose, ale je to logicky povinnosť DI. Tá ten kontext vytvára a spravuje ho, od vzniku po zánik a teda aj Dispose.

Nahoru Odpovědět 17. září 15:16
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Luboš Satik Běhounek
Autoredaktor
Avatar
Odpovídá na Luboš Hnědý
Luboš Satik Běhounek:17. září 15:33

Ano, jestli dobre chapu, ze ta DBContext trida je nejaka tvoje trida, pak by Dispose rozhodne mit mela, ale volat by jsi ji tady v tom pouziti co popisujes nemel, jak jsem psal uz vejs.

Nahoru Odpovědět 17. září 15:33
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Luboš Satik Běhounek
Luboš Hnědý:17. září 15:48

Zase děkuji za supr ujasnění a poslední dotaz. Zde nejde přímo o třídu DBContext. Používám EF DB First. Takže si to do toho DBContextu nemůžu ani zapsat. Ale pro komunikaci s databází používám právě ty Managery a předávám si to přes ten konstruktor. Takže v té třídě BaseManager si zdědím IDispose a doprogramuju si metodu Dispose, kde vlastně zavolám Con.Dispose() ano?

 
Nahoru Odpovědět 17. září 15:48
Avatar
Luboš Satik Běhounek
Autoredaktor
Avatar
Odpovídá na Luboš Hnědý
Luboš Satik Běhounek:17. září 15:59

Ne.
Pokud je ten DBContext nejaka existujici DB trida uz od nejakeho frameworku, tak Dispose vubec neres.
Ani ho nikam nepridavej, ani ho nevolej, ten framework si tohle vsechno resi.

Dispose se resi (v 99% pripadu) jen na te tride, co ma primo drzi ty unmanaged zdroje.

Ja totiz puvodne to pochopil tak, ze ten DBContext je nejaka tvoje trida pro praci s DB.

Editováno 17. září 16:01
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 17. září 15:59
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Luboš Satik Běhounek
Luboš Hnědý:17. září 17:50

Jj je to od entity frameworku. Ale kdyz se do ty tridy podivam jsou tam jenom DbSety. Ale to je teda jedno nemam to resit jo?

 
Nahoru Odpovědět 17. září 17:50
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.