WF4 RC - невозможно создать неизвестный тип при загрузке службы WF из свободного Xaml с помощью ActivityXamlServices - PullRequest
8 голосов
/ 25 февраля 2010

Я пытаюсь разместить Сервис WF4 (RC) динамически. У меня есть тестовое решение с двумя проектами. Первая - это декларативная библиотека службы рабочего процесса с одним корневым действием потоковой диаграммы и простым пользовательским действием кода. Библиотека службы рабочего процесса не зависит от каких-либо других пользовательских сборок или ссылок. Второе - это мое хост-приложение, которое в моем тестовом решении представляет собой просто консольное приложение.

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

Как только я пытаюсь обновить объект WorkflowServiceHost, я получаю это исключение ...

Невозможно создать неизвестный тип {CLR-имен: DeclarativeServiceLibrary1} CodeActivity1 '

.

Если я удаляю CodeActivity1 из моего конструктора потоковых диаграмм, все работает нормально. Если я добавлю прямую ссылку на проект службы рабочего процесса из моего хост-проекта, а затем создаю WorkflowServiceHost, используя экземпляр моего действия Flowchart вместо действия, созданного из Xaml, он также будет работать нормально.

Кажется, по какой-то причине мне не нравится использовать мой CodeActivity при динамической загрузке.

У кого-нибудь есть идеи относительно того, почему я не могу динамически создать службу рабочего процесса?

Мой код выглядит следующим образом ...

DeclarativeServiceLibrary1.Activity1.xaml ...

<Activity mc:Ignorable="sap" x:Class="DeclarativeServiceLibrary1.Activity1" sap:VirtualizedContainerService.HintSize="654,676" mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:DeclarativeServiceLibrary1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Flowchart sad:XamlDebuggerXmlReader.FileName="C:\dev\test\MyWorkflow\DeclarativeServiceLibrary1\Activity1.xaml" sap:VirtualizedContainerService.HintSize="614,636">
    <sap:WorkflowViewStateService.ViewState>
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">False</x:Boolean>
        <av:Point x:Key="ShapeLocation">270,2.5</av:Point>
        <av:Size x:Key="ShapeSize">60,75</av:Size>
        <av:PointCollection x:Key="ConnectorLocation">300,77.5 300,107.5 300,165</av:PointCollection>
      </scg3:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <Flowchart.StartNode>
      <FlowStep x:Name="__ReferenceID0">
        <sap:WorkflowViewStateService.ViewState>
          <scg3:Dictionary x:TypeArguments="x:String, x:Object">
            <av:Point x:Key="ShapeLocation">172.5,165</av:Point>
            <av:Size x:Key="ShapeSize">255,90</av:Size>
            <av:PointCollection x:Key="ConnectorLocation">300,255 300,285 300,299.5</av:PointCollection>
          </scg3:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <p:Receive CanCreateInstance="True" sap:VirtualizedContainerService.HintSize="255,90" OperationName="MyOperation" ServiceContractName="MyContractName" />
        <FlowStep.Next>
          <FlowStep x:Name="__ReferenceID1">
            <sap:WorkflowViewStateService.ViewState>
              <scg3:Dictionary x:TypeArguments="x:String, x:Object">
                <av:Point x:Key="ShapeLocation">194.5,299.5</av:Point>
                <av:Size x:Key="ShapeSize">211,61</av:Size>
                <av:PointCollection x:Key="ConnectorLocation">300,360.5 300,390.5 300,399</av:PointCollection>
              </scg3:Dictionary>
            </sap:WorkflowViewStateService.ViewState>
            <WriteLine sap:VirtualizedContainerService.HintSize="211,61" Text="Workflow started" />
            <FlowStep.Next>
              <FlowStep x:Name="__ReferenceID3">
                <sap:WorkflowViewStateService.ViewState>
                  <scg3:Dictionary x:TypeArguments="x:String, x:Object">
                    <av:Point x:Key="ShapeLocation">200,399</av:Point>
                    <av:Size x:Key="ShapeSize">200,22</av:Size>
                    <av:PointCollection x:Key="ConnectorLocation">300,421 300,451 300,479.5</av:PointCollection>
                  </scg3:Dictionary>
                </sap:WorkflowViewStateService.ViewState>
                <local:CodeActivity1 sap:VirtualizedContainerService.HintSize="200,22" />
                <FlowStep.Next>
                  <FlowStep x:Name="__ReferenceID2">
                    <sap:WorkflowViewStateService.ViewState>
                      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
                        <av:Point x:Key="ShapeLocation">194.5,479.5</av:Point>
                        <av:Size x:Key="ShapeSize">211,61</av:Size>
                      </scg3:Dictionary>
                    </sap:WorkflowViewStateService.ViewState>
                    <WriteLine sap:VirtualizedContainerService.HintSize="211,61" Text="The code activity worked!" />
                  </FlowStep>
                </FlowStep.Next>
              </FlowStep>
            </FlowStep.Next>
          </FlowStep>
        </FlowStep.Next>
      </FlowStep>
    </Flowchart.StartNode>
    <x:Reference>__ReferenceID0</x:Reference>
    <x:Reference>__ReferenceID1</x:Reference>
    <x:Reference>__ReferenceID2</x:Reference>
    <x:Reference>__ReferenceID3</x:Reference>
  </Flowchart>
</Activity>

DeclarativeServiceLibrary1.CodeActivity1.cs ...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;

namespace DeclarativeServiceLibrary1
{

    public sealed class CodeActivity1 : CodeActivity
    {
        // Define an activity input argument of type string
        //public InArgument<string> Text { get; set; }

        // 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
            //string text = context.GetValue(this.Text);
        }
    }
}

DeclarativeServiceLibrary1.Web.Config ...

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

ConsoleApplication1.Program.cs ...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.XamlIntegration;
using System.ServiceModel;
using System.ServiceModel.Activities;
using System.ServiceModel.Description;
using System.Xaml;
using System.Reflection;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {            
            string baseAddress = @"http://localhost:8081/MyContractName";

            string curDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            string wfDefPath =  Path.Combine(curDir, "Activity1.xaml");

            Activity workflowActivity = (Activity)ActivityXamlServices.Load(wfDefPath); 
            WorkflowService service = new WorkflowService { Body = workflowActivity }; 
            Uri serviceUri = new Uri(baseAddress, UriKind.Absolute); 
            WorkflowServiceHost host = new WorkflowServiceHost(service, new Uri[] { serviceUri }); 
            host.Open();

            //Display that we are listening on the console window
            Console.WriteLine("Workflow '{0}' is listening at '{1}'", host.Activity.DisplayName, baseAddress);
            Console.ReadLine();
        }
    }
}

У меня есть событие после сборки в библиотеке службы рабочего процесса, которая копирует файл Assembly и Xaml в папку bin \ debug \ приложения консоли хоста.

Ответы [ 4 ]

12 голосов
/ 26 февраля 2010

Краткий ответ - загрузка Xaml не может определить локальную сборку (по умолчанию), поэтому вам необходимо указать ее в XamlReaderSettings.LocalAssembly.

9 голосов
/ 05 мая 2010

Открытый исходный код действия. Измените "xmlns: local =" clr-namespace: DeclarativeServiceLibrary1 "на XMLNS: локальные = "CLR-имена: DeclarativeServiceLibrary1; сборка = DeclarativeServiceLibrary1" * * 1 001.

0 голосов
/ 25 февраля 2010

Глядя на ваш код, я могу сказать, что вы должны загрузить WorkflowService вместо простого действия. Здесь есть два варианта:

Вариант 1: загрузить действие и разместить его в сгенерированной службе рабочего процесса.

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

WorkflowService service = new WorkflowService();
service.Body = loadedActivity;

После этого вы можете разместить его внутри хоста службы рабочего процесса.

Вариант 2. Загрузка службы рабочего процесса напрямую

Второй вариант мало чем отличается от того, что есть у вас сейчас. Но вместо использования класса ActivityXamlServices вам нужно будет использовать класс XamlServices для загрузки службы рабочего процесса. После этого нужно запустить узел службы рабочего процесса с параметрами, которые вы использовали в своем примере.

0 голосов
/ 25 февраля 2010

Вы десериализуете файл xaml напрямую, но он ссылается на тип (CodeActivity1), который скомпилирован как тип CLR в сборку DeclarativeServiceLibrary1. Наиболее очевидный ответ заключается в том, что сборка DeclarativeServiceLibrary1 недоступна консольному приложению во время выполнения. Убедитесь, что эта сборка скопирована в папку, в которой вы запускаете консольное приложение (\ bin \ debug), и посмотрите, имеет ли это значение.

Суть в том, что даже если вы читаете файл xaml напрямую, ему все равно нужен доступ ко всем типам, на которые он ссылается.

...