Предоставление расширений рабочих процессов для службы рабочих процессов - WF 4.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);
}

Затем я вставляю это действие в службу рабочего процесса и пытаюсь использовать ее через мое веб-приложение, добавив ссылку на службу. Однако, когда я добавляю ссылку, я получаю:

System.Activities.ValidationException: Для запуска этого рабочего процесса необходимо настроить расширение типа "PizzaMan.ActivityLibrary.IPreparePizzaExtension".

Справедливости ради - конечно, моя деятельность требует, чтобы я передал ему реализацию IPreparePizzaExtension - в конце концов, я сказал об этом!

Итак, мой вопрос, как же мне передать это на службу? Я могу достаточно легко управлять этим в сценарии консольного приложения, используя WorkflowInvoker, но я не вижу никакого очевидного способа сделать это с помощью сервисного подхода. Я бы предположил, что, очевидно, программный подход к добавлению ссылки - это то, что нужно, но опять же я не знаю, как именно это сделать.

Любая помощь будет принята с благодарностью.

С наилучшими пожеланиями, Ян

4 ответа

Решение

WorkflowServiceHost имеет свойство WorkflowExtensions, в которое можно добавить расширение рабочего процесса. Есть несколько способов сделать это. Если вы самостоятельно размещаете хостинг, это легко, так как вы создаете WorkflowServiceHost. Если вы используете IIS, вам нужно создать ServiceHostFactory для настройки вашего WorkflowServiceHost. Наконец, есть возможность добавить расширение рабочего процесса в CacheMetadata вашей деятельности, используя функцию metadata.AddDefaultExtensionProvider().

Решено это следующим образом, в стиле хостинга:

    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();
    }

Мой инструментарий имеет поддержку конфигурации для этого. См. http://neovolve.codeplex.com/wikipage?title=Neovolve.Toolkit.Workflow.dll%20-%201.1

Существует также этот метод выполнения действий: http://wf.codeplex.com/wikipage?title=How%20do%20I%20add%20an%20extension%20to%20a%20WCF%20Workflow%20Service?

Другие вопросы по тегам