В настоящее время я разрабатываю n-уровневое решение, которое использует Entity Framework 5 (.net 4) в качестве стратегии доступа к данным, но беспокоюсь о том, как включить внедрение зависимостей, чтобы сделать его тестируемым / гибким.
Моя текущая схема решения выглядит следующим образом (мое решение называется Alcatraz):
Alcatraz.WebUI : проект веб-формы asp.net, интерфейс пользователя, ссылки на проекты Alcatraz.Business и Alcatraz.Data.Models .
Alcatraz.Business : проект библиотеки классов, содержит бизнес-логику, ссылки на проекты Alcatraz.Data.Access , Alcatraz.Data.Models
Alcatraz.Data.Access : проект библиотеки классов, содержит AlcatrazModel.edmx и AlcatrazEntities
DbContext, ссылается на проекты Alcatraz.Data.Models .
Alcatraz.Data.Models : проект библиотеки классов, содержит POCO для модели Alcatraz, без ссылок.
Мое видение того, как это решение будет работать, заключается в том, что web-интерфейс мог бы создавать репозиторий в бизнес-библиотеке. Этот репозиторий будет иметь зависимость (через конструктор) от строки соединения (не AlcatrazEntities
экземпляра). Веб-интерфейс знал бы строки подключения к базе данных, но не то, чтобы это была строка подключения структуры сущностей.
В бизнес-проекте:
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;
}
}
В веб-интерфейсе:
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();
У меня есть несколько связанных вопросов об этом дизайне.
Имеет ли этот дизайн смысл с точки зрения возможностей Entity Frameworks? Я слышал, что Entity Framework уже использует шаблон Unit-of-Work, я просто излишне добавляю еще один слой абстрактных данных?
Я не хочу, чтобы мой веб-интерфейс напрямую связывался с Entity Framework (или даже ссылался на него), я хочу, чтобы весь доступ к базе данных проходил через бизнес-уровень, поскольку в будущем у меня будет несколько проектов, использующих один и тот же бизнес-уровень. (веб-сервис, приложение Windows и т. д.), и я хочу, чтобы его было легко поддерживать / обновлять, располагая бизнес-логику в одной центральной области. Это подходящий способ для достижения этого?
Должен ли бизнес-уровень даже содержать репозитории или он должен содержаться на уровне доступа? Если там, где они находятся, все в порядке, является ли передача строки соединения хорошей зависимостью?
Спасибо, что нашли время, чтобы прочитать!
DbContext
как свою зависимость. Бизнес-классы имеют репозитории в качестве зависимости. Для внедрения зависимости я делаю это вручную (поэтому я понимаю, что происходит). Причина, по которой я хочу установить строку подключения,DbContext
заключается в том, что я использую сегментирование базы данных, поэтому в некоторых случаях мне нужна структура сущностей для подключения к различным базам данных (с одинаковой структурой). Я правильно тебя понимаю?