1

Wie implementieren Sie die Einheit der Arbeit und Repository-Muster in MVC 5 und EF6? Bisher habe ich keine Notwendigkeit für Arbeitseinheit vermieden, indem ein einzelnes Repository, das in meinen Controller injiziert wurde wie folgt:MVC 5 EF6 Einheit von Arbeit und Repository-Muster

public class ProductController : BaseController 
{ 
    private IShopRepository _repository; 


    public ClassController() 
     : this(new ShopRepository()) 
    { 
    } 

    public ClassController(IShopRepository repository) 
    { 
     _repository = repository; 
    } 


    .... 

} 

Aber jetzt möchte ich den Code Refactoring, so dass ich ein separates Repository für jede Entität haben Geben Sie zB ProductRepository, CustomerRepository usw. und in der Lage sein, mehrere Repositories in einen Controller zu injizieren, während sichergestellt wird, dass derselbe dbcontext verwendet wird.

Wenn Sie das Microsoft-Lernprogramm unter http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application durchlesen, empfehlen die Architekten jetzt, dass das Repository und die Arbeitseinheitsmuster nicht mehr benötigt werden, aber sie bieten kein Beispiel für die Implementierung oder Strukturierung von Repositories in ihren Beispielen.

Einige Leute haben sogar damit begonnen, Repositories in Dienste umzubenennen?

Wie strukturieren Sie Ihre Repositorys und implementieren Sie die Arbeitseinheit in MVC5 mit EF6, vielleicht mit einem IOC wie Unity? Oder was ist eine andere Lösung?

Ich arbeite in den folgenden Zeilen, aber nicht sicher, ob es die beste Lösung ist und wie füge ich Einheit der Arbeit hinzu?

public class ShopContext : DbContext 
{ 
    public ShopContext() : base("name=ShopContext") 
    { 
    } 

    public DbSet<Product> Products { get; set; } 
    public DbSet<Customer> Customers { get; set; } 
    ... 

} 


public interface IProductRepository 
{ 
    IEnumerable<Product> GetAll(); 
    ... 
} 


public interface ICustomerRepository 
{ 
    IEnumerable<Customer> GetAll(); 
    ... 
} 

public class ProductRepository : IDisposable, IProductRepository 
{ 
    private ShopContext _context; 

    public ProductRepository() 
    { 
    _context = new ShopContext(); 

    } 

    public IEnumerable<Product> GetAll() 
    { 
     return _context.Products; 
    } 

    // Other methods not displayed 

    protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (_context != null) 
      { 
       _context.Dispose(); 
       _context = null; 
      } 
     } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

} 

public class CustomerRepository : IDisposable, ICustomerRepository 
{ 
    private ShopContext _context; 

    public CustomerRepository() 
    { 
     _context = new ShopContext(); 

    } 

    public IEnumerable<Customer> GetAll() 
    { 
     return _context.Customers; 
    } 

    // Other methods not displayed 

    protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (_context != null) 
      { 
       _context.Dispose(); 
       _context = null; 
      } 
     } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 


public class ProductsController : BaseController 
{ 

    private IProductRepository _productRepository; 
    private ICustomerRepository _customerRepository; 


    public ProductsController() 
     : this(new ProductRepository(), new CustomerRepository()) 
    { 
    } 

    public ProductsController(IProductRepository productRepository, ICustomerRepository customerRepository) 
    { 
     _productRepository = productRepository; 
     _customerRepository = customerRepository; 

    } 

    // Other controller methods not shown. 
} 

Beispielcode wäre hilfreich.

+0

Das ist eine lange Frage haben Sie einige Ideen aus 'Codeprojekt' versucht – KhawajaAtteeq

+3

EF6 implementiert Einheit der Arbeit und Repository-Muster. Dein 'DbContext' ist deine Arbeitseinheit. Jedes 'DbSet ' ist ein Repository.So können Sie einfach Ihren Dbcontext in Ihren Controller injizieren. – Thomas

+0

@Thomas. Sie sagen also, dass ich keine separaten Repositories brauche. Wenn dies der Fall ist, organisiere ich meine Abfragen. Idealerweise möchte ich sie in separaten Dateien aufbewahren - das Erstellen von Repositories ermöglicht mir dies. Etwas Code wäre nützlich, um zu erklären, was Sie meinen. – adam78

Antwort

3

Das beste Arbeits Beispiel ist die Serie von Herrn Mittal bei codeproject finden er Entity Framework, Generic Repository pattern und Unit of Work verwendet. mit ihm Schritt halten Sie kennen lernen, wie das alles hier funktioniert der Link Mittal Series

0

Wie @Thomas bereits in den Kommentaren erklärt hat, glaube ich, was du bist, nachdem hier eine Dienstschicht eher als eine Repository. Die zwei Begriffe werden oft sehr synonym verwendet, aber sie sind nicht dasselbe.

Das Repository-Muster soll eine Abstraktion der Datenbank bereitstellen, damit sich die Datenbank ändern kann, ohne den restlichen Code zu beeinträchtigen. Der DBContext in EF6 macht das bereits für Sie, da Sie beispielsweise eine Tabelle namens One Thing haben können, die jedoch einer Klasse mit einem anderen Namen zugeordnet ist. Der DBContext implementiert das Muster der Arbeitseinheit auch bereits, da es alle Aktionen in einer einzigen Transaktion ausführt, bis Sie SaveChanges/SaveChangesAsync im Kontext aufrufen.

Die Serviceschicht stellt dann Methoden für die Benutzerschnittstellenebene bereit. Dazu ruft es die Methoden aus dem Repository auf.

Mit einem einfachen Modell scheint es, als wären die Service-Schicht und das Repository identisch, aber Ihr Repository würde normalerweise einem Geschäftsobjekt (z. B. einem Kontakt) zugeordnet, wo Ihre Service-Schicht eine Anzahl von Objekten einkapseln könnte eine Kundengeschäftseinheit, die beim Speichern Daten in den Contact- und CustomerProfile-Repositorys speichert), mithilfe einer Arbeitseinheit, um sicherzustellen, dass beide Änderungen festgeschrieben oder zusammen rückgängig gemacht werden.

Diese excellent existing stack overflow answer by @ken2k geht in viel mehr ins Detail.