Jag har precis börjat använda NHibernate och är fortfarande på testningsstadiet. Jag har till stor del följt guiderna på http://www.summerofnhibernate.com/ som jag blev tipsad om i en annan tråd. Men nu har jag börjat ta min egen approach istället för att blint följa guiden. Det beror på 2 saker: Tack, då förstår jag lite bättre. Nu ahr jag även strukturerat om koden lite så det blir lättare att hantera. I .Net kan en klass ha en Finalizer. Denna anropas (eventuellt) när systemet städar upp minnet. Det är en slags sista utväg för att lämna tillbaka resurser om någon glömt att anropa Dispose.IDisposable, när behöver jag implementera den?
Så jag har skapat en klass som heter DataLayer vars konstructor ser ut såhär:
<code>
public DataLayer()
{
_session = SessionManager.GetNewSession();
_transactionManager = new TransactionManager(_session);
}
</code>
SessionManager.GetNewSession() är en statisk metod som skapar ett statiskt ISessionFactory objekt (om det inte redan finns) och sedan returnerar en ISession.
Sessionen sparas som ni ser i en _session variabel samt skickas till TransactionManagern som jag använder för att med lite mindre kod hantera transaktioner.
Nu är frågan: Behöver jag disposa sessionen och transactionmanagern? Och hur går jag i så fall till väga för att göra det? Jag har följt guiden http://www.codeguru.com/csharp/.net/net_general/debugginganderrorhandling/article.php/c14173 lite grann men känner mig nästan mera förvirrad efteråt.
Bland annat står det: "The only thing you should do in Dispose() is clean up and free resources. You should not be calling other methods or referencing any other objects."
Vad exakt är "resources" och vad menas med "other objects" är min session ett "annat object" och ska alltså inte disposas?Sv: IDisposable, när behöver jag implementera den?
1. Är objekten IDisposable
2. "Äger" din klass objekten.
TransactionManager är enkelt. Om TransactionManager implementerar IDisposable så måste din klass också göra det och anropa _transactionManager.Dispose()
ISession är klurigare. På din beskriving verkar det som om det är SessionManagern som äger objektet och borde därför vara ansvarig för att frigöra det. Eftersom SessionManager är statisk så implementerar den inte IDisposable men den kanske innehåller en ReleaseSession som gör motsvarande sak. Den metoden skall du isåfall anropa i Dispose(). Finns det ingen sån metod innehåller ISession inte några resurser som behöver frigöras och du behöver ingen Dispose.
>Vad exakt är "resources"
Jag skulle säga att det är globala saker i systemet som det finns begränsat antal av. dvs om du använder dem så kan det hindra andra program från att använda dem. Det kan vara öppna filer, anslutningar till databaser, grafikobjekt mm. Minne är också en resurs men det har en särställning i .Net eftersom det lämnas tillbaka automatiskt när det inte används längre. Sv:IDisposable, när behöver jag implementera den?
Nu är nästa fråga, vad gör
GC.SuppressFinalize(true); ?Sv: IDisposable, när behöver jag implementera den?
Finalizers är dock ganska komplicerade i .Net och ställer till det vid minnesstädningen. SuppressFinalize talar helt enkelt om för systemet att nu har Dispose utförts så Finalizern behöver inte anropas.
(Enligt min åsikt så skall dock en Finalizer endast kasta ett undantag för att uppmärksamma programmeraren på att han glömt Dispose någonstans. Alla andra lösningar är bara sätt att dölja att någon gjort fel.)