Mam zamiar rozpocząć nowy projekt, który będzie używać Entity Framework (EF) jako ORM do połączenia z SQL Server. Dużo czytałem, aby zrozumieć, jakie są dobre podejścia do pracy z EF w odniesieniu do abstrakcji i ostatecznie sprawiają, że mój kod można przetestować.Czy korzystanie z repozytorium abstrakcji w ramach struktury Entity Framework jest dobre, czy nie?
Problem polega na tym, że im więcej czytasz, tym bardziej jestem zdezorientowany, że staję się z tym wszystkim.
Myślałem że to dobry sposób, aby przejść:
miałem zamiar zejść repozytorium trasy, należy je więc są łatwe do wstrzykiwania poprzez interfejsy i łatwo drwić dla celów testowych, z partii przykładów, które wydaje mi się znaleźć, jest wielu, którzy przysięgają na to podejście. Dla części repozytoriów, które współdziałają z EF, miałem zamiar przejść testy integracyjne, ponieważ w moich repozytoriach nie byłoby logiki biznesowej, przesunąłbym to na klasy Service/Controller, aby sobie z tym poradzić.
Niektórzy mówią, że Repository Wzór jest nieuzasadnione abstrakcji
http://ayende.com/blog/3955/repository-is-the-new-singleton
Były też inne linki, ale nie chciał zalać to pytanie zbyt wiele
I niby dostać to rozumiem, że EF i jego realizacja są w zasadzie abstrakcją, ale wydaje mi się, że jest to konkretna (trafia ona w coś nieobjętego zakresem zastosowania ... DB) Problemem jest dla mnie p używa dla mnie kwestii testowania (przynajmniej w początkowej architekturze), w której prawdopodobnie będę wchodził w interakcję z danymi dotyczącymi danych i jednostką pracy z poziomu mojej usługi, ale wydaje mi się, że łączę logowanie dostępu do danych z logiką biznesową na tym poziomie a potem, jak do cholery mam to sprawdzić?
Wydaje mi się, że czytałem tak dużo, że nie mam teraz jasnego kierunku i nieunikniony blok programistów włączył się. Próbuję szukać podejścia, które jest czyste i mogę testować przeciwko.
AKTUALIZACJA - Rozwiązanie mam zamiar zacząć od
poszedłem nieco inną ścieżkę następnie jeden w odpowiedzi udzielonej przez Simona ale dzięki artykuł, który czytałem, ale on ponownie przedłożony tak ja przeszedł to jeszcze raz. Po pierwsze używam Code First, ponieważ mam istniejącą bazę danych iz jakiegoś powodu nie lubię narzędzi projektantów. Stworzyłem kilka prostych obiektów POCO i kilka mapowań, aby wszystko było proste. Po prostu pokażę jedno POCO/Mapping, a co nie.
POCO
public abstract class BaseEntity<T>
{
[Key]
public T Id { get; set; }
public string Name { get; set; }
public DateTime CreatedOn { get; set; }
}
public class Project : BaseEntity<int>
{
public virtual ICollection<Site> Sites { get; set; }
public bool Active { get; set; }
}
Jednostka interfejsu Work
public interface IUnitOfWork
{
IDbSet<Project> Projects { get; }
void Commit();
}
Kontekst
internal class MyContext : DbContext
{
public MyContext(string connectionString)
: base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ProjectMap());
}
}
Concrete UnitOfWork Kod
public class UnitOfWork : IUnitOfWork
{
readonly MyContext _context;
const string ConnectionStringName = "DBConn";
public UnitOfWork()
{
var connectionString = ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString;
_context = new FosilContext(connectionString);
}
public IDbSet<Project> Projects
{
get { return _context.Set<Project>(); }
}
public void Commit()
{
_context.SaveChanges();
}
}
podstawowy test
var _repo = new UnitOfWork().Projects;
var projects = from p in _repo
select p;
foreach (var project in projects)
{
Console.WriteLine(string.Format("{0} - {1} - {2} - {3})", project.Id, project.Name, project.Active.ToString(), project.CreatedOn.ToShortDateString()));
}
Console.Read();
UnitOfWork jest oczywista, ale w oparciu o konkretny kontekst, mogę stworzyć fałszywy IUnitOfWork i przekazać go w fałszywym IDBSet do testowania . Dla mnie, i to może wrócić, by mnie ugryźć w architekturę, tym bardziej dostaję się do tego, ale nie mam Repo na tym oddalającym się EF (myślę). Jak wyjaśnia artykuł, IDbSet jest odpowiednikiem Repo, więc to, czego używam. Trochę ukrywam swój niestandardowy kontekst za UU, ale zobaczę, jak to wygląda.
To, co teraz myślę, to mogę użyć tego w warstwie usługowej, która będzie zawierała pobieranie danych i reguł biznesowych, ale powinna być testowana, ponieważ mogę podrobić określone elementy EF. Miejmy nadzieję, że uczyni moje kontrolery dość szczupły, ale zobaczymy :)
Nie zapominaj, że jeśli używasz Entity Framework, 'DbContext' _is_ jest podobne do UnitOfWork i' DbSet' _is_ jest podobne do repozytorium. To pytanie, jak sądzę, zachęca do osobistej opinii i może nie być odpowiednie dla Stack Overflow, ale uważam, że jeśli zamierzasz używać Entity Framework, równie dobrze możesz przyjąć schemat. Dalsze pakowanie 'DbContext' i' DbSet's jest naprawdę bardzo cienką abstrakcją dla konkretnej klasy dla łatwości testowania jednostkowego i, do pewnego stopnia, Dependency Injection. –
Dzięki za komentarz. To, czego nie dostaję (jestem bardzo nowy w EF) to wygląd cienkiej warstwy. Oglądałem film o EF i testowaniu, autor wykorzystał IDBSet i wprowadził interfejs IContext, ale z osobną jednostką pracy (te przykłady używały repozytorium), która została przekazana. Cienka warstwa była IDBSet i IContext, ale nawet autor zauważył, że ukrywałeś EF za pomocą tych abstrakcji, które wydawały się dokładnie takie same, jak problem, jaki ludzie mają ze Wzorcem Repozytorium? – Modika
Przenoszę ścianę tekstu do poprzedniej odpowiedzi. Ograniczenia postaci powodują, że formatowanie jest trochę trudne. –