Obecnie projektuję rozwiązanie n-tier, które wykorzystuje Entity Framework 5 (.net 4) jako swoją strategię dostępu do danych, ale martwię się, jak włączyć wstrzykiwanie zależności, aby uczynić go testowalnym / elastycznym.
Mój obecny układ rozwiązania jest następujący (moje rozwiązanie nazywa się Alcatraz):
Alcatraz.WebUI : Projekt strony internetowej asp.net, interfejs użytkownika, odwołuje się do projektów Alcatraz.Business i Alcatraz.Data.Models .
Alcatraz.Business : Projekt biblioteki klas, zawiera logikę biznesową, odwołuje się do projektów Alcatraz.Data.Access , Alcatraz.Data.Models
Alcatraz.Data.Access : Projekt biblioteki klas, zawierający AlcatrazModel.edmx i AlcatrazEntities
DbContext, odwołuje się do projektów Alcatraz.Data.Models .
Alcatraz.Data.Models : Projekt biblioteki klas, zawiera POCO dla modelu Alcatraz, bez odniesień.
Moja wizja działania tego rozwiązania polegałaby na tym, że interfejs sieciowy tworzyłby repozytorium w bibliotece biznesowej. Repozytorium to miałoby zależność (za pośrednictwem konstruktora) ciągu połączenia (nie AlcatrazEntities
instancji). Interfejs WWW znałby parametry połączenia z bazą danych, ale nie to, że był to łańcuch połączenia struktury encji.
W projekcie biznesowym:
public class InmateRepository : IInmateRepository
{
private string _connectionString;
public InmateRepository(string connectionString)
{
if (connectionString == null)
{
throw new ArgumentNullException("connectionString");
}
EntityConnectionStringBuilder connectionBuilder = new EntityConnectionStringBuilder();
connectionBuilder.Metadata = "res://*/AlcatrazModel.csdl|res://*/AlcatrazModel.ssdl|res://*/AlcatrazModel.msl";
connectionBuilder.Provider = "System.Data.SqlClient";
connectionBuilder.ProviderConnectionString = connectionString;
_connectionString = connectionBuilder.ToString();
}
public IQueryable<Inmate> GetAllInmates()
{
AlcatrazEntities ents = new AlcatrazEntities(_connectionString);
return ents.Inmates;
}
}
W interfejsie internetowym:
IInmateRepository inmateRepo = new InmateRepository(@"data source=MATTHEW-PC\SQLEXPRESS;initial catalog=Alcatraz;integrated security=True;");
List<Inmate> deathRowInmates = inmateRepo.GetAllInmates().Where(i => i.OnDeathRow).ToList();
Mam kilka powiązanych pytań dotyczących tego projektu.
Czy ten projekt ma w ogóle sens pod względem możliwości Entity Frameworks? Słyszałem, że środowisko Entity już używa wzorca Unit-of-work, czy po prostu niepotrzebnie dodaję kolejną warstwę abstrakcji?
Nie chcę, aby mój interfejs WWW komunikował się bezpośrednio z Entity Framework (a nawet odwoływał się do niego w tym zakresie), chcę, aby cały dostęp do bazy danych przechodził przez warstwę biznesową, ponieważ w przyszłości będę mieć wiele projektów korzystających z tej samej warstwy biznesowej (usługa sieci web, aplikacja systemu Windows itp.). Chcę mieć łatwą konserwację / aktualizację dzięki logice biznesowej w jednym centralnym obszarze. Czy to odpowiedni sposób na osiągnięcie tego?
Czy warstwa biznesowa powinna nawet zawierać repozytoria, czy powinna zawierać się w warstwie dostępu? Jeśli ich położenie jest w porządku, to czy przekazywanie ciągu połączenia jest dobrą zależnością do założenia?
Dziękujemy za poświęcenie czasu na czytanie!
DbContext
jako swoją zależność. Klasy biznesowe mają zależności jako repozytoria. W przypadku wstrzykiwania zależności robię to ręcznie (więc rozumiem, co się dzieje). Powodem, dla którego chcę ustawić parametry połączenia,DbContext
jest shardowanie bazy danych, więc w niektórych przypadkach muszę mieć strukturę encji, aby połączyć się z różnymi bazami danych (o tej samej strukturze). Czy dobrze cię rozumiem?