diff --git a/Source/TrackableEntities.Patterns.EF.6/UnitOfWork b/Source/TrackableEntities.Patterns.EF.6/UnitOfWork new file mode 100644 index 00000000..8864d25b --- /dev/null +++ b/Source/TrackableEntities.Patterns.EF.6/UnitOfWork @@ -0,0 +1,99 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +/// +/// General unit of work for committing changes across one or more repositories. +/// Inherit from this class to supply a specific DbContext. +/// Add a property for each respository for which unit of work must be done. +/// +public abstract class UnitOfWork : IUnitOfWork, IUnitOfWorkAsync, IDisposable +{ + private readonly IRepositoryFactory _repositoryFactory; + private bool _disposed; + + /// + /// Constructs a new general unit of work. + /// + protected UnitOfWork() { } + + /// + /// Constructs a new general unit of work. + /// + /// Entity Framework DbContext-derived class. + protected UnitOfWork(DbContext context, IRepositoryFactory repositoryFactory) + { + _repositoryFactory = repositoryFactory; + Context = context; + } + + /// + /// Gets the DbContext for the unit of work. + /// + protected DbContext Context { get; set; } + + /// + /// Disposes the DbContext. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected T GetRepository() + { + return _repositoryFactory.GetRepository(); + } + + /// + /// Disposes the DbContext. + /// + /// True to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + if (disposing) Context.Dispose(); + _disposed = true; + } + + /// + /// Saves changes made to one or more repositories. + /// + /// The number of objects saved. + public virtual int SaveChanges() + { + if (_disposed) + throw new ObjectDisposedException("UnitOfWork"); + return Context.SaveChanges(); + } + + /// + /// Saves changes made to one or more repositories. + /// + /// A task that represents the asynchronous save operation. The task result contains the number of objects saved. + public virtual async Task SaveChangesAsync() + { + if (_disposed) + throw new ObjectDisposedException("UnitOfWork"); + return await SaveChangesAsync(CancellationToken.None); + } + + /// + /// Saves changes made to one or more repositories. + /// + /// A CancellationToken to observe while waiting for the task to complete. + /// A task that represents the asynchronous save operation. The task result contains the number of objects saved. + public virtual async Task SaveChangesAsync(CancellationToken cancellationToken) + { + if (_disposed) + throw new ObjectDisposedException("UnitOfWork"); + return await Context.SaveChangesAsync(cancellationToken); + } +} + + +public interface IRepositoryFactory +{ + T GetRepository(); +}