nello strato Business Logic di un'applicazione Entity Framework-based, tutti i metodi che agiscono su DB dovrebbe (come ho sentito) da inserire all'interno di:Entity Framework - uso concomitante di contenitori
using(FunkyContainer fc = new FunkyContainer())
{
// do the thing
fc.SaveChanges();
}
Naturalmente, per mia comodità, spesso questi metodi si usano l'un l'altro, per non ripetermi. Il rischio che vedo qui è il seguente:
public void MainMethod()
{
using(FunkyContainer fc = new FunkyContainer())
{
// perform some operations on fc
// modify a few objects downloaded from DB
int x = HelperMethod();
// act on fc again
fc.SaveChanges();
}
}
public int HelperMethod()
{
using(FunkyContainer fc2 = new FunkyContainer())
{
// act on fc2 an then:
fc2.SaveChanges();
return 42;
}
}
io non guardare bene a me, quando si crea il contenitore fc2
, mentre fc
è ancora aperto e non è stato ancora salvato. Quindi questo porta alla mia domanda numero uno:
- È possibile aprire più contenitori contemporaneamente e agire su di essi con noncuranza una pratica accettabile?
sono arrivato a una conclusione, che avrei potuto scrivere un semplice oggetto di guardia in stile come questo:
public sealed class FunkyContainerAccessGuard : IDisposable
{
private static FunkyContainer GlobalContainer { get; private set; }
public FunkyContainer Container // simply a non-static adapter for syntactic convenience
{
get
{
return GlobalContainer;
}
}
private bool IsRootOfHierarchy { get; set; }
public FunkyContainerAccessGuard()
{
IsRootOfHierarchy = (GlobalContainer == null);
if (IsRootOfHierarchy)
GlobalContainer = new FunkyContainer();
}
public void Dispose()
{
if (IsRootOfHierarchy)
{
GlobalContainer.Dispose();
GlobalContainer = null;
}
}
}
Ora l'utilizzo sarebbe come segue:
public void MainMethod()
{
using(FunkyContainerAccessGuard guard = new FunkyContainerAccessGuard())
{
FunkyContainer fc = guard.Container;
// do anything with fc
int x = HelperMethod();
fc.SaveChanges();
}
}
public int HelperMethod()
{
using(FunkyContainerAccessGuard guard = new FunkyContainerAccessGuard())
{
FunkyContainer fc2 = guard.Container;
// do anything with fc2
fc2.SaveChanges();
}
}
Quando il HelperMethod
è chiamato da MainMethod
, il GlobalContainer
è già stata creata, e la sua utilizzato da entrambi i metodi, quindi non c'è alcun conflitto. Inoltre, HelperMethod
può anche essere utilizzato separatamente, quindi crea il proprio contenitore.
Tuttavia, questo mi sembra un enorme eccessivo per me; quindi:
- Questo problema è già stato risolto in forma di classe (IoC?) o almeno di un bel motivo di progettazione?
Grazie.
Non penso che FunkyContainerAccessGuard funzioni. Con MainMethod e HelperMethod condivide lo stesso DbContext e viene eliminato da HelperMethod, ma in questo modo si richiama il metodo SaveChanges dell'oggetto in MainMethod, che genera un'eccezione ObjectDisposed. – mr100
No, HelperMethod non eliminerà il contesto condiviso. –
@ Holen Holterman - hai ragione, mio errore. La guardia è stata eliminata lì, e non il contenitore stesso. – mr100