Como: hospedar várias versões de um fluxo de trabalho lado a lado
O WorkflowIdentity
fornece uma maneira para que os desenvolvedores de aplicativos de fluxo de trabalho associem um nome e uma versão a uma definição de fluxo de trabalho, e para que essas informações sejam associadas a uma instância de fluxo de trabalho persistida. Essas informações de identidade podem ser usadas por desenvolvedores de aplicativos de fluxo de trabalho para habilitar cenários como execução lado a lado de várias versões de uma definição de fluxo de trabalho, e fornece o pilar para outra funcionalidade como a atualização dinâmica. Esta etapa no tutorial demonstra como usar o WorkflowIdentity
para hospedar ao mesmo tempo várias versões de um fluxo de trabalho.
Neste tópico
Nesta etapa do tutorial, as atividades WriteLine
no fluxo de trabalho são modificadas para fornecer informações adicionais e uma nova atividade WriteLine
é adicionada. Uma cópia do assembly original do fluxo de trabalho é armazenada e o aplicativo host é atualizado de forma que possa executar os fluxos de trabalho atualizados e originais ao mesmo tempo.
Para fazer uma cópia do projeto NumberGuessWorkflowActivities
Para atualizar WorkflowVersionMap para incluir as versões anteriores do fluxo de trabalho
Observação
Antes de seguir as etapas deste tópico, execute o aplicativo, inicie vários fluxos de trabalho de cada tipo e dê um ou dois palpites para cada um. Esses fluxos de trabalho persistentes são usados nesta etapa e na etapa seguinte, Como: Atualizar a definição de uma instância de fluxo de trabalho em execução.
Para fazer uma cópia do projeto NumberGuessWorkflowActivities
Abra a solução WF45GettingStartedTutorial no Visual Studio 2012 se não estiver aberta.
Pressione CTRL+SHIFT+B para criar a solução.
Feche a solução WF45GettingStartedTutorial.
Abra o Windows Explorer e navegue até a pasta onde o arquivo da solução do tutorial e as pastas do projeto estão localizados.
Crie uma nova pasta chamada PreviousVersions na mesma pasta que NumberGuessWorkflowHost e NumberGuessWorkflowActivities. Essa pasta é usada para conter os assemblies que contêm as versões diferentes dos fluxos de trabalho usados nas etapas subsequentes do tutorial.
Navegue até a pasta NumberGuessWorkflowActivities\bin\debug (ou bin\release dependendo das configurações do seu projeto). Copie NumberGuessWorkflowActivities.dll e cole-o na pasta PreviousVersions.
Renomeie NumberGuessWorkflowActivities.dll na pasta PreviousVersions para NumberGuessWorkflowActivities_v1.dll.
Observação
As etapas deste tópico demonstram uma maneira de gerenciar os assemblies usados para conter várias versões dos fluxos de trabalho. Outros métodos como nomeação forte dos assemblies e registrando deles no cache de assembly global também podem ser usados.
Crie uma nova pasta chamada NumberGuessWorkflowActivities_du na mesma pasta que NumberGuessWorkflowHost, NumberGuessWorkflowActivities e a pasta PreviousVersions recém-adicionada e copie todas os arquivos e subpastas da pasta NumberGuessWorkflowActivities para a nova pasta NumberGuessWorkflowActivities_du. Esta cópia de backup do projeto para a versão inicial das atividades é usada em Como: Atualizar a definição de uma instância de fluxo de trabalho em execução.
Reabra a solução WF45GettingStartedTutorial no Visual Studio 2012.
Para atualizar os fluxos de trabalho
Nesta seção, as definições de fluxo de trabalho são atualizadas. As duas atividades WriteLine
que fornecem comentários sobre o palpite do usuário são atualizadas, e uma nova atividade WriteLine
é adicionada, que fornece informações adicionais sobre o jogo quando o número é acertado.
Para atualizar o fluxo de trabalho de StateMachine
No Gerenciador de Soluções, no projeto NumberGuessWorkflowActivities, clique duas vezes em StateMachineNumberGuessWorkflow.xaml.
Clique duas vezes na transição Adivinhar incorreto na máquina de estado.
Atualize o
Text
doWriteLine
mais à esquerda na atividadeIf
.Guess & " is too low."
Guess + " is too low."
Atualize o
Text
doWriteLine
mais à direita na atividadeIf
.Guess & " is too high."
Guess + " is too high."
Retorne à exibição geral da máquina de estado no designer de fluxo de trabalho clicando em StateMachine na exibição de trilha na parte superior do designer de fluxo de trabalho.
Clique duas vezes na transição Guess Correct na máquina de estado.
Arraste uma atividade WriteLine da seção Primitives da Toolbox e solte-a no rótulo Drop Action activity here da transição.
Digite a seguinte expressão na caixa de propriedades de
Text
.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Para atualizar o fluxo de trabalho de Fluxograma
No Gerenciador de Soluções, no projeto NumberGuessWorkflowActivities, clique duas vezes em FlowchartNumberGuessWorkflow.xaml.
Atualize o
Text
doWriteLine
mais à esquerda.Guess & " is too low."
Guess + " is too low."
Atualize o
Text
doWriteLine
mais à direita.Guess & " is too high."
Guess + " is too high."
Arraste uma atividade WriteLine da seção Primitives da Toolbox e solte-a no ponto de soltar da ação
True
doFlowDecision
superior. A atividadeWriteLine
é adicionada ao fluxograma e vinculada à açãoTrue
doFlowDecision
.Digite a seguinte expressão na caixa de propriedades de
Text
.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Para atualizar o fluxo de trabalho Sequencial
No Gerenciador de Soluçõesr, no projeto NumberGuessWorkflowActivities, clique duas vezes em SequentialNumberGuessWorkflow.xaml.
Atualize o
Text
doWriteLine
mais à esquerda na atividadeIf
.Guess & " is too low."
Guess + " is too low."
Atualize o
Text
da atividadeWriteLine
mais à direita na atividadeIf
.Guess & " is too high."
Guess + " is too high."
Arraste uma atividade WriteLine da seção Primitives da Toolbox e solte-a após a atividade DoWhile para que a WriteLine é a atividade final na atividade
Sequence
raiz.Digite a seguinte expressão na caixa de propriedades de
Text
.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Para atualizar WorkflowVersionMap para incluir as versões anteriores do fluxo de trabalho
Clique duas vezes em WorkflowVersionMap.cs (ou WorkflowVersionMap.vb) no projeto NumberGuessWorkflowHost para abri-lo.
Adicione as seguintes instruções
using
(ouImports
) na parte superior do arquivo com as outras instruçõesusing
(ouImports
).Imports System.Reflection Imports System.IO
using System.Reflection; using System.IO;
Adicione três novas identidades de fluxo de trabalho abaixo das três declarações de identidade de fluxo de trabalho existentes. Essas novas identidades de fluxo de trabalho
v1
serão usadas para fornecer a definição correta para fluxos de trabalho iniciados antes que as atualizações foram feitas.'Current version identities. Public StateMachineNumberGuessIdentity As WorkflowIdentity Public FlowchartNumberGuessIdentity As WorkflowIdentity Public SequentialNumberGuessIdentity As WorkflowIdentity 'v1 Identities. Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity
// Current version identities. static public WorkflowIdentity StateMachineNumberGuessIdentity; static public WorkflowIdentity FlowchartNumberGuessIdentity; static public WorkflowIdentity SequentialNumberGuessIdentity; // v1 identities. static public WorkflowIdentity StateMachineNumberGuessIdentity_v1; static public WorkflowIdentity FlowchartNumberGuessIdentity_v1; static public WorkflowIdentity SequentialNumberGuessIdentity_v1;
No construtor
WorkflowVersionMap
, atualize a propriedadeVersion
das três identidades atuais de fluxo de trabalho para2.0.0.0
.'Add the current workflow version identities. StateMachineNumberGuessIdentity = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } FlowchartNumberGuessIdentity = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } SequentialNumberGuessIdentity = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow()) map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow()) map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow())
// Add the current workflow version identities. StateMachineNumberGuessIdentity = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; FlowchartNumberGuessIdentity = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; SequentialNumberGuessIdentity = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow()); map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow()); map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow());
Esse código adiciona as versões atuais dos fluxos de trabalho para o dicionário que usa as versões atuais que são referenciadas no projeto, de modo que o código que inicializa as definições de fluxo de trabalho não precise ser atualizado.
Adicione o seguinte código no construtor imediatamente depois do código que adiciona as versões atuais ao dicionário.
'Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) }
// Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; SequentialNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) };
Essas identidades de fluxo de trabalho são associadas às versões iniciais das definições de fluxo de trabalho correspondentes.
Em seguida, carregue o assembly que contém a versão inicial das definições de fluxo de trabalho, e crie e adicione as definições correspondentes do fluxo de trabalho ao dicionário.
'Add the previous version workflow identities to the dictionary along with 'the corresponding workflow definitions loaded from the v1 assembly. 'Assembly.LoadFile requires an absolute path so convert this relative path 'to an absolute path. Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll" v1AssemblyPath = Path.GetFullPath(v1AssemblyPath) Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath) map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow")) map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow")) map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow"))
// Add the previous version workflow identities to the dictionary along with // the corresponding workflow definitions loaded from the v1 assembly. // Assembly.LoadFile requires an absolute path so convert this relative path // to an absolute path. string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"; v1AssemblyPath = Path.GetFullPath(v1AssemblyPath); Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath); map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity); map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity); map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity);
O exemplo a seguir é a listagem completa para a classe
WorkflowVersionMap
atualizada.Public Module WorkflowVersionMap Dim map As Dictionary(Of WorkflowIdentity, Activity) 'Current version identities. Public StateMachineNumberGuessIdentity As WorkflowIdentity Public FlowchartNumberGuessIdentity As WorkflowIdentity Public SequentialNumberGuessIdentity As WorkflowIdentity 'v1 Identities. Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity Sub New() map = New Dictionary(Of WorkflowIdentity, Activity) 'Add the current workflow version identities. StateMachineNumberGuessIdentity = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } FlowchartNumberGuessIdentity = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } SequentialNumberGuessIdentity = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(2, 0, 0, 0) } map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow()) map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow()) map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow()) 'Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "StateMachineNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "FlowchartNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With { .Name = "SequentialNumberGuessWorkflow", .Version = New Version(1, 0, 0, 0) } 'Add the previous version workflow identities to the dictionary along with 'the corresponding workflow definitions loaded from the v1 assembly. 'Assembly.LoadFile requires an absolute path so convert this relative path 'to an absolute path. Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll" v1AssemblyPath = Path.GetFullPath(v1AssemblyPath) Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath) map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow")) map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow")) map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow")) End Sub Public Function GetWorkflowDefinition(identity As WorkflowIdentity) As Activity Return map(identity) End Function Public Function GetIdentityDescription(identity As WorkflowIdentity) As String Return identity.ToString() End Function End Module
public static class WorkflowVersionMap { static Dictionary<WorkflowIdentity, Activity> map; // Current version identities. static public WorkflowIdentity StateMachineNumberGuessIdentity; static public WorkflowIdentity FlowchartNumberGuessIdentity; static public WorkflowIdentity SequentialNumberGuessIdentity; // v1 identities. static public WorkflowIdentity StateMachineNumberGuessIdentity_v1; static public WorkflowIdentity FlowchartNumberGuessIdentity_v1; static public WorkflowIdentity SequentialNumberGuessIdentity_v1; static WorkflowVersionMap() { map = new Dictionary<WorkflowIdentity, Activity>(); // Add the current workflow version identities. StateMachineNumberGuessIdentity = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; FlowchartNumberGuessIdentity = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; SequentialNumberGuessIdentity = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", // Version = new Version(1, 0, 0, 0), Version = new Version(2, 0, 0, 0) }; map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow()); map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow()); map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow()); // Initialize the previous workflow version identities. StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; SequentialNumberGuessIdentity_v1 = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; // Add the previous version workflow identities to the dictionary along with // the corresponding workflow definitions loaded from the v1 assembly. // Assembly.LoadFile requires an absolute path so convert this relative path // to an absolute path. string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"; v1AssemblyPath = Path.GetFullPath(v1AssemblyPath); Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath); map.Add(StateMachineNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity); map.Add(SequentialNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity); map.Add(FlowchartNumberGuessIdentity_v1, v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity); } public static Activity GetWorkflowDefinition(WorkflowIdentity identity) { return map[identity]; } public static string GetIdentityDescription(WorkflowIdentity identity) { return identity.ToString(); } }
Para criar e executar o aplicativo
Pressione CTRL+SHIFT+B para criar o aplicativo, e CTRL+F5 para iniciar.
Inicie um novo fluxo de trabalho clicando em Novo Jogo. A versão do fluxo de trabalho é exibida abaixo da janela de status e reflete a versão atualizada do
WorkflowIdentity
associado. Faça uma anotação doInstanceId
para que você possa exibir o arquivo de rastreamento para o fluxo de trabalho quando ele for concluído, e insira os palpites até que o jogo seja concluído. Observe como o palpite do usuário é exibido nas informações exibidas na janela de status com base nas atualizações das atividadesWriteLine
.Please enter a number between 1 and 10 5 is too high. Please enter a number between 1 and 10 3 is too high. Please enter a number between 1 and 10 1 is too low. Please enter a number between 1 and 10 Congratulations, you guessed the number in 4 turns.
Observação
O texto atualizado das atividades
WriteLine
é exibido, mas não a saída final da atividadeWriteLine
final que foi adicionada neste tópico. Isso ocorre porque a janela de status é atualizada pelo manipuladorPersistableIdle
. Como o fluxo de trabalho é concluído e não fica ocioso após a atividade final, o manipuladorPersistableIdle
não é chamado. No entanto, uma mensagem semelhante é exibida na janela de status pelo manipuladorCompleted
. Se desejar, um código pode ser adicionado ao manipuladorCompleted
para extrair o texto deStringWriter
e exibi-lo na janela de status.Abra o Windows Explorer e navegue até a pasta NumberGuessWorkflowHost\bin\debug (ou bin\release dependendo das configurações do seu projeto) e abra o arquivo de rastreamento usando o Bloco de Notas que corresponde ao fluxo de trabalho concluído. Se você não anotou o
InstanceId
, poderá identificar o arquivo de rastreamento correto usando as informações de Data de modificação no Windows Explorer.Please enter a number between 1 and 10 5 is too high. Please enter a number between 1 and 10 3 is too high. Please enter a number between 1 and 10 1 is too low. Please enter a number between 1 and 10 2 is correct. You guessed it in 4 turns.
A saída
WriteLine
atualizada está contida no arquivo de rastreamento, incluindo a saída deWriteLine
que foi adicionada neste tópico.Alterne novamente para o aplicativo de palpite de número e selecione um dos fluxos de trabalho que foi iniciado antes que as atualizações foram feitas. Você pode identificar a versão do fluxo de trabalho selecionado no momento examinando as informações de versão que são exibidas embaixo da janela de status. Insira alguns palpites e observe que as atualizações de status correspondem à saída da atividade
WriteLine
da versão anterior, e não incluem o palpite do usuário. Isso ocorre porque esses fluxos de trabalho estão usando a definição do fluxo de trabalho anterior que não tem as atualizaçõesWriteLine
.Na próxima etapa, Como: Atualizar a definição de uma instância de fluxo de trabalho em execução, as instâncias de fluxo de trabalho
v1
em execução são atualizadas para que contenham a nova funcionalidade como instânciasv2
.