public void Push(CommandComposite composite) { bool isOuterCycle = false; if (unitOfWorkCollection == null) { isOuterCycle = true; unitOfWorkCollection = new Dictionary <int, UnitOfWorkItem>(); } //var delays = new List<IMessage<object>>(); var eventBroker = IoCFactory.Instance.TryResolve <IEventBroker>(); //var units = new Dictionary<int, Tuple<IUnitOfWork, bool>>(); foreach (IGrouping <MessageExecuteSetting, IMessage <object> > groupMessage in composite.Parts.GroupBy(part => part.Setting, r => r)) { var groupMessageKey = groupMessage.Key; List <IMessage <object> > messages = groupMessage.ToList(); bool isFlush = messages.Any(r => r is CommandBase); IUnitOfWork unitOfWork; var unitOfWorkKey = groupMessageKey.GetHashCode(); if (unitOfWorkCollection.ContainsKey(unitOfWorkKey)) { unitOfWork = unitOfWorkCollection[unitOfWorkKey].UnitOfWork; } else { var unitOfWorkFactory = string.IsNullOrWhiteSpace(groupMessageKey.DataBaseInstance) ? IoCFactory.Instance.TryResolve <IUnitOfWorkFactory>() : IoCFactory.Instance.TryResolveByNamed <IUnitOfWorkFactory>(groupMessageKey.DataBaseInstance); unitOfWork = unitOfWorkFactory.Create(isFlush ? IsolationLevel.ReadCommitted : IsolationLevel.ReadUncommitted, groupMessageKey.Connection); unitOfWorkCollection.Add(groupMessageKey.GetHashCode(), new UnitOfWorkItem { UnitOfWork = unitOfWork, IsFlush = isFlush }); } foreach (IMessage <object> part in messages) { bool isThrow = false; try { part.Setting.outerDispatcher = this; part.Setting.unitOfWork = unitOfWork; part.Setting.OnBefore.Do(action => action(part)); if (!part.Setting.Mute.HasFlag(MuteEvent.OnBefore)) { eventBroker.Publish(new OnBeforeExecuteEvent(part)); } part.Execute(); part.Setting.OnAfter.Do(action => action(part)); if (!part.Setting.Mute.HasFlag(MuteEvent.OnAfter)) { eventBroker.Publish(new OnAfterExecuteEvent(part)); } if (isFlush) { unitOfWork.Flush(); } } catch (Exception exception) { isThrow = true; part.Setting.OnError.Do(action => action(part, exception)); var onAfterErrorExecuteEvent = new OnAfterErrorExecuteEvent(part, exception); if (!part.Setting.Mute.HasFlag(MuteEvent.OnError) && eventBroker.HasSubscriber(onAfterErrorExecuteEvent)) { eventBroker.Publish(onAfterErrorExecuteEvent); } throw; } finally { part.Setting.OnComplete.Do(action => action(part)); if (!part.Setting.Mute.HasFlag(MuteEvent.OnComplete)) { eventBroker.Publish(new OnCompleteExecuteEvent(part)); } if (isThrow) { if (isOuterCycle) { unitOfWorkCollection.Select(r => r.Value) .DoEach(r => r.UnitOfWork.Dispose()); unitOfWorkCollection = null; } } } } } if (isOuterCycle) { unitOfWorkCollection.Select(r => r.Value) .DoEach(r => { if (r.IsFlush) { r.UnitOfWork.Commit(); } r.UnitOfWork.Dispose(); }); unitOfWorkCollection = null; } //foreach (var messages in delays.GroupBy(r => r.Setting.Delay, r => r)) //{ // IoCFactory.Instance.TryResolve<IDispatcher>() // .Push(new AddDelayToSchedulerCommand // { // Commands = messages // .ToList() // }, new MessageExecuteSetting // { // Connection = messages.Key.Connection, // DataBaseInstance = messages.Key.DataBaseInstance // }); //} }
public void Push(CommandComposite composite) { bool hasAtLeastCommand = composite.Parts.Any(r => r.Message is CommandBase); var isolationLevel = hasAtLeastCommand ? IsolationLevel.ReadCommitted : IsolationLevel.ReadUncommitted; composite.Parts.Last().Setting.Commit = hasAtLeastCommand; var eventBroker = IoCFactory.Instance.TryResolve <IEventBroker>(); string named = composite.Parts.Last().Setting.DataBaseInstance; var connectionString = composite.Parts.Last().Setting.Connection; var unitOfWorkFactory = string.IsNullOrWhiteSpace(named) ? IoCFactory.Instance.TryResolve <IUnitOfWorkFactory>() : IoCFactory.Instance.TryResolveByNamed <IUnitOfWorkFactory>(named); using (var unitOfWork = unitOfWorkFactory.Create(isolationLevel, connectionString)) { foreach (var part in composite.Parts) { try { if (!string.IsNullOrWhiteSpace(part.Setting.DataBaseInstance)) { part.Message.SetValue("dataBaseInstance", part.Setting.DataBaseInstance); } part.Setting.OnBefore(); if (part.Setting.PublishEventOnBefore) { eventBroker.Publish(new OnBeforeExecuteEvent(part.Message)); } part.Message.Execute(); part.Setting.OnAfter(); if (part.Setting.PublishEventOnAfter) { eventBroker.Publish(new OnAfterExecuteEvent(part.Message)); } if (part.Setting.Commit) { unitOfWork.Commit(); } } catch (Exception exception) { part.Setting.OnError(exception); var onAfterErrorExecuteEvent = new OnAfterErrorExecuteEvent(part.Message, exception); if (part.Setting.PublishEventOnError && eventBroker.HasSubscriber(onAfterErrorExecuteEvent)) { eventBroker.Publish(onAfterErrorExecuteEvent); } else { throw; } } finally { part.Setting.OnComplete(); if (part.Setting.PublishEventOnComplete) { eventBroker.Publish(new OnCompleteExecuteEvent(part.Message)); } } } } }