我正在尝试使用C#而不是设计器和XAML编写一些活动。 VS2010已经出错并且非常慢,并且它的编译支持也很差(对于变量名称,属性等)。
所以我试图通过直接继承Activity类来创建活动,但我遇到了障碍。
这是我的代码:
public class TestActivity : Activity
{
public InArgument<string> Username { get; set; }
public InArgument<string> Password { get; set; }
public OutArgument<bool> ValidCredential { get; set; }
public OutArgument<ProvisioningRole> Role { get; set; }
public OutArgument<Guid> Guid { get; set; }
protected override Func<Activity> Implementation
{
get
{
return () =>
{
return new Sequence()
{
Activities =
{
new AuthenticateUserActivity()
{
Username = this.Username,
Password = this.Password,
Guid = this.Guid,
Result = this.ValidCredential
},
new If()
{
Condition = this.ValidCredential,
Then = new GetUserRoleActivity()
{
Username = this.Username,
Password = this.Password,
Result = this.Role
}
},
}
};
};
}
set { base.Implementation = value; }
}
}
问题在于If(),条件。它应该是一个InArgument,但是.ValidCredential是一个OutArgument。我已经尝试创建一个Variable,为它分配ValidCredential的值。我还尝试将AuthenticateUserActivity的结果放在变量中,然后将其分配给ValidCredential,但是我得到一个错误,指出需要指定Assign的To属性。
我已经四处查找了正确的教程,但我发现的只是一篇MSDN文章,它有一个快速而脏的代码实现,它使用了文字而不是传递的参数,所以没有帮助。
答案 0 :(得分:5)
我发现了怎么做。您只需要从原始的InArgument创建新的InArgument。有一个构造函数为它接受表达式。
Username = new InArgument<bool>((ActivityContext c) => this.ValidCredential.Get(c))
所以我将整个活动改为
return new CompensableActivity()
{
Body = new Sequence()
{
Activities =
{
new AuthenticateUserActivity()
{
Username = this.Username.In(),
Password = this.Password.In(),
Guid = this.Guid.Out(),
Result = this.ValidCredential.Out()
},
new If(this.ValidCredential.In())
{
Then = new GetUserRoleActivity()
{
Username = this.Username.In(),
Password = this.Password.In(),
Result = this.Role.Out()
},
Else = new Assign<ProvisioningRole>()
{
To = this.Role.Out(),
Value = ProvisioningRole.User
}
}
}
},
};
In and Out是我写的扩展方法:
public static class WorkflowExtensions
{
#region In
public static InArgument<T> In<T>(this InArgument<T> self)
{
return new InArgument<T>(context => self.Get(context));
}
public static InArgument<T> In<T>(this OutArgument<T> self)
{
return new InArgument<T>(context => self.Get(context));
}
#endregion
#region Out
public static OutArgument<T> Out<T>(this InArgument<T> self)
{
return new OutArgument<T>(context => self.Get(context));
}
public static OutArgument<T> Out<T>(this OutArgument<T> self)
{
return new OutArgument<T>(context => self.Get(context));
}
#endregion
}
现在一切都很好!
答案 1 :(得分:1)
你应该能够让它发挥作用。基本方法应该是使用变量来存储数据,使用OutArgument将活动中的数据导入Variable和InArguments,以便将变量中的数据转换为活动。
另请注意,将InArguments绑定到变量的表达式是VisualBasicValue表达式。如下所示:
Condition = new VisualBasicValue(“System.DateTime.Now.Hour&lt; 12”)
This博客文章不是关于使用参数和变量,而是展示了几个例子。
答案 2 :(得分:0)
去无耻地插入我自己的库,我最终为此做了: http://code.google.com/p/system-transactions/
允许基本的代码补偿,而不会出现WF的巨大麻烦。此外,编译正确,易于调试。