2016-02-01 10 views
5

Der folgende Code scheint dies funktioniert mit:PetaPoco + Arbeitseinheit + Repository-Muster

var unitOfWorkProvider = new PetaPocoUnitOfWorkProvider(); 
var repository = new FakeRepository(); 
var fake = new Fake 
{  
    // etc. 
}; 

using (var uow = unitOfWorkProvider.GetUnitOfWork("BlaConnectionString")) 
{ 
    repository.Insert(uow, fake); 
    uow.Commit(); 
} 

, die schließlich in eine Dienstschicht bewegen kann. Ich würde mich über Feedback freuen, um diesen Code zu verbessern.

public interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
    Database Database { get; } 
} 

public interface IUnitOfWorkProvider 
{ 
    IUnitOfWork GetUnitOfWork(string connectionString); 
} 

public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider 
{ 
    public IUnitOfWork GetUnitOfWork(string connectionString) 
    { 
     return new PetaPocoUnitOfWork(connectionString); 
    } 
} 

public interface IRepository<T> 
{ 
    void Insert(IUnitOfWork unitOfWork, T entity); 
    void Update(IUnitOfWork unitOfWork, T entity); 
    void Delete(IUnitOfWork unitOfWork, T entity); 
    T Fetch(IUnitOfWork unitOfWork, long uid); 
} 

public class PetaPocoUnitOfWork : IUnitOfWork 
{ 
    private readonly Transaction _petaTransaction; 
    private readonly Database _database; 

    public PetaPocoUnitOfWork(string connectionString) 
    { 
     _database = new Database(connectionString); 
     _petaTransaction = new Transaction(_database); 
    } 

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

    public Database Database 
    { 
     get { return _database; } 
    } 

    public void Commit() 
    { 
     _petaTransaction.Complete(); 
    } 
} 

public class FakeRepository : IRepository<Fake> 
{ 
    public void Insert(IUnitOfWork unitOfWork, Fake entity) 
    { 
     unitOfWork.Database.Save(entity); 
    } 

    public void Update(IUnitOfWork unitOfWork, Fake entity) 
    { 
     unitOfWork.Database.Update(entity); 
    } 

    public void Delete(IUnitOfWork unitOfWork, Fake entity) 
    { 
     unitOfWork.Database.Delete(entity); 
    } 

    public FakeJobFact Fetch(IUnitOfWork unitOfWork, long uid) 
    { 
     return unitOfWork.Database.Fetch<Fake>("SELECT * FROM Fakes WHERE [FakeId] = @0", uid).FirstOrDefault(); 
    } 
} 

PS:

ich den Code nach @Plebsori aktuellen Antwort angepasst haben:

public abstract class BaseRepository<T> 
{ 
    protected IDatabase Database 
    { 
     get 
     { 
     return UnitOfWork.Current; 
     } 
    } 

    public void Insert(T entity) 
    { 
     Database.Save(entity); 
    } 

    public void Update(T entity) 
    { 
     Database.Update(entity); 
    } 

    public void Delete(T entity) 
    { 
     Database.Delete(entity); 
    } 
} 

public interface IRepository<T> 
{ 
    void Insert(T entity); 
    void Update(T entity); 
    void Delete(T entity); 
    T Fetch(long uid); 
} 

public interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
    Database Database { get; } 
} 

public interface IUnitOfWorkProvider 
{ 
    IUnitOfWork GetUnitOfWork(string connectionString); 
} 

public class PetaPocoUnitOfWork : IUnitOfWork 
{ 
    private readonly Transaction _petaTransaction; 
    private readonly Database _database; 

    public PetaPocoUnitOfWork(string connectionString) 
    { 
     _database = new Database(connectionString); 
     _petaTransaction = new Transaction(_database); 
    } 

    public void Dispose() 
    { 
     UnitOfWork.Current = null; 
     _petaTransaction.Dispose(); 
    } 

    public Database Database 
    { 
     get { return _database; } 
    } 

    public void Commit() 
    { 
     _petaTransaction.Complete(); 
    } 
} 

public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider 
{ 
    public IUnitOfWork GetUnitOfWork(string connectionString) 
    { 
     if (UnitOfWork.Current != null) 
     { 
     throw new InvalidOperationException("Existing unit of work."); 
     } 

     var petaPocoUnitOfWork = new PetaPocoUnitOfWork(connectionString); 
     UnitOfWork.Current = petaPocoUnitOfWork.Database; 
     return petaPocoUnitOfWork; 
    } 
} 

public static class UnitOfWork 
{ 
    [ThreadStatic] public static IDatabase Current; 
} 
+0

Könnten Sie das näher erläutern, was die "IDatabase" -Schnittstelle sein soll? Auch, waren Sie mit diesem Ansatz zufrieden? – Mathieu

Antwort

6

Sie können oder nicht, aber hier ist, wie ich das Vergehen der Arbeitseinheit entfernt und die Arbeitseinheit von der Schnittstelle.

var unitOfWorkProvider = new PetaPocoUnitOfWorkProvider(); 
var repository = new FakeRepository(); 
var fake = new Fake 
{  
    // etc. 
}; 

using (var uow = unitOfWorkProvider.GetUnitOfWork("BlaConnectionString")) 
{ 
    repository.Insert(fake); 
    uow.Commit(); 
} 

-Code

public interface IUnitOfWorkProvider 
{ 
    IUnitOfWork GetUnitOfWork(string connectionString); 
} 

public static class UnitOfWork 
{ 
    [ThreadStatic] 
    public static IUnitOfWork Current { get; set; } 
} 

public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider 
{ 
    public IUnitOfWork GetUnitOfWork(string connectionString) 
    { 
     if (UnitOfWork.Current != null) 
     { 
      throw new InvalidOperationException("Existing unit of work."); 
     } 
     UnitOfWork.Current = new PetaPocoUnitOfWork(connectionString); 
     return UnitOfWork.Current; 
    } 
} 

public interface IRepository<T> 
{ 
    void Insert(T entity); 
    void Update(T entity); 
    void Delete(T entity); 
    T Fetch(long uid); 
} 

public class PetaPocoUnitOfWork : IUnitOfWork 
{ 
    private readonly Transaction _petaTransaction; 
    private readonly Database _database; 

    public PetaPocoUnitOfWork(string connectionString) 
    { 
     _database = new Database(connectionString); 
     _petaTransaction = new Transaction(_database); 
    } 

    public void Dispose() 
    { 
     UnitOfWork.Current = null; 
     _petaTransaction.Dispose(); 
    } 

    public Database Database 
    { 
     get { return _database; } 
    } 

    public void Commit() 
    { 
     _petaTransaction.Complete(); 
    } 
} 

public abstract class BaseRepository<T> : IRepository<T> 
{ 
    protected IDatabase Db 
    { 
     get 
     { 
      return UnitOfWork.Current; 
     } 
    } 
} 

public class FakeRepository : BaseRepository<T> 
{ 
    public void Insert(Fake entity) 
    { 
     Db.Save(entity); 
    } 

    public void Update(Fake entity) 
    { 
     Db.Update(entity); 
    } 

    public void Delete(Fake entity) 
    { 
     Db.Delete(entity); 
    } 

    public FakeJobFact Fetch(long uid) 
    { 
     return Db.Fetch<Fake>("SELECT * FROM Fakes WHERE [FakeId] = @0", uid).FirstOrDefault(); 
    } 
} 
+0

Ich mag diesen Dank. Ja, die ganze Zeit die Uu zu gehen fühlt sich nicht richtig an. Nur neugierig - stellt der UnitOfWork.Current sicher, dass der Repo nur die UOW nutzt, die Teil des Using Scope ist? Vielen Dank! – cs0815

+1

Das Codebeispiel wurde aktualisiert, um zu werfen, wenn eine andere Arbeitseinheit vorhanden ist. Es wird die verschachtelte Einheit der Arbeiten stoppen. Da es sich bei der Statik jedoch um statische Threads handelt, bedeutet dieses Design, dass mehrere Threads jeweils ihren eigenen Geltungsbereich haben. – Plebsori

+0

Was ist der Zweck von ThreadStatic, wenn Current nicht statisch ist? – cs0815

Verwandte Themen