7

Projekty w moim rozwiązania są ustawione tak:Injecting DbContext do repozytorium biblioteki klas

  • App.Data
  • App.Models
  • App.Web

W App. Dane, używam Entity Framework, aby uzyskać dostęp do moich danych za pomocą paczki Repozytoria, aby uzyskać abstrakcyjną interakcję z nimi. Z oczywistych powodów chciałbym, aby moja App.Web odwoływała się tylko do projektu App.Data, a nie do Entity Framework.

Używam konstruktora iniekcji dać moje Kontrolery odniesienie do repozytorium pojemniku, który wygląda tak:

public interface IDataRepository 
{ 
    IUserRepository User { get; set; } 
    IProductRepository Product { get; set; } 

    // ... 
} 

public class DataRepository : IDataRepository 
{ 
    private readonly AppContext _context; 

    public DataRepository(AppContext context) 
    { 
     _context = context; 
    } 

    // ... 
} 

DataRepository będzie miał AppContext obiekt (która dziedziczy z Entity Framework DbContext), że wszystkie dzieci Repozytoria będą używać do uzyskania dostępu do bazy danych.

W końcu dochodzimy do mojego problemu: Jak używać Instrukcji Konstruktorów na DataRepository biorąc pod uwagę, że jest to biblioteka kodów i nie ma punktu wejścia? Nie mogę załadować AppContext w App.Web, ponieważ wtedy muszę odwołać się do Entity Framework z tego projektu.

A może robię coś głupiego?

+0

Nie jest to odpowiedź na twoje pytanie, ale zamiast definiowania wiele interfejsów repozytorium, spróbuj wyznaczając jeden '' IRepository interfejs, jak wyjaśniono [tutaj] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92). Pozwala to na znacznie większą elastyczność. – Steven

+3

@Steven Dzięki za komentarz. Z tego powodu wolę określone repozytoria: "repozytorium jest częścią modelowanej domeny, a ta domena nie jest generyczna, nie każda jednostka może zostać usunięta, nie każda jednostka może zostać dodana, nie każda jednostka ma repozytorium". http://stackoverflow.com/questions/1230571/advantage-of-creating-a-generic-repository-vs-specific-repository-for-each-obje – ajbeaven

Odpowiedz

12

Możesz zdefiniować klasę RepositoryConnection w App.Data, która działa jako opakowanie do kontekstu i usuwa potrzebę odwołania do EF w App.Web. Jeśli korzystasz z kontenera IoC, możesz kontrolować czas życia klasy RepositoryConnection, aby zapewnić, że wszystkie instancje Repository otrzymują ten sam kontekst. To jest uproszczony przykład ...

public class RepositoryConnection 
{ 
    private readonly AppContext _context; 

    public RepositoryConnection() 
    { 
     _context = new AppContext(); 
    } 

    public AppContext AppContext { get { return _context; } } 
} 

public class DataRepository : IDataRepository 
{ 
    private readonly AppContext _context; 

    public DataRepository(RepositoryConnection connection) 
    { 
     _context = connection.AppContext; 
    } 

// ... 
} 
+0

Ah oczywiście! Awansuj na tego człowieka! – ajbeaven

+0

Jeśli wszystkie klasy mają ten sam kontekst, nikt nie pozbywa się kontekstu EF, który jest zły, bardzo zły. Konteksty EF są zaprojektowane z myślą o tworzeniu, używaniu i usuwaniu. –

+0

@BrunoBrant jesteś absolutnie poprawny - "Kontekst" powinien być tak krótki, jak to tylko możliwe, a ta odpowiedź w pełni to potwierdza. Fakt, że mamy 'RepositoryConnection' do działania jako' 'bridge' między złożeniami, niczego nie zmienia. "RepositoryConnection", a zatem "Context" są rejestrowane ** na żądanie internetowe **. Każdy "RepositoryConnection" (a zatem "Context") będzie istnieć w ramach pojedynczego żądania internetowego i dlatego będzie on żył przez kilka sekund. Zaraz po zakończeniu żądania strony internetowej klasy zarządzane DI zostaną wyłączone z zakresu i będą oznaczone jako "Disposed()". – qujck

Powiązane problemy