Unit Of Work Pattern(ORM Transaction Controller) Implementation Sample

3420 ワード

1. Transaction Unit Entity
 public class TransactionUnitBase
    {
        public ActionType ThisActionType { get; set; }
    }

    public class TransactionUnit<TIn,TOut> : TransactionUnitBase
    {
        public Func<TIn,TOut> UnitAction { get; set; }
        public TIn ActionParam { get; set; }
    }

    public class TransactionUnit<TIn> : TransactionUnitBase
    {
        public Action<TIn> UnitAction { get; set; }
        public TIn ActionParam { get; set; }
    }

    public class TransactionUnitNoParam<TOut> : TransactionUnitBase
    {
        public Func<TOut> UnitAction { get; set; }
    }

2.ActionType
 public enum ActionType
    {
        BothParamAndReturn,
        ParamOnly,
        ReturnOnly
    }

3.TransactionUnit Manager
 public class TransactionUnitManager : ITransactionUnit
    {
        private readonly List<dynamic> _currentWorks;

        public TransactionUnitManager()
        {
            _currentWorks = new List<dynamic>();
        }
        public ITransactionUnit AddWorkUnit<TParam, TReturn>(Func<TParam, TReturn> work,TParam pamameter)
        {
            var unitOfWork = new TransactionUnit<TParam,TReturn>
                {
                    ThisActionType = ActionType.BothParamAndReturn,
                    ActionParam = pamameter,
                    UnitAction = work
                };

            _currentWorks.Add(unitOfWork);
            return this;
        }

        public ITransactionUnit AddWorkUnit<TParam>(Action<TParam> work,TParam parameter)
        {

            var unitOfWork = new TransactionUnit<TParam>
            {
                ThisActionType = ActionType.ParamOnly,
                ActionParam = parameter,
                UnitAction = work
            };
            _currentWorks.Add(unitOfWork);
            return this;
        }

        public ITransactionUnit AddWorkUnit<TReturn>(Func<TReturn> work)
        {
            var unitOfWork = new TransactionUnitNoParam<TReturn>
            {
                ThisActionType = ActionType.ReturnOnly,
                UnitAction = work
            };
            _currentWorks.Add(unitOfWork);
            return this;
        }

        public void CommitTransaction()
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromMinutes(10)))
                {
                    foreach (var t in _currentWorks)
                    {
                        if (t.ThisActionType == ActionType.BothParamAndReturn)
                        {
                            t.UnitAction(t.ActionParam);
                        }
                        else if (t.ThisActionType == ActionType.ParamOnly)
                        {
                            t.UnitAction(t.ActionParam);
                        }
                        else if (t.ThisActionType == ActionType.ReturnOnly)
                        {
                            t.UnitAction();
                        }
                    }

                    scope.Complete();
                }
            }
            finally
            {
                _currentWorks.Clear();
            }

        }
    }