Commit 8455bd0b authored by 阿星Plus's avatar 阿星Plus

工作单元

parent e5648bfb
using System.Collections.Generic;
namespace Plus.Domain.Uow
{
public class DataFilterConfiguration
{
public string FilterName { get; }
public bool IsEnabled { get; }
public IDictionary<string, object> FilterParameters { get; }
public DataFilterConfiguration(string filterName, bool isEnabled)
{
FilterName = filterName;
IsEnabled = isEnabled;
FilterParameters = new Dictionary<string, object>();
}
internal DataFilterConfiguration(DataFilterConfiguration filterToClone, bool? isEnabled = null)
: this(filterToClone.FilterName, isEnabled ?? filterToClone.IsEnabled)
{
foreach (var filterParameter in filterToClone.FilterParameters)
{
FilterParameters[filterParameter.Key] = filterParameter.Value;
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Plus.Domain.Uow
{
/// <summary>
/// This interface is used to work with active unit of work.
/// This interface can not be injected.
/// Use <see cref="IUnitOfWorkManager"/> instead.
/// </summary>
public interface IActiveUnitOfWork
{
/// <summary>
/// This event is raised when this UOW is successfully completed.
/// </summary>
event EventHandler Completed;
/// <summary>
/// This event is raised when this UOW is failed.
/// </summary>
event EventHandler<UnitOfWorkFailedEventArgs> Failed;
/// <summary>
/// This event is raised when this UOW is disposed.
/// </summary>
event EventHandler Disposed;
/// <summary>
/// Gets if this unit of work is transactional.
/// </summary>
UnitOfWorkOptions Options { get; }
/// <summary>
/// Gets data filter configurations for this unit of work.
/// </summary>
IReadOnlyList<DataFilterConfiguration> Filters { get; }
/// <summary>
/// A dictionary to use for custom operations on unitOfWork
/// </summary>
Dictionary<string, object> Items { get; set; }
/// <summary>
/// Is this UOW disposed?
/// </summary>
bool IsDisposed { get; }
/// <summary>
/// Saves all changes until now in this unit of work.
/// This method may be called to apply changes whenever needed.
/// Note that if this unit of work is transactional, saved changes are also rolled back if transaction is rolled back.
/// No explicit call is needed to SaveChanges generally,
/// since all changes saved at end of a unit of work automatically.
/// </summary>
void SaveChanges();
/// <summary>
/// Saves all changes until now in this unit of work.
/// This method may be called to apply changes whenever needed.
/// Note that if this unit of work is transactional, saved changes are also rolled back if transaction is rolled back.
/// No explicit call is needed to SaveChanges generally,
/// since all changes saved at end of a unit of work automatically.
/// </summary>
Task SaveChangesAsync();
/// <summary>
/// Disables one or more data filters.
/// Does nothing for a filter if it's already disabled.
/// Use this method in a using statement to re-enable filters if needed.
/// </summary>
/// <param name="filterNames">One or more filter names. <see cref="AbpDataFilters"/> for standard filters.</param>
/// <returns>A <see cref="IDisposable"/> handle to take back the disable effect.</returns>
IDisposable DisableFilter(params string[] filterNames);
/// <summary>
/// Enables one or more data filters.
/// Does nothing for a filter if it's already enabled.
/// Use this method in a using statement to re-disable filters if needed.
/// </summary>
/// <param name="filterNames">One or more filter names. <see cref="AbpDataFilters"/> for standard filters.</param>
/// <returns>A <see cref="IDisposable"/> handle to take back the enable effect.</returns>
IDisposable EnableFilter(params string[] filterNames);
/// <summary>
/// Checks if a filter is enabled or not.
/// </summary>
/// <param name="filterName">Name of the filter. <see cref="AbpDataFilters"/> for standard filters.</param>
bool IsFilterEnabled(string filterName);
/// <summary>
/// Sets (overrides) value of a filter parameter.
/// </summary>
/// <param name="filterName">Name of the filter</param>
/// <param name="parameterName">Parameter's name</param>
/// <param name="value">Value of the parameter to be set</param>
IDisposable SetFilterParameter(string filterName, string parameterName, object value);
/// <summary>
/// Sets/Changes Tenant's Id for this UOW.
/// </summary>
/// <param name="tenantId">The tenant id.</param>
/// <returns>A disposable object to restore old TenantId value when you dispose it</returns>
IDisposable SetTenantId(int? tenantId);
/// <summary>
/// Sets/Changes Tenant's Id for this UOW.
/// </summary>
/// <param name="tenantId">The tenant id</param>
/// <param name="switchMustHaveTenantEnableDisable">
/// True to enable/disable <see cref="IMustHaveTenant"/> based on given tenantId.
/// Enables <see cref="IMustHaveTenant"/> filter if tenantId is not null.
/// Disables <see cref="IMustHaveTenant"/> filter if tenantId is null.
/// This value is true for <see cref="SetTenantId(int?)"/> method.
/// </param>
/// <returns>A disposable object to restore old TenantId value when you dispose it</returns>
IDisposable SetTenantId(int? tenantId, bool switchMustHaveTenantEnableDisable);
/// <summary>
/// Gets Tenant Id for this UOW.
/// </summary>
/// <returns></returns>
int? GetTenantId();
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
namespace Plus.Domain.Uow
namespace Plus.Domain.Uow
{
/// <summary>
/// Defines a unit of work.
/// This interface is internally used by ABP.
/// Use <see cref="IUnitOfWorkManager.Begin()"/> to start a new unit of work.
/// </summary>
public interface IUnitOfWork : IActiveUnitOfWork, IUnitOfWorkCompleteHandle
{
/// <summary>
/// Unique id of this UOW.
/// </summary>
string Id { get; }
/// <summary>
/// Reference to the outer UOW if exists.
/// </summary>
IUnitOfWork Outer { get; set; }
/// <summary>
/// Begins the unit of work with given options.
/// </summary>
/// <param name="options">Unit of work options</param>
void Begin(UnitOfWorkOptions options);
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Plus.Domain.Uow
{
public interface IUnitOfWorkCompleteHandle
/// <summary>
/// Used to complete a unit of work.
/// This interface can not be injected or directly used.
/// Use <see cref="IUnitOfWorkManager"/> instead.
/// </summary>
public interface IUnitOfWorkCompleteHandle : IDisposable
{
/// <summary>
/// Completes this unit of work.
/// It saves all changes and commit transaction if exists.
/// </summary>
void Complete();
/// <summary>
/// Completes this unit of work.
/// It saves all changes and commit transaction if exists.
/// </summary>
Task CompleteAsync();
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Transactions;
namespace Plus.Domain.Uow
{
/// <summary>
/// Used to get/set default options for a unit of work.
/// </summary>
public interface IUnitOfWorkDefaultOptions
{
/// <summary>
/// Scope option.
/// </summary>
TransactionScopeOption Scope { get; set; }
/// <summary>
/// Should unit of works be transactional.
/// Default: true.
/// </summary>
bool IsTransactional { get; set; }
/// <summary>
/// A boolean value indicates that System.Transactions.TransactionScope is available for current application.
/// Default: true.
/// </summary>
bool IsTransactionScopeAvailable { get; set; }
/// <summary>
/// Gets/sets a timeout value for unit of works.
/// </summary>
TimeSpan? Timeout { get; set; }
/// <summary>
/// Gets/sets isolation level of transaction.
/// This is used if <see cref="IsTransactional"/> is true.
/// </summary>
IsolationLevel? IsolationLevel { get; set; }
/// <summary>
/// Gets list of all data filter configurations.
/// </summary>
IReadOnlyList<DataFilterConfiguration> Filters { get; }
/// <summary>
/// A list of selectors to determine conventional Unit Of Work classes.
/// </summary>
List<Func<Type, bool>> ConventionalUowSelectors { get; }
/// <summary>
/// Registers a data filter to unit of work system.
/// </summary>
/// <param name="filterName">Name of the filter.</param>
/// <param name="isEnabledByDefault">Is filter enabled by default.</param>
void RegisterFilter(string filterName, bool isEnabledByDefault);
/// <summary>
/// Overrides a data filter definition.
/// </summary>
/// <param name="filterName">Name of the filter.</param>
/// <param name="isEnabledByDefault">Is filter enabled by default.</param>
void OverrideFilter(string filterName, bool isEnabledByDefault);
}
}
\ No newline at end of file
using System.Transactions;
namespace Plus.Domain.Uow
{
/// <summary>
/// Unit of work manager.
/// Used to begin and control a unit of work.
/// </summary>
public interface IUnitOfWorkManager
{
/// <summary>
/// Gets currently active unit of work (or null if not exists).
/// </summary>
IActiveUnitOfWork Current { get; }
/// <summary>
/// Begins a new unit of work.
/// </summary>
/// <returns>A handle to be able to complete the unit of work</returns>
IUnitOfWorkCompleteHandle Begin();
/// <summary>
/// Begins a new unit of work.
/// </summary>
/// <returns>A handle to be able to complete the unit of work</returns>
IUnitOfWorkCompleteHandle Begin(TransactionScopeOption scope);
/// <summary>
/// Begins a new unit of work.
/// </summary>
/// <returns>A handle to be able to complete the unit of work</returns>
IUnitOfWorkCompleteHandle Begin(UnitOfWorkOptions options);
}
}
\ No newline at end of file
using System;
namespace Plus.Domain.Uow
{
/// <summary>
/// Used as event arguments on <see cref="IActiveUnitOfWork.Failed"/> event.
/// </summary>
public class UnitOfWorkFailedEventArgs : EventArgs
{
/// <summary>
/// Exception that caused failure.
/// </summary>
public Exception Exception { get; private set; }
/// <summary>
/// Creates a new <see cref="UnitOfWorkFailedEventArgs"/> object.
/// </summary>
/// <param name="exception">Exception that caused failure</param>
public UnitOfWorkFailedEventArgs(Exception exception)
{
Exception = exception;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
namespace Plus.Domain.Uow
{
/// <summary>
/// Unit of work options.
/// </summary>
public class UnitOfWorkOptions
{
/// <summary>
/// Scope option.
/// </summary>
public TransactionScopeOption? Scope { get; set; }
/// <summary>
/// Is this UOW transactional?
/// Uses default value if not supplied.
/// </summary>
public bool? IsTransactional { get; set; }
/// <summary>
/// Timeout of UOW As milliseconds.
/// Uses default value if not supplied.
/// </summary>
public TimeSpan? Timeout { get; set; }
/// <summary>
/// If this UOW is transactional, this option indicated the isolation level of the transaction.
/// Uses default value if not supplied.
/// </summary>
public IsolationLevel? IsolationLevel { get; set; }
/// <summary>
/// This option should be set to <see cref="TransactionScopeAsyncFlowOption.Enabled"/>
/// if unit of work is used in an async scope.
/// </summary>
public TransactionScopeAsyncFlowOption? AsyncFlowOption { get; set; }
/// <summary>
/// Can be used to enable/disable some filters.
/// </summary>
public List<DataFilterConfiguration> FilterOverrides { get; }
/// <summary>
/// Creates a new <see cref="UnitOfWorkOptions"/> object.
/// </summary>
public UnitOfWorkOptions()
{
FilterOverrides = new List<DataFilterConfiguration>();
}
internal void FillDefaultsForNonProvidedOptions(IUnitOfWorkDefaultOptions defaultOptions)
{
//TODO: Do not change options object..?
if (!IsTransactional.HasValue)
{
IsTransactional = defaultOptions.IsTransactional;
}
if (!Scope.HasValue)
{
Scope = defaultOptions.Scope;
}
if (!Timeout.HasValue && defaultOptions.Timeout.HasValue)
{
Timeout = defaultOptions.Timeout.Value;
}
if (!IsolationLevel.HasValue && defaultOptions.IsolationLevel.HasValue)
{
IsolationLevel = defaultOptions.IsolationLevel.Value;
}
}
internal void FillOuterUowFiltersForNonProvidedOptions(List<DataFilterConfiguration> filterOverrides)
{
foreach (var filterOverride in filterOverrides)
{
if (FilterOverrides.Any(fo => fo.FilterName == filterOverride.FilterName))
{
continue;
}
FilterOverrides.Add(filterOverride);
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment