2013-02-20 31 views
11

Giả sử rằng có hai giao diện kho:Thực hành tốt nhất thực hiện đơn vị của công việc và mô hình kho sử dụng ServiceStack.ORMLite

interface IFooRepository 
{ 
    void Delete(int id); 
} 

interface IBarRepository 
{ 
    void Delete(int id); 
} 

Và một giao diện IUnitOfWork như:

interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
    void Rollback(); 
} 

thực hiện những điều tốt nhất là gì triển khai các giao diện đó bằng ServiceStack.ORMLite để người dùng có thể sử dụng chúng như

MyFooRepository.Delete(4); 
// if an Exception throws here, Bar won't be deleted 
MyBarRepository.Delete(7); 

Hoặc

using (var uow = CreateUnitOfWork()) 
{ 
    MyFooRepository.Delete(4); 
    MyBarRepository.Delete(7); 
    uow.Commit(); //now they are in an transaction 
} 
+0

Tôi khuyên bạn nên tránh sử dụng UOW càng nhiều có thể. Đi xung quanh một giao dịch mở như vậy thường là một thiết kế rất xấu. (Trong các bản sửa đổi trước đó, tôi đã phạm tội với những thứ này) –

Trả lời

9

Không chắc chắn về nhu cầu của bạn cho Repository + UnitOfWork mẫu nhưng tôi nghĩ rằng có một số giải pháp thay thế trong ServiceStack + OrmLite mà giữ mã của bạn 'DRY' trước khi bạn cần để giới thiệu bất kỳ mẫu (đặc biệt nếu bạn' chủ yếu tìm kiếm hỗ trợ Giao dịch/Rollback). Một cái gì đó như dưới đây là nơi tôi sẽ bắt đầu.

public class Foo //POCO for data access 
{ 
    //Add Attributes for Ormlite 
    public int Id { get; set; } 
} 

public class Bar //POCO for data access 
{ 
    //Add Attributes for Ormlite 
    public int Id { get; set; } 
} 

//your request class which is passed to your service 
public class DeleteById 
{ 
    public int Id { get; set; } 
} 

public class FooBarService : MyServiceBase //MyServiceBase has resusable method for handling transactions. 
{ 
    public object Post(DeleteById request) 
    { 
     DbExec(dbConn => 
        { 
         dbConn.DeleteById<Foo>(request.Id); 
         dbConn.DeleteById<Bar>(request.Id); 
        }); 

     return null; 
    } 
} 

public class MyServiceBase : Service 
{ 
    public IDbConnectionFactory DbFactory { get; set; } 

    protected void DbExec(Action<IDbConnection> actions) 
    { 
     using (var dbConn = DbFactory.OpenDbConnection()) 
     { 
      using (var trans = dbConn.OpenTransaction()) 
      { 
       try 
       { 
        actions(dbConn); 
        trans.Commit(); 
       } 
       catch (Exception ex) 
       { 
        trans.Rollback(); 
        throw ex; 
       } 
      } 
     } 
    } 
} 

Một số tài liệu tham khảo ...

https://github.com/ServiceStack/ServiceStack.RedisWebServices - Đoạn mã trên được sửa đổi từ ví dụ này

https://groups.google.com/forum/#!msg/servicestack/1pA41E33QII/R-trWwzYgjEJ - thảo luận về các lớp trong ServiceStack

http://ayende.com/blog/3955/repository-is-the-new-singleton - Ayende Rahien (NHibernate lõi đóng góp) trên mẫu Kho lưu trữ

+1

patternalist, có vẻ là một mẫu tốt – GorillaApe

+0

Trong trường hợp bạn cần sql logic đặc biệt/phức tạp, nơi bạn sẽ đặt chúng? – GorillaApe

+0

Tôi đoán bạn có thể làm nhiều sql logic đặc biệt/phức tạp như bạn muốn trong hành động/hàm được gửi đến phương thức DbExec. Cũng có thể viết một hàm độc lập và truyền nó (hành động/hàm) trong khối. Ngoài ra, ví dụ này có lẽ không phải là cách tiếp cận tốt nhất cho các tình huống phức tạp. – paaschpa

Các vấn đề liên quan