Ho una semplice classe che è destinata ad essere un semplice POCO: contiene solo dati. Con una sola eccezione: contiene una raccolta di note. Voglio caricare pigro questa raccolta in modo che non debba recuperare le note su pagine che non ne hanno bisogno. Lo stub per questo è questo:Caricamento pigro della raccolta: come ottenere gli articoli?
public class MyDTOClass
{
private ICollection<Note> _notes = null;
public ICollection<Note> Notes
{
get
{
if(_notes == null)
{
// Get an INoteRepository and initialize the collection
}
return _notes;
}
}
}
Ora, mi chiedo come procedere da qui. È un'applicazione ASP.net MVC e uso Dependency Injection per iniettare gli IRepositories nelle classi che ne hanno bisogno, ad esempio i miei controller. Ma siccome questa classe qui dovrebbe essere un DTO veramente semplice, sono riluttante a iniettarvi un INoteRepository, anche perché il chiamante non dovrebbe preoccuparsi o preoccuparsi del fatto che questo è pigro-caricato.
Quindi sto pensando di avere un'altra classe nel mio modello che contiene un INoteRepository.
public class MyDataAccessClass
{
private INoteRepository _noteRepo;
// Inject is part of Ninject and makes sure I pass the correct
// INoteRepository automatically
[Inject]
public MyDataAccessClass(INoteRepository noteRepository)
{
_noteRepo = noteRepository;
}
public IEnumerable<Note> GetNotes(int projectId)
{
return _noteRepo.GetNotes(projectId);
}
}
Questo funzionerebbe ovviamente, ma mi chiedo se questa è l'architettura corretta? Accoppiato il DTOClass semplice a un'altra classe di accesso ai dati e probabilmente anche al mio meccanismo DI (poiché ho bisogno di creare un'istanza della classe Data Access nel getter di Notes).
Lo faresti diversamente? C'è un modo migliore per farlo, anche tenendo presente che utilizzo già Ninject?
Suppongo che questo non sia più un POCO o un DTO poiché ora contiene la logica, ma va bene. Voglio che a compaia come come un POCO per il chiamante esterno, quindi mi piace avere una proprietà "Note" piuttosto che metodi come "GetNotesForProject" su questa o altre classi.
La mia soluzione attuale è davvero brutta, in quanto ho bisogno di ottenere il kernel Ninject da MvcApplication e usarlo per far ruotare la classe ProjectDataProvider che prende un INoteRepository nel suo costruttore, per evitare di dover mettere il file INoteRepository da qualche parte nel mio " DTO "-Class:
public ICollection<Note> Notes
{
get
{
if(_notes == null)
{
var app = HttpContext.Current.ApplicationInstance as MvcApplication;
if (app == null)
throw new InvalidOperationException("Application couldn't be found");
var pdp = app.Kernel.Get<ProjectDataProvider>();
_notes = new List<Note>(pdp.GetNotes(Id));
}
return _notes;
}
}
Edit: aperto una taglia. Ignoriamo la terminologia di "POCO" e "DTO", mi rifatterò di conseguenza. Quindi si tratta di: Come dovrebbe apparire il codice Lazy-Loading in una situazione del genere e posso/dovrei evitare di passare INoteRepository nel MyDTOClass?
Questa è la migliore risposta IMO, fornisce la soluzione e non rende intrinsecamente dipendente la sua classe DTO su un IRepository, sono sicuro di averlo visto questo modello implementato in modo riutilizzabile sia come ILazy o AbstractLazy . –
Ya .. Penso che questo io s esattamente ciò che Lazy in. Net 4 fare. –
madaboutcode
Sì, questo è il metodo che userei pure. Programmazione funzionale 4tw. =) –