为工作流服务提供工作流扩展 - WF 4.0

发布于 2024-10-16 13:55:40 字数 1554 浏览 2 评论 0原文

问候大家!

我对 WF 4.0 和 WWF 总体来说是个新手,所以请原谅我,如果这看起来像一个新手类型的问题,但相信我,我已经在互联网深处搜索了这个问题的解决方案,但没有结果。

我创建了一个示例 WF 应用程序,其中包含需要提供扩展的自定义 CodeActivity,如下所示:

public sealed class PreparePizza : CodeActivity
{
    public InArgument<Order> Order { get; set; }

    protected override void CacheMetadata(CodeActivityMetadata metadata)
    {
        base.CacheMetadata(metadata);

        if (this.Order == null)
            metadata.AddValidationError("You must supply an Order.");

        metadata.RequireExtension<IPreparePizzaExtension>();
    }
    // If your activity returns a value, derive from CodeActivity<TResult>
    // and return the value from the Execute method.
    protected override void Execute(CodeActivityContext context)
    {
        // Obtain the runtime value of the Text input argument
        Order order = context.GetValue(this.Order);
        var extension = context.GetExtension<IPreparePizzaExtension>();
        extension.Prepare(order);
    }
}

public interface IPreparePizzaExtension
{
    void Prepare(Order order);
}

然后,我将此活动放入工作流服务中,并尝试通过添加服务引用来通过我的 Web 应用程序进行使用。但是,当我添加参考时,我得到:

System.Activities.ValidationException:必须配置“PizzaMan.ActivityLibrary.IPreparePizzaExtension”类型的扩展才能运行此工作流程。

很公平 - 当然,我的活动要求我向它传递 IPreparePizzaExtension 的实现 - 毕竟,我已经告诉它了!

所以我的问题是,我到底如何将其传递给服务?我可以使用 WorkflowInvoker 在控制台应用程序场景中轻松管理此操作,但我看不到任何明显的方法可以通过服务方法来执行此操作。我认为显然需要一种添加引用的编程方法,但我再次不知道如何进行此操作。

任何帮助将不胜感激。

此致 伊恩

Greetings one and all!

I'm new to WF 4.0 and WWF in general so forgive me if this seems like a newbie type of question, but believe me I've scoured the depths of the Internet for a solution to this problem, but to no avail.

I have created a sample WF application with a custom CodeActivity that requires an extension be provided, as per below:

public sealed class PreparePizza : CodeActivity
{
    public InArgument<Order> Order { get; set; }

    protected override void CacheMetadata(CodeActivityMetadata metadata)
    {
        base.CacheMetadata(metadata);

        if (this.Order == null)
            metadata.AddValidationError("You must supply an Order.");

        metadata.RequireExtension<IPreparePizzaExtension>();
    }
    // If your activity returns a value, derive from CodeActivity<TResult>
    // and return the value from the Execute method.
    protected override void Execute(CodeActivityContext context)
    {
        // Obtain the runtime value of the Text input argument
        Order order = context.GetValue(this.Order);
        var extension = context.GetExtension<IPreparePizzaExtension>();
        extension.Prepare(order);
    }
}

public interface IPreparePizzaExtension
{
    void Prepare(Order order);
}

I then slot this activity into a workflow service and attempt to consume via my web app by adding a service reference. However, when I add the reference I get:

System.Activities.ValidationException: An extension of type 'PizzaMan.ActivityLibrary.IPreparePizzaExtension' must be configured in order to run this workflow.

Fair enough - of course my activity requires that I pass it an implementation of IPreparePizzaExtension - after all, I've told it to!

So my question is, how on earth do I pass this to the service? I can manage this easily enough in a console app scenario, using the WorkflowInvoker, but I cannot see any obvious way to do this via the service approach. I would assume that obviously a programmatic approach to adding the reference is what's needed, but again I'm at a loss as to precisely how to go about this.

Any help would be greatly appreciated.

Best regards
Ian

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我早已燃尽 2024-10-23 13:55:40

WorkflowServiceHost 具有 WorkflowExtensions 属性,您可以在其中添加工作流扩展。有几种方法可以做到这一点。如果您是自托管,这很容易,因为您创建 WorkflowServiceHost。如果您使用 IIS,则需要创建一个 ServiceHostFactory 来配置您的 WorkflowServiceHost。最后,可以选择使用metadata.AddDefaultExtensionProvider() 函数在活动的CacheMetadata 中添加工作流扩展。

The WorkflowServiceHost has a WorkflowExtensions property where you can add the workflow extenstion. There are several ways you can do that. If you are self hosting this is easy as you create the WorkflowServiceHost. If you are usign IIS you need to create a ServiceHostFactory to configure you WorkflowServiceHost. Finally there is an option to add the workflow extension in the CacheMetadata of your activity using the metadata.AddDefaultExtensionProvider() function.

尐籹人 2024-10-23 13:55:40

解决如下,自托管风格:

    static void Main(string[] args)
    {
        Workflow1 workflow = new Workflow1();
        // Provide some default values; note: these will be overriden once method on the service is called.
        workflow.productID = -1;

        Uri address = new Uri("http://localhost:1234/WorkflowService1");
        WorkflowServiceHost host = new WorkflowServiceHost(workflow, address);

        // Behaviours
        host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
        host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
        host.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });

        // Persistence
        var connStr = @"";
        var behavior = new SqlWorkflowInstanceStoreBehavior(connStr);
        behavior.InstanceCompletionAction = InstanceCompletionAction.DeleteNothing;
        behavior.InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry;
        behavior.InstanceEncodingOption = InstanceEncodingOption.None;
        host.Description.Behaviors.Add(behavior);

        // Add extension implementations
        if (!TEST_MODE)
        {
            host.WorkflowExtensions.Add(new MyExtension());                
        }
        else
        {
            host.WorkflowExtensions.Add(new MyExtensionTest());
        }

        host.Faulted += new EventHandler(host_Faulted);

        host.Open();

        foreach (System.ServiceModel.Description.ServiceEndpoint endpoint in host.Description.Endpoints)
        {
            Console.WriteLine(endpoint.Address);
        }

        Console.WriteLine("Listening...");
        Console.ReadLine();
        host.Close();
    }

Solved it as follows, self-hosting style:

    static void Main(string[] args)
    {
        Workflow1 workflow = new Workflow1();
        // Provide some default values; note: these will be overriden once method on the service is called.
        workflow.productID = -1;

        Uri address = new Uri("http://localhost:1234/WorkflowService1");
        WorkflowServiceHost host = new WorkflowServiceHost(workflow, address);

        // Behaviours
        host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
        host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
        host.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });

        // Persistence
        var connStr = @"";
        var behavior = new SqlWorkflowInstanceStoreBehavior(connStr);
        behavior.InstanceCompletionAction = InstanceCompletionAction.DeleteNothing;
        behavior.InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry;
        behavior.InstanceEncodingOption = InstanceEncodingOption.None;
        host.Description.Behaviors.Add(behavior);

        // Add extension implementations
        if (!TEST_MODE)
        {
            host.WorkflowExtensions.Add(new MyExtension());                
        }
        else
        {
            host.WorkflowExtensions.Add(new MyExtensionTest());
        }

        host.Faulted += new EventHandler(host_Faulted);

        host.Open();

        foreach (System.ServiceModel.Description.ServiceEndpoint endpoint in host.Description.Endpoints)
        {
            Console.WriteLine(endpoint.Address);
        }

        Console.WriteLine("Listening...");
        Console.ReadLine();
        host.Close();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文