Ejemplo n.º 1
0
		public void Throwing_an_exception_from_an_event_handler()
		{
			_workflow = StateMachineWorkflow.New<SubjectWorkflow, Subject>(x =>
				{
					x.AccessCurrentState(y => y.CurrentState);

					x.Initially()
						.When(e => e.Create)
						.Then(i => i.Create)
						.TransitionTo(s => s.Created)
						.InCaseOf()
						.Exception<SubjectException>()
						.Then(i =>
							{
								_instanceHandlerCalled = true;
							})
						.Then(() => _handlerCalled = true)
						.TransitionTo(s => s.Failed);
				});

			_subject = new Subject();

			_instance = _workflow.GetInstance(_subject);

			_instance.RaiseEvent(x => x.Create);
		}
Ejemplo n.º 2
0
        internal DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup, 
            WorkflowInstance host, bool debugStartedAtRoot, bool resetDynamicModule)
        {
            if (resetDynamicModule)
            {
                dynamicModuleManager = null;
            }

            if (dynamicModuleManager == null)
            {
                dynamicModuleManager = new StateManager.DynamicModuleManager(moduleNamePrefix);
            }

            this.stateManager = new StateManager(
                new StateManager.Properties
                    {
                        ModuleNamePrefix = moduleNamePrefix,
                        TypeNamePrefix = typeNamePrefix,
                        AuxiliaryThreadName = auxiliaryThreadName,
                        BreakOnStartup = breakOnStartup
                    },
                    debugStartedAtRoot, dynamicModuleManager);
            
            this.states = new Dictionary<object, State>();
            this.runningThreads = new Dictionary<int, Stack<Activity>>();
            this.instrumentationTracker = new InstrumentationTracker(root);
            this.host = host;
        }
Ejemplo n.º 3
0
 /// <summary>
 /// 创建工作流实例
 /// </summary>
 /// <param name="p"></param>
 /// <returns></returns>
 public static WorkflowInstance CreateInstance(Process p, IWorkflowParser parser)
 {
     var workflow = parser.Parse(GetCacheKey(p.ProcessType)
         , p.ProcessType.Workflow.Serialized
         , p.ProcessType.ActivitySettings);
     var instance = new WorkflowInstance(workflow, p.ID, p.GetInputs());
     //HACK:【重要】强制让Core调度使用同步上下文进行调度而不使用Threaded模式,使得事务与resumption嵌套,便于事务控制和错误处理 20120507
     instance.SynchronizationContext = new WorkflowInstance.DefaultSynchronizationContext();
     //标记为可持久化
     instance.IsPersistable = true;
     //数据字段扩展
     instance.Extensions.Add<DataFieldExtension>(WorkflowBuilder.CreateDataFieldExtension(p));
     //自定义节点扩展
     instance.Extensions.Add<CustomExtension>(new CustomExtension(p.ProcessType.ActivitySettings
         .Where(o => o is CustomSetting)
         .Select(o => o as CustomSetting)
         .ToList()));
     //人工节点扩展
     instance.Extensions.Add<HumanExtension>(new HumanExtension());
     //服务端节点扩展
     instance.Extensions.Add<ServerExtension>(new ServerExtension());
     //并行节点扩展
     instance.Extensions.Add<ParallelExtension>(new ParallelExtension());
     //子流程节点扩展
     instance.Extensions.Add<SubProcessExtension>(new SubProcessExtension());
     return instance;
 }
Ejemplo n.º 4
0
        /// <summary>
        /// 实例化审批页面选择对象
        /// </summary>
        /// <param name="instance"></param>
        public ApproveSelector(WorkflowInstance instance)
            : this()
        {
            var currentActi = instance.GetCurrentActi();
            foreach (var choice in currentActi.Transitions.Keys) {
                var nextActi = currentActi.Transitions[choice];
                if (nextActi == null) {
                    throw new NextActivityNotFoundException(instance.InstanceNo, instance.CurrentActivity, choice);
                }
                var actor = nextActi.Actor;
                this.m_NextChoice.Add(choice);
                this.m_Activities.Add(choice, nextActi.Name);

                IEnumerable<IUser> users = new List<IUser>();
                if (actor != null) {
                    if (choice.Contains("退回")) {
                        actor.RefActivityName = nextActi.Name;
                        users = actor.Resolve(instance);
                    } else {
                        users = actor.Resolve(instance);
                    }
                }

                foreach (var user in users) {
                    var organization = SecurityContext.Provider.GetOrganization(user.DeptId);
                    this[choice].Add(new SelectorUser() {
                        id = user.Id,
                        name = user.Name,
                        deptName = organization.FullName
                    });
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>Creates an workflow instance based on this workflow definition. </summary>
        /// <returns>The <see cref="WorkflowInstance"/>. </returns>
        /// <exception cref="WorkflowException">A workflow validation exception occurred. </exception>
        public WorkflowInstance CreateInstance()
        {
            ValidateRoutes();

            var instance = new WorkflowInstance(this, new List<ActivityData>());
            instance.CurrentActivityIds.Add(StartActivityId);
            return instance;
        }
Ejemplo n.º 6
0
		public void Creating_a_new_workflow()
		{
			_workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x =>
				{
					x.AccessCurrentState(y => y.CurrentState);
				});

			_instance = _workflow.GetInstance(new TestInstance());
		}
Ejemplo n.º 7
0
        public void Human()
        {
            Taobao.Activities.Hosting.WorkflowInstance.IsEnableDebug = true;

            var app = new WorkflowInstance(new HumanWorkflow(), null);
            app.Extensions.Add<HumanExtension>(new HumanExtension());
            app.Extensions.Add<CustomExtension>(new CustomExtension(new List<CustomSetting>() { new ServerSetting(0, "节点1", "", "", null, null, false) }));
            app.Extensions.Add<DataFieldExtension>(new DataFieldExtension("", 0, null));
            app.Run();

            Thread.Sleep(1000);
        }
 public DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup, WorkflowInstance host, bool debugStartedAtRoot)
 {
     StateManager.Properties properties = new StateManager.Properties {
         ModuleNamePrefix = moduleNamePrefix,
         TypeNamePrefix = typeNamePrefix,
         AuxiliaryThreadName = auxiliaryThreadName,
         BreakOnStartup = breakOnStartup
     };
     this.stateManager = new StateManager(properties, debugStartedAtRoot);
     this.states = new Dictionary<object, System.Activities.Debugger.State>();
     this.runningThreads = new Dictionary<int, Stack<Activity>>();
     this.instrumentationTracker = new InstrumentationTracker(root);
     this.host = host;
 }
Ejemplo n.º 9
0
		public void An_event_causing_a_state_transition()
		{
			_workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x =>
				{
					x.AccessCurrentState(y => y.CurrentState);

					x.During(y => y.Initial)
						.When(y => y.Finish)
						.TransitionTo(y => y.Completed);
				});

			_instance = _workflow.GetInstance(new TestInstance());

			_instance.RaiseEvent(x => x.Finish);
		}
Ejemplo n.º 10
0
        public void CtorShouldCreateTracker()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);

                // Act
                var wi = new WorkflowInstance(model);

                // Assert
                Assert.IsNotNull(wi.StateTracker);
            }
        }
Ejemplo n.º 11
0
        public void HostIsNotNull()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);

                // Act
                wi.New();

                // Assert
                Assert.IsNotNull(wi.Host);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// 传阅流程
        /// </summary>
        /// <param name="instance">流程实例.</param>
        /// <param name="toUsers">传阅用户.</param>
        public override bool PassAround(WorkflowInstance instance, IList<IUser> toUsers)
        {
            var tobeReadWorkItems = new List<K2WorkflowItem>();
            var currentWorkItem = instance.CurrentWorkItem;

            #region 添加下一环节待阅流程

            var lastTaskId = this.GetWorkItemLastTaskId(instance.InstanceNo);
            foreach (var user in toUsers) {
                var workItem = WorkflowItemFactory.Create<K2WorkflowItem>();
                lastTaskId += 1;
                workItem.TaskId = lastTaskId;
                workItem.InstanceNo = instance.InstanceNo;
                workItem.PartId = user.Id;
                workItem.PartName = user.Name;
                workItem.PartDeptId = user.DeptId;
                var dept = SecurityContext.Provider.GetOrganization(user.DeptId);
                workItem.PartDeptName = (dept == null ? "" : dept.FullName);
                workItem.ReceTime = DateTime.Now;
                workItem.TaskStatus = TaskStatus.ToRead;
                workItem.CurrentActi = currentWorkItem.CurrentActi;
                // 传阅人
                workItem.Mandatary = CurrentUser.Name;
                workItem.MandataryId = CurrentUser.Id;

                tobeReadWorkItems.Add(workItem);
            }

            #endregion

            using (var transactionScope = new TransactionScope(TransactionScopeOption.Required)) {
                // 新增传阅环节
                foreach (var workitem in tobeReadWorkItems) {
                    _dao.Insert<K2WorkflowItem>(workitem);
                }
                transactionScope.Complete();
            }

            return true;
        }
Ejemplo n.º 13
0
		public void A_message_event_is_raised()
		{
			_workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x =>
			{
				x.AccessCurrentState(y => y.CurrentState);

				x.During(y => y.Initial)
					.When(y => y.Finish)
					.Then(() => _nonInstanceValue = true)
					.Then(instance => instance.MessageValue = "Success")
					.Then((instance, message) => instance.MessageValue = message.Value)
					.TransitionTo(y => y.Completed);
			});

			_testInstance = new TestInstance();

			_instance = _workflow.GetInstance(_testInstance);

			_instance.RaiseEvent(x => x.Finish, new Result
			{
				Value = "Success"
			});
		}
Ejemplo n.º 14
0
 public DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup,
     WorkflowInstance host, bool debugStartedAtRoot) :
     this(root, moduleNamePrefix, typeNamePrefix, auxiliaryThreadName, breakOnStartup, host, debugStartedAtRoot, false)
 {
 }
Ejemplo n.º 15
0
 /// <summary>
 /// 是否可以查看流程
 /// </summary>
 public abstract bool CanViewWorkflow(WorkflowInstance instance);
Ejemplo n.º 16
0
 /// <summary>
 /// 运行流程
 /// </summary>
 /// <param name="instance">流程编号</param>
 /// <param name="result">审批结果</param>
 /// <returns></returns>
 /// <remarks>
 /// 根据用户选择的下一步骤,计算出下一环节的参与者并持久化到数据库
 /// 1、检查流程数据的合法性(及权限)
 /// 2、根据Choice获取下一环节的定义(名称)
 /// 3、结束当前WorkflowItem
 /// 4、添加下一环节处理人的WorkItem(s)数据
 /// =========================================================
 /// 调用K2接口
 /// </remarks>
 public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result);
Ejemplo n.º 17
0
 /// <summary>
 /// 流程传阅
 /// </summary>
 /// <param name="instance">流程实例.</param>
 /// <param name="toUsersId">传阅目标用户.</param>
 public abstract bool PassAround(WorkflowInstance instance, params string[] toUsersId);
Ejemplo n.º 18
0
 /// <summary>
 /// 删除流程
 /// </summary>
 /// <param name="instance"></param>
 /// <returns></returns>
 public abstract bool DeleteWorkflow(WorkflowInstance instance);
Ejemplo n.º 19
0
        public void IdIsHostId()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);

                // Act
                wi.New();
                var hostid = wi.Host.Id;
                var id = wi.Id;

                // Assert
                Assert.AreEqual(hostid, id);
            }
        }
 internal WorkflowInstanceProxy(WorkflowInstance instance)
 {
     this.instance = instance;
 }
Ejemplo n.º 21
0
 /// <summary>
 /// 办理流程
 /// </summary>
 /// <param name="instance">流程实例</param>
 /// <param name="result">处理结果</param>
 /// <param name="listNextUsers">分配办理人员列表</param>
 /// <param name="tobeReadUsers">待阅人员</param>
 /// <remarks></remarks>
 /// <returns></returns>
 public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result, IList<IUser> listNextUsers, IList<IUser> tobeReadUsers);
Ejemplo n.º 22
0
        public void IdIsNotEmptyGuid()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);

                // Act
                var id = wi.Id;

                // Assert
                Assert.AreEqual(Guid.Empty, id);
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// 计算环节参与人
        /// </summary>
        public override IEnumerable<IUser> Resolve(WorkflowInstance instance)
        {
            // 已当前环节的原处理人为计算基准
            var currentUser = SecurityContext.Provider.Get(instance.CurrentWorkItem.PartId);

            var actorUsers = new List<IUser>();

            // 优先级顺序
            // 1、指定环节处理人
            // 2、固定角色处理人(建单用户、系统)
            // 3、流程角色处理人(根据角色名称查询)
            // 4、基于场景(RoleBase:当前用户、建单用户)的角色处理人
            // 5、基于场景的指定部门的角色处理人

            // 指定环节处理人(获取该环节最后一次非AutoFinished的处理人)
            if (!string.IsNullOrEmpty(this.RefActivityName)) {
                var lastUser = GetLastActivityApprover(instance.InstanceNo, this.RefActivityName);
                if (lastUser != null) {
                    actorUsers.Add(lastUser);
                }
                return actorUsers;
            }

            // 固定角色
            if (string.IsNullOrEmpty(this.RoleName)) {
                throw new NullReferenceException("当前环节未配置有效的参与者计算规则");
            }

            if (this.RoleName == "建单用户") {
                actorUsers.Add(SecurityContext.Provider.Get(instance.CreatorId));
                return actorUsers;
            } else if (this.RoleName == "系统") {
                actorUsers.Add(SecurityContext.Provider.GetUser("system"));
                return actorUsers;
            } else {
                // 配置角色
                // 全局角色
                if (string.IsNullOrEmpty(this.RoleBase)) {
                    var roleUsers = _dao.QueryEntities<User>("k2client.actor.getroleusers", new { RoleName = this.RoleName });
                    actorUsers.AddRange(roleUsers.Select(roleUser => SecurityContext.Provider.Get(roleUser.Id)));
                    return actorUsers;
                } else if (this.RoleBase == "当前用户" || this.RoleBase == "建单用户") {
                    IList<User> listUser;

                    #region 逐层遍历
                    var tempOrgId = "";
                    switch (this.RoleBase) {
                        case "当前用户":
                            tempOrgId = currentUser.DeptId;
                            break;
                        case "建单用户":
                            tempOrgId = instance.CreatorDeptId;
                            break;
                    }

                    do {
                        listUser = _dao.QueryEntities<User>("K2Client.User.GetListByRoleOrg", new { OrgId = tempOrgId, RoleName = this.RoleName });
                        if (listUser == null || listUser.Count == 0) {
                            tempOrgId = _dao.QueryScalar<string>("K2Client.Organization.GetParentId", new { OrgId = tempOrgId });
                        }
                    } while ((listUser == null || listUser.Count == 0) && !string.IsNullOrEmpty(tempOrgId)); //这个遍历是逐部门往上的

                    #endregion

                    return listUser;
                } else if(this.RoleBase == "指定部门" && !string.IsNullOrEmpty(this.DeptId)) {
                    var listUser = _dao.QueryEntities<User>("K2Client.User.GetListByRoleOrg"
                        , new { OrgId = this.DeptId, RoleName = this.RoleName });

                    return listUser;
                }
            }

            return actorUsers;
        }
Ejemplo n.º 24
0
        /// <summary>
        /// 初始化流程表单对象
        /// </summary>
        /// <param name="instance">流程实例</param>
        /// <returns></returns>
        public static WorkflowForm Init(WorkflowInstance instance)
        {
            var currentUser = SecurityContext.User;

            var form = new WorkflowForm();
            form.Instance = instance;
            form.AppCode = instance.AppCode;
            form.AppName = instance.AppName;
            form.Description = instance.Description;
            form.VersionStr = instance.Version.ToString(CultureInfo.InvariantCulture);
            form.InstanceNo = instance.InstanceNo;
            #region FormStatus
            switch (instance.Status) {
                case InstanceStatus.Draft:
                    {
                        form.Status = FormStatus.Draft;
                        break;
                    }
                case InstanceStatus.Running:
                    {
                        var currentWorkItem = instance.CurrentWorkItem;
                        // 待办条件:当前环节的审批人为当前登录用户 && 当前环节未结束
                        if ((currentWorkItem.PartId.Equals(currentUser.Id, StringComparison.OrdinalIgnoreCase)
                            || (!string.IsNullOrEmpty(currentWorkItem.MandataryId) && currentWorkItem.MandataryId.Equals(currentUser.Id, StringComparison.OrdinalIgnoreCase))
                            || DelegateWork.IsDelegate(instance.AppCode, currentWorkItem.PartId, currentUser.Id))
                            && currentWorkItem.TaskStatus == TaskStatus.Waiting) {
                            form.Status = FormStatus.Todo;
                        } else {
                            form.Status = FormStatus.Done;
                        }
                        break;
                    }
                case InstanceStatus.Cancel:
                case InstanceStatus.Deleted:
                case InstanceStatus.Finished:
                    {
                        form.Status = FormStatus.Done;
                        break;
                    }
            }
            #endregion
            form.Creator = SecurityContext.Provider.Get(instance.CreatorId);
            form.CreatorDept = SecurityContext.Provider.GetOrganization(form.Creator.DeptId);
            form.CurrentUser = SecurityContext.User;
            form.TaskId = instance.CurrentWorkItem == null ? 1 : instance.CurrentWorkItem.TaskId;
            form.CurrentActi = instance.CurrentWorkItem == null ? instance.CurrentActivity : instance.CurrentWorkItem.CurrentActi;
            form.Controller = FlowFactory.GetWorklfowControllerName(form.AppCode);
            form.Instance = instance;

            // 根据WorkItem中的环节信息计算出历史环节(Distinct)
            // 获取并添加到List中,用于渲染
            var workItems = instance.GetWorkItems();
            if (workItems != null && workItems.Any()) {
                var lastTaskId = workItems.First(p => p.CurrentActi.Equals(form.CurrentActi, StringComparison.OrdinalIgnoreCase)).TaskId;
                var activities = workItems.Where(p => p.TaskId <= lastTaskId).OrderBy(p => p.TaskId);
                foreach (var activity in activities) {
                    if (form.HistoryActivities.Contains(activity.CurrentActi)) {
                        continue;
                    }
                    form.HistoryActivities.Add(activity.CurrentActi);
                }
            }
            if (form.HistoryActivities.Count == 0) {
                form.HistoryActivities.Add(form.CurrentActi);
            }

            return form;
        }
Ejemplo n.º 25
0
        public void IsLoadedFiresPropertyChanged()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);
                var propChanged = false;

                wi.PropertyChanged += (sender, args) =>
                    {
                        if (!propChanged)
                        {
                            propChanged = args.PropertyName == "IsLoaded";
                        }
                    };

                // Act
                wi.New();

                // Assert
                Assert.IsTrue(propChanged);
            }
        }
 public WorkflowInstancePipeBind(WorkflowInstance instance)
 {
     _instance = instance;
 }
Ejemplo n.º 27
0
 /// <summary>
 /// 传阅流程
 /// </summary>
 /// <returns><c>true</c>, if around was passed, <c>false</c> otherwise.</returns>
 /// <param name="instance">流程实例.</param>
 /// <param name="toUsers">传阅用户.</param>
 public abstract bool PassAround(WorkflowInstance instance, IList<IUser> toUsers);
Ejemplo n.º 28
0
        public void IsLoadedReturnsTrueOnNew()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);
                wi.New();

                // Act
                var actual = wi.IsLoaded;

                // Assert
                Assert.IsTrue(actual);
            }
        }
Ejemplo n.º 29
0
 /// <summary>
 /// 启动流程实例
 /// </summary>
 /// <param name="instance">流程实例对象</param>
 /// <remarks>同时新增流程办理历史</remarks>
 /// <returns></returns>
 public abstract bool SaveWorkflow(WorkflowInstance instance);
Ejemplo n.º 30
0
        public void ResumeShouldResume()
        {
            // Arrange
            using (var testdb = new SqlWorkflowInstanceStoreTest())
            {
                var view = new TestWorkflowView(testdb.CreateInstanceStore());
                var model = new WorkflowModel(view);
                var wi = new WorkflowInstance(model);
                wi.New();

                // Act
                wi.Resume(StateTrigger.T1);

                // Assert
                Assert.AreEqual(StateMachineExample.State2, wi.StateTracker.CurrentState);
            }
        }