3

我一直在尋找一些博客帖子,試圖創建一個適合以下要求的解決方案,但我似乎無法將它們拼湊在一起。希望完全有人可以幫忙。MVC倉庫與工作單元,自動映射器和通用倉庫

我一直在使用使用Automapper接口庫模式......這裏有一個下調例如:

public class BookingRepository : IBookingRepository 
{ 
    Entities context = new Entities(); 

    public IEnumerable<BookingDto> GetBookings 
    { 
     get { return Mapper.Map<IQueryable<Booking>, IEnumerable<BookingDto>>(context.Bookings); } 
    } 

    public BookingDto GetBookingWithProduct(Guid bookingId) 
    { 
     return Mapper.Map<BookingDto>(context.Bookings.Include(c => c.Products).SingleOrDefault(c => c.BookingId == bookingId)); 
    } 

    public void Update(BookingDto bookingDto) 
    { 
     var booking = Mapper.Map<Booking>(bookingDto); 
     context.Entry(booking).State = EntityState.Modified; 
    } 

    public void Save() 
    { 
     context.SaveChanges(); 
    } 

    public void Dispose() 
    { 
     context.Dispose(); 
    } 
} 

public interface IBookingRepository : IDisposable 
{ 
    IEnumerable<BookingDto> GetBookings { get; } 
    BookingDto GetBooking(Guid bookingId); 
    void Update(BookingDto bookingDto); 
    void Save(); 
} 

隨着不同的實體一個單獨的存儲庫,例如

public class ProductRepository : IProductRepository 
{ 
    Entities context = new Entities(); 

    public IEnumerable<ProductDto> GetProducts 
    { 
     get { return Mapper.Map<IQueryable<Product>, IEnumerable<ProductDto>>(context.Products); } 
    } 

    public ProductDto GetProductWithDesign(int productId) 
    { 
     return Mapper.Map<ProductDto>(context.Products.Include(c => c.Designs).SingleOrDefault(c => c.ProductId == productId)); 
    } 

    public void Update(ProductDto productDto) 
    { 
     var product = Mapper.Map<Product>(productDto); 
     context.Entry(product).State = EntityState.Modified; 
    } 

    public void Save() 
    { 
     context.SaveChanges(); 
    } 

    public void Dispose() 
    { 
     context.Dispose(); 
    } 
} 

public interface IProductRepository : IDisposable 
{ 
    IEnumerable<ProductDto> GetProducts { get; } 
    ProductDto GetProduct(int productId);  
    void Update(ProductDto productDto); 
    void Save(); 
} 

然後在我的控制器中,我使用的庫如下:

public class HomeController : Controller 
{ 
    private readonly IBookingRepository bookingRepository; 
    private readonly IProductRepository productRepository; 

    public HomeController() : this(new BookingRepository(), new ProductRepository()) { } 
    public HomeController(IBookingRepository bookingRepository, IProductRepository productRepository) 
    { 
     this.bookingRepository = bookingRepository; 
     this.productRepository = productRepository; 
    } 

    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 

     if (disposing && this.bookingRepository != null) 
      this.bookingRepository.Dispose(); 

     if (disposing && this.productRepository != null) 
      this.productRepository.Dispose(); 

    } 
} 

因此,現在我希望創建一個工作單元來抽象這些存儲庫並共享上下文,併爲重複操作(保存和更新)創建一個通用存儲庫,同時記住我正在傳遞Dtos和映射到實體對象。我很難理解如何將它們結合在一起。

此外,我已經看到了這個帖子

Repository pattern with generics and DI

其中指出:「你不應該有除了你的通用倉庫等庫接口」和自定義查詢「應該擁有自己的(通用)抽象:」這是增加了我的勞累過度的大腦的另一個複雜因素,因爲我的存儲庫將具有使用包含語句返回複雜鏈接對象的自定義查詢,因爲禁用了「延遲加載」。

所以我準備好被擊落,並告訴我這是錯誤的方式,但會感謝任何方向。

在此先感謝。

回答

5

不要使用普通的倉庫。他們都是抽象的抽象。問問自己,通過使用抽象並不能真正抽象出什麼東西,你會得到什麼好處?您可以直接在這些情況下使用您的OR/M。

我的意思是任何公開IQueryable<T>都會強制用戶瞭解底層OR/M所具有的弱點。例子:orm如何處理延遲加載?我如何急切地加載相關實體?如何創建IN子句?

如果您真的想要使用存儲庫模式,請將其與規範模式一起使用(您可以繼續使用通用存儲庫)或創建特定於每個根聚合的存儲庫。

我的博客上講述它:http://blog.gauffin.org/2013/01/repository-pattern-done-right/

+0

我覺得你的文章很有趣,但看起來你實際上正在展示如何創建一個通用庫。 – reddy 2014-06-04 06:52:58

+0

@Joey:重要的區別是我不直接使用它,而是繼承它。 – jgauffin 2014-06-04 07:47:47

+0

這很有道理,謝謝 – reddy 2014-06-04 07:50:33

0

我通常在這種情況下,做的是創建一個抽象基類存儲庫這樣的:

public abstract class BaseRepository<T> : IRepository<T> 
{ 
    Entities context = new Entities(); 

    public virtual T GetAll() 
    { 
     return context.Set<T>(); 
    } 
    // Add base implementation for normal CRUD here 
} 

如果你不需要特殊的查詢,那麼你就需要建立特殊的接口和類(但你當然可以提高可讀性)。所以,你會使用,例如:

var bookingsRepo = new BaseRepository<BookingsDto>(); 
var allBookings = bookingsRepo.GetAll(); 

如果你需要一些特殊的查詢,您創建一個擴展底座接口的接口:

public interface IProductRepository : IRepository<Product> 
{ 
    Product GetSpecialOffer(); 
} 

然後創建類:

public class ProductRepository : BaseRepository<Product>, IProductRepository 
{ 
    public Product GetSpecialOffer() 
    { 
     // your logic here 
    } 
} 

這樣,您只需指定最少數量的特殊情況,同時依賴基本抽象實現來處理所有事情。

我加virtual到基本方法,因爲我總是喜歡給派生類重寫的東西的能力...

+0

嗨Tallmaris ...感謝您的答覆......你會因此如何解釋這個事實,該庫正在返回的DTO,而不是實體對象。我需要Generic存儲庫以某種方式使用Automapper來返回Dtos。 – ledragon 2013-05-01 12:32:24

+0

我相信是這樣的,你可以使用AutoMapper來在你的對象之間前後映射。 – Tallmaris 2013-05-01 13:15:43