Como: Hospedar várias versões de um fluxo de trabalho lado a lado
WorkflowIdentity
Fornece uma maneira para os desenvolvedores de aplicativos de fluxo de trabalho associarem 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 persistente. Essas informações de identidade podem ser usadas por desenvolvedores de aplicativos de fluxo de trabalho para habilitar cenários como a execução lado a lado de várias versões de uma definição de fluxo de trabalho e fornecem a pedra angular para outras funcionalidades, como a atualização dinâmica. Esta etapa no tutorial demonstra como usar WorkflowIdentity
para hospedar várias versões de um fluxo de trabalho ao mesmo tempo.
Neste tópico
Nesta etapa do tutorial, as WriteLine
atividades no fluxo de trabalho são modificadas para fornecer informações adicionais e uma nova WriteLine
atividade é adicionada. Uma cópia do assembly de fluxo de trabalho original é armazenada e o aplicativo host é atualizado para que possa executar os fluxos de trabalho original e atualizado ao mesmo tempo.
Para fazer uma cópia do projeto NumberGuessWorkflowActivities
Para atualizar o WorkflowVersionMap para incluir as versões anteriores do fluxo de trabalho
Nota
Antes de seguir as etapas neste tópico, execute o aplicativo, inicie vários fluxos de trabalho de cada tipo e faça um ou dois palpites para cada um. Esses fluxos de trabalho persistentes são usados nesta etapa e na etapa a seguir, 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 ela não estiver aberta.
Prima CTRL+SHIFT+B para compilar a solução.
Feche a solução WF45GettingStartedTutorial .
Abra o Windows Explorer e navegue até a pasta onde o arquivo de solução tutorial e as pastas do projeto estão localizados.
Crie uma nova pasta chamada PreviousVersions na mesma pasta que NumberGuessWorkflowHost e NumberGuessWorkflowActivities. Esta pasta é usada para conter os assemblies que contêm as diferentes versões 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 projeto). Copie-NumberGuessWorkflowActivities.dll e cole-o na pasta PreviousVersions.
Renomeie NumberGuessWorkflowActivities.dll na pasta PreviousVersions para NumberGuessWorkflowActivities_v1.dll.
Nota
As etapas neste tópico demonstram uma maneira de gerenciar os assemblies usados para conter várias versões dos fluxos de trabalho. Outros métodos, como nomear fortemente os assemblies e registrá-los no cache global de assemblies 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 todos 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 WriteLine
atividades que dão feedback sobre o palpite do usuário são atualizadas, e uma nova WriteLine
atividade é adicionada que fornece informações adicionais sobre o jogo assim que o número é adivinhado.
Para atualizar o fluxo de trabalho 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
dos maisWriteLine
à esquerda naIf
atividade.Guess & " is too low."
Guess + " is too low."
Atualize o
Text
dos maisWriteLine
à direita naIf
atividade.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 Adivinhar Correto na máquina de estado.
Arraste uma atividade WriteLine da seção Primitivos da Caixa de Ferramentas e solte-a no rótulo Drop Action activity here da transição.
Digite a seguinte expressão na caixa de
Text
propriedade.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Para atualizar o fluxo de trabalho do Fluxograma
No Gerenciador de Soluções, no projeto NumberGuessWorkflowActivities , clique duas vezes em FlowchartNumberGuessWorkflow.xaml.
Atualize a
Text
atividade maisWriteLine
à esquerda.Guess & " is too low."
Guess + " is too low."
Atualize a
Text
atividade maisWriteLine
à direita.Guess & " is too high."
Guess + " is too high."
Arraste uma atividade WriteLine da seção Primitivos da Caixa de Ferramentas e solte-a no ponto de soltar da
True
ação do topoFlowDecision
. AWriteLine
atividade é adicionada ao fluxograma e vinculada àTrue
ação doFlowDecision
.Digite a seguinte expressão na caixa de
Text
propriedade.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ções, no projeto NumberGuessWorkflowActivities , clique duas vezes em SequentialNumberGuessWorkflow.xaml.
Atualize o
Text
dos maisWriteLine
à esquerda naIf
atividade.Guess & " is too low."
Guess + " is too low."
Atualize a
Text
atividade maisWriteLine
à direita naIf
atividade.Guess & " is too high."
Guess + " is too high."
Arraste uma atividade WriteLine da seção Primitivos da Caixa de Ferramentas e solte-a após a atividade DoWhile para que a WriteLine seja a atividade final na atividade raiz
Sequence
.Digite a seguinte expressão na caixa de
Text
propriedade.Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Para atualizar o WorkflowVersionMap para incluir as versões anteriores do fluxo de trabalho
Clique duas vezes em WorkflowVersionMap.cs (ou WorkflowVersionMap.vb) sob o projeto NumberGuessWorkflowHost para abri-lo.
Adicione as seguintes
using
(ouImports
) instruções à parte superior do arquivo com as outrasusing
(ouImports
) instruções.Imports System.Reflection Imports System.IO
using System.Reflection; using System.IO;
Adicione três novas identidades de fluxo de trabalho logo abaixo das três declarações de identidade de fluxo de trabalho existentes. Essas novas
v1
identidades de fluxo de trabalho serão usadas para fornecer a definição correta de fluxo de trabalho para fluxos de trabalho iniciados antes que as atualizações fossem 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;
WorkflowVersionMap
No construtor, atualize aVersion
propriedade das três identidades de fluxo de trabalho atuais 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());
O código que adiciona as versões atuais dos fluxos de trabalho ao dicionário usa as versões atuais que são referenciadas no projeto, portanto, o código que inicializa as definições de fluxo de trabalho não precisa ser atualizado.
Adicione o seguinte código no construtor logo após o 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 estã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 de fluxo de trabalho correspondentes 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 atualizada
WorkflowVersionMap
.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, em seguida, CTRL+F5 para iniciar.
Inicie um novo fluxo de trabalho clicando em Novo Jogo. A versão do fluxo de trabalho é exibida na janela de status e reflete a versão atualizada do arquivo
WorkflowIdentity
. Anote oInstanceId
para que você possa visualizar o arquivo de acompanhamento do fluxo de trabalho quando ele for concluído e, em seguida, insira suposições 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 dasWriteLine
atividades.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.
Nota
O texto atualizado das
WriteLine
atividades é exibido, mas a saída da atividade finalWriteLine
que foi adicionada neste tópico não é. Isso ocorre porque a janela de status é atualizada peloPersistableIdle
manipulador. Como o fluxo de trabalho é concluído e não fica ocioso após a atividade final, oPersistableIdle
manipulador não é chamado. No entanto, uma mensagem semelhante é exibida na janela de status peloCompleted
manipulador. Se desejar, oCompleted
código pode ser adicionado ao manipulador para extrair o texto do e exibi-lo na janela deStringWriter
status.Abra o Windows Explorer e navegue até a pasta NumberGuessWorkflowHost\bin\debug (ou bin\release , dependendo das configurações do projeto) e abra o arquivo de acompanhamento usando o Bloco de Notas que corresponde ao fluxo de trabalho concluído. Se você não anotou o
InstanceId
, você pode identificar o arquivo de controle 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 atualizada
WriteLine
está contida no arquivo de rastreamento, incluindo a saída doWriteLine
que foi adicionado neste tópico.Volte para o aplicativo de adivinhação de números e selecione um dos fluxos de trabalho que foi iniciado antes das atualizações serem feitas. Você pode identificar a versão do fluxo de trabalho selecionado no momento examinando as informações de versão exibidas abaixo da janela de status. Insira alguns palpites e observe que as atualizações de status correspondem à
WriteLine
saída de atividade 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 de fluxo de trabalho anterior que não tem asWriteLine
atualizações.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 em execução
v1
são atualizadas para que contenham a nova funcionalidade como asv2
instâncias.