Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

49
versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS

Transcript of Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

Page 1: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Tecgraf PUC-RioNovembro de 2013

API C# do SCS

Page 2: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

A API do SCS

• A API da biblioteca SCS permite a construção de componentes– Manualmente– Através de descritores

• A API lida apenas com a representação local do componente– Encarrega-se apenas da construção– Não lida com a composição de vários componentes

(que pode ser distribuída)• A representação local de um componente

SCS-C# é dada pela interface ComponentContext

Page 3: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Criação de um Componente

• São necessários alguns passos:

1.Alterar facetas básicas (opcional)2.Implementar suas facetas (opcional)3.Criar o ComponentId4.Instanciar a representação local do

componente5.Adicionar facetas (opcional)6.Adicionar receptáculos (opcional)

Page 4: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Criação de um Componente

• Outra opção é utilizar descritores XML• Externalizam como deve ser a construção do

componente• Não é necessário recompilar o código para

mudar a configuração do componente• Os passos passam a ser:

• Descrever o componente em um arquivo XML• Implementar suas facetas (opcional)• Utilizar a API para construir o componente a

partir do arquivo XML

Page 5: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Implementação de uma Faceta

Page 6: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Uma faceta SCS nada mais é do que uma implementação de uma interface CORBA

• O SCS adiciona algumas convenções, mas a implementação da interface se dá da mesma forma

public class MyFacetServant : MarshalByRefObject, MyFacet { }

Criação de Facetas

Page 7: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Pode ser útil também ter um construtor que receba a representação local do componente ao qual essa faceta pertencerá

• Assim pode-se ter acesso a outras facetas e dados comuns ao componente como um todo

• Essa representação local é chamada de contexto do componente (interface ComponentContext)

• Esse construtor não é obrigatório, a não ser na construção por XML

Criação de Facetas

Page 8: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Exemplo de faceta completapublic class MyFacetServant : MarshalByRefObject, MyFacet {

private ComponentContext _context;

public MyFacetServant(ComponentContext context) { _context = context; }

...}

Criação de Facetas

Page 9: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Representação Local do Componente (ComponentContext)

Page 10: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Definição do ComponentId• Idêntico ao demonstrado na IDL

ComponentId cpId = new ComponentId( “MyComponentName”, 1, 0, 0, “.NET 4.0”);

Criação do ComponentId

Page 11: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• ComponentContext– Atua como um envólucro que facilita o uso do

componente como uma entidade única e não apenas um aglomerado de facetas e receptáculos• Representação local do componente• Acesso a todas as facetas (incluindo as básicas) e receptáculos• Guarda os metadados, como descrições de facetas e receptáculos e identificador do componente (ComponentId)•Implementação padrão dada pela classe DefaultComponentContext

O Componente C#

Page 12: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• ComponentContext – Diferença entre representações– Visão distribuída de um componente

– Em um ambiente distribuído (CORBA), existe apenas o que está no contrato da IDL (scs.idl)– O componente é essencialmente o conjunto das facetas IComponent, IReceptacles, IMetaInterface e facetas adicionais– NÃO existe uma “caixa” que agrupe essas facetas em um bloco, representando o componente como um todo– A faceta IComponent é o que mais se aproxima de representar o componente– Receptáculos não existem de fato, e são manuseados apenas através da faceta IReceptacles

– Visão local de um componente– Objeto ComponentContext une as facetas e receptáculos em uma única representação

O Componente C#

Page 13: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• ComponentContext– A classe DefaultComponentContext pode ser

estendida para adicionar outros dados de uso global no componente• Dados acessados por mais de uma faceta• Dados referentes ao componente em si, não a uma faceta específica• Métodos

O Componente C#

Page 14: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• public (Default)ComponentContext(ComponentId id)– Construtor que recebe o ComponentId– Adiciona automaticamente as facetas básicas (e já as

ativa no ORB)

• ComponentId GetComponentId()– Retorna o ComponentId fornecido no construtor

• IComponent GetIComponent()– Retorna o objeto CORBA referente à faceta IComponent do

componente

Interface C# ComponentContext

Page 15: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• void AddFacet(String name, String interfaceName, MarshalByRefObject servant)– Adiciona uma faceta ao componente– Ativa o objeto CORBA no ORB

• void RemoveFacet(String name)– Remove uma faceta do componente– Desativa o objeto CORBA no ORB

• void UpdateFacet(String name, MarshalByRefObject servant)– Desativa o objeto CORBA da faceta no ORB– Substitui o objeto CORBA pelo novo fornecido– Ativa o novo objeto CORBA no ORB

Interface C# ComponentContext

Page 16: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• void AddReceptacle(String name, String interfaceName, Boolean isMultiple)– Adiciona um receptáculo ao componente

• void RemoveReceptacle(String name)– Remove um receptáculo do componente

Interface C# ComponentContext

Page 17: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• IDictionary<String, Facet> GetFacets()– Retorna um dicionário com todas as facetas do componente,

associadas aos seus nomes– A classe Facet contém o objeto CORBA e os metadados

associados

• Facet GetFacetByName(String name)– Retorna uma faceta específica

• IDictionary<String, Receptacle> GetReceptacles()– Retorna um dicionário com todos os receptáculos do

componente, associados aos seus nomes

• Receptacle GetReceptacleByName(String name)– Retorna um receptáculo específico

Interface C# ComponentContext

Page 18: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Como obter uma faceta a partir de outra?

• Como acessar uma dependência conectada a um receptáculo?

context.GetReceptacleByName(“ReceptacleName”).GetConnections()

context.GetFacetByName(“FacetName”).Reference

Exemplos

Page 19: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Novas implementações podem ser fornecidas para as facetas básicas

• A implementação é feita normalmente como em qualquer faceta / objeto CORBA, basta seguir a interface desejada

• Após criar o ComponentContext, deve-se substituir o servant da faceta desejada pelo novo (método updateFacet)

Alteração de Facetas Básicas

Page 20: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

ComponentId cpId = new ComponentId( “MyComponentName”, (byte) 1, (byte) 0, (byte) 0, “windows”);ComponentContext context = new DefaultComponentContext(cpId);MyIComponentClass myIC = new MyIComponentClass(context);context.UpdateFacet(“IComponent”, myIC);

Alteração de Facetas Básicas

Page 21: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Outras Funcionalidades

Page 22: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• É possível montar um componente a partir de um arquivo descritor em XML ‒ Substitui os passos demonstrados anteriormente

• O descritor deve conter no mínimo: ‒ Identificador do componente

• Pode-se fornecer, opcionalmente: ‒ Descrições de facetas (nome, interface, e classe a ser instanciada)

• A classe da faceta deve conter um construtor que receba apenas um ComponentContext como parâmetro

‒ Descrições de receptáculos (nome, interface, multiplex)‒ Classe a ser usada como ComponentContext

• A biblioteca fornece um arquivo xsd com o formato

XMLComponentBuilder

Page 23: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Exemplo de arquivo XML

<?xml version="1.0" encoding="iso-8859-1" ?><scs:component xmlns:scs="tecgraf.scs.core"> <id> <name>MyComponent</name> <version>1.0.0</version> <platformSpec>.NET 4.0</platformSpec> </id> <facets> <facet> <name>MyFacet</name> <interfaceName>IDL:module/Interface:1.0</interfaceName> <facetImpl>mypackage.InterfaceImpl</facetImpl> </facet> <facet> <name>AnotherFacet</name> <interfaceName>IDL:module/AnotherInterface:1.0</interfaceName> <facetImpl>mypackage.AnotherInterfaceImpl</facetImpl> </facet> </facets></scs:component>

XMLComponentBuilder

Page 24: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

• Exemplo de uso da API

…XmlTextReader reader = new XmlTextReader(args[0]);XmlComponentBuilder xmlBuilder = new XmlComponentBuilder(reader);ComponentContext context = xmlBuilder.build();…

XMLComponentBuilder

Page 25: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Aplicação Exemplo

Page 26: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Exemplo passo-a-passo

• Veremos um exemplo, passo-a-passo, de desenvolvimento de uma aplicação SCS usando C#

• Para desenvolver a aplicação, usaremos o IIOP.NET como ORB tanto para o cliente quanto para o servidor, e as bibliotecas do SCS

Page 27: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Exemplo de Aplicação

StockSeller

StockServer StockExchange

StockLoggerExchangePrinter

• O componente StockSeller implementa duas facetas: StockServer e StockExchange

• O componente StockSeller tem um receptáculo para componentes que implementema faceta ExchangePrinter

• O componente StockLogger implementa a faceta ExchangePrinter

Page 28: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Passo 1: Alterando a IDL

// StockMarket.idl// O módulo StockMarket consiste das definições// úteis para desenvolvimento de aplicações// que lidam com mercado de ações.module StockMarket {

...

// A interface ExchangePrinter é a interface que // representa uma impressora de negociações de ações. interface ExchangePrinter { // Imprime que houve uma negociação da ação indicada. // A saída utilizada para impressão não é especificada. // Exemplos de saídas: tela, arquivo, clients remotos. void print(in StockSymbol symbol); };

// A interface StockExchange é a interface que permite // a compra de ações. interface StockExchange { // Usa os componentes ExchangePrinter que estejam // conectados para imprimir a negociaçao efetuada. boolean buyStock(in StockSymbol symbol); };};

Page 29: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Passo 2: Implementando as facetas

• Facetas são interfaces CORBA e, portanto, sua implementação segue as mesmas regras que vimos nos exemplos de CORBA

• Precisaremos alterar a classe StockServerImpl para que ela se torne uma Faceta SCS

• Além disso, precisaremos implementar as facetas StockExchange e ExchangePrinter

Page 30: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

StockServerImpl

namespace StockSeller { public class StockServerImpl : MarshalByRefObject, StockServer {

public StockServerImpl(StockSellerContext context) { }

/// <summary> /// Retorna o valor corrente de uma ação específica. /// </summary> /// <param name="symbol">Símbolo identificador da ação.</param> /// <returns>O valor da ação requisitada.</returns> public float getStockValue(string symbol) { }

/// <summary> /// Retorna os símbolos de todas as ações disponíveis. /// </summary> /// <returns>As ações disponíveis.</returns> public string[] getStockSymbols() { }

public override object InitializeLifetimeService() { } }}

Page 31: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

StockExchangeImpl

namespace StockSeller { public class StockExchangeImpl : MarshalByRefObject, StockExchange {

public StockExchangeImpl(StockSellerContext context) { _context = context; }

/// <summary> /// Realiza a compra de uma ação. Quando uma ação é negociada, seu valor /// aumenta em uma taxa de 10%. /// /// Usa os componentes ExchangePrinter que estejam /// conectados para imprimir a negociaçao efetuada. /// </summary> /// <param name="symbol">Símbolo da ação a ser comprada.</param> /// <returns>True se a venda da ação foi bem sucedida, False caso contrário. /// </returns> public bool buyStock(string symbol) { }

public override object InitializeLifetimeService() { } }}

Page 32: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

DisplayExchangePrinter

namespace StockLogger {

public class DisplayExchangePrinter : MarshalByRefObject, ExchangePrinter {

public DisplayExchangePrinter(ComponentContext context) { }

/// <summary> /// Imprime que houve uma negociação da ação indicada. /// A saída utilizada para impressão é a tela. /// </summary> /// <param name="text">Texto a ser impresso na tela.</param> public void print(string text) { }

public override object InitializeLifetimeService() { } }}

Page 33: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Passo 3: Criando o componente StockSeller

• O componente StockSeller oferece as facetas StockServer e StockExchange

• O componente StockSeller possui um receptáculo para conectar um ou mais compontes que implementem a faceta ExchangePrinter

Page 34: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Inicia o ORB

• A inicialização do ORB, ao iniciar o servidor, é igual à que já usamos nos exemplos anteriores.

• O servidor deve, após criar o componente, deixar ao menos uma thread ativa para que o ORB possa ficar aguardando as requisições

// inicializa o ORB, indicando que utilize uma porta aleatória para // receber chamadasIiopChannel chan = new IiopChannel(0);ChannelServices.RegisterChannel(chan, false);

...Thread.Sleep(Timeout.Infinite);

Page 35: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Criando o identificador do componente

• Todo componente precisa ter um identificador, que é descrito usando a classe ComponentId

ComponentId componentId = new ComponentId( "StockSeller", 1, 0, 0, “.NET 4.0");

Page 36: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Criando o componente

• A classe DefaultComponentContext deve ser instanciada para servir como representação local do componente (ou uma classe mais específica definida pelo usuário)

• Esse componente já conterá as facetas básicas do SCS

ComponentContext context = new DefaultComponentContext(componentId);

Page 37: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Criando e adicionando as facetas

// cria as facetasStockServerImpl stockServer = new StockServerImpl(context);StockExchangeImpl stockExchange = new StockExchangeImpl(context);

// adiciona as facetas ao componentestring serverType = Repository.GetRepositoryID(typeof (StockServer));string exchangeType = Repository.GetRepositoryID(typeof (StockExchange));context.AddFacet("StockServer", serverType, stockServer);context.AddFacet("StockExchange", exchangeType, stockExchange);

Page 38: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Adicionando receptáculos

// adiciona o receptáculostring printerType = Repository.GetRepositoryID(typeof (ExchangePrinter));context.AddReceptacle("ExchangePrinter", printerType, true);

Page 39: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Salva o IOR em um arquivo

• Nessa solução, ainda usaremos um arquivo para gravar a referência para o objeto CORBA

• Note que estamos usando a referência para um IComponent

OrbServices orb = OrbServices.GetSingleton();string ior = orb.object_to_string(context.GetIComponent());File.WriteAllText(args[0], ior);

Page 40: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Passo 4: Criando o componente StockLogger

• O componente StockLogger oferece a faceta ExchangePrinter

• O código StockLoggerMain.cs é responsável por criar o componente SCS StockLogger

• Em nosso exemplo, o código que o conecta ao componente StockSeller é uma aplicação separada

• A criação do componente StockLogger é similar ao que fizemos para criar o StockSeller, exceto que não há receptáculos

Page 41: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Passo 5: Recuperando as referências dos componentes para conectá-los

• A conexão pode ser feita por um dos componentes do sistema ou por um cliente externo

// Lê os IORs dos arquivos cujos nomes são passados como parâmetrosstring sellerIOR = File.ReadAllText(args[0]);string loggerIOR = File.ReadAllText(args[1]);

Page 42: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Obtendo as facetas IReceptacles do StockSeller e ExchangePrinter do StockLogger

• Precisaremos da faceta ExchangePrinter do componente StockLogger, pois é essa faceta que será conectada ao receptáculo do StockSeller

• A faceta IComponent tem métodos para recuperar suas outras facetas

ORB orb = OrbServices.GetSingleton();// Obtém as referências para os objetos CORBAIComponent sellerIC = orb.string_to_object(sellerIOR) as IComponent;if (sellerIC == null) {...}IComponent loggerIC = orb.string_to_object(loggerIOR) as IComponent;if (loggerIC == null) {...}

string receptaclesType = Repository.GetRepositoryID(typeof (IReceptacles));IReceptacles irStockSeller = sellerIC.getFacet(receptaclesType) as IReceptacles;if (irStockSeller == null) {...}string printerType = Repository.GetRepositoryID(typeof (ExchangePrinter));ExchangePrinter printer = loggerIC.getFacet(printerType) as ExchangePrinter;if (printer == null) {...}

Page 43: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Conectando a faceta ExchangePrinter do StockLogger no receptáculo do StockSeller

• Usamos a faceta IReceptacles de StockSeller para fazer a conexão dos componentes

• O método connect faz a conexão do componente StockLogger usando sua faceta ExchangePrinter

• O exemplo não mostra para simplificar, mas deve-se tratar as exceções CORBA como no exercício anterior em toda chamada remota CORBA, assim como exceções específicas do método

// Faz a conexão da faceta ExchangePrinter do componente StockLogger no// receptáculo do StockSeller

irStockSeller.connect("ExchangePrinter", printer);

Page 44: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Passo 6: Usando os componentes conectados ao receptáculo do StockSeller

• A implementação do método buyStock pela faceta StockExchange do componente StockSeller deve chamar o método print da faceta ExchangePrinter conectada a esse mesmo componente

Page 45: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Obtendo o receptáculo correspondente a ExchangePrinter

• O contexto do componente possui o método GetReceptacleByName que retorna um receptáculo

• A classe Receptacle permite então recuperar as descrições das conexões

• As descrições das conexões são recuperadas com o método GetConnections de Receptacle

• O campo objref de ConnectionDescription possui a referência para a faceta IComponent da dependência conectada

public bool buyStock(string symbol) { ... IList<ConnectionDescription> conns = _context.GetReceptacleByName( "ExchangePrinter").GetConnections(); foreach (ConnectionDescription conn in conns) {

try { ((ExchangePrinter)conn.objref).print( "Negociação da ação " + symbol + ". Novo valor: " + value);

}catch(...) {...}

} ...}

Page 46: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Passo 7: Usando o componente StockSeller

• O cliente usa o componente StockSeller através de suas facetas

• O StockMarketClient.cs possui a etapa de inicialização do ORB que já vimos nos exemplos anteriores

• O que muda é o uso das facetas do componente para invocar os métodos remotos

Page 47: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Obtendo a referência para o componente StockSeller

• O cliente recupera a referência para o componente StockSeller lendo do arquivo recebido por parâmetro

// Lê o IOR do arquivo cujo nome é passado como parâmetrostring ior = File.ReadAllText(args[0]);ORB orb = OrbServices.GetSingleton();// Obtém a referência para o objeto CORBAIComponent sellerIC = orb.string_to_object(ior) as IComponent;if (sellerIC == null) {…}

Page 48: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Obtendo as facetas StockServer e StockExchange do componente StockSeller

• Tendo o componente, as facetas StockServer e StockExchange são recuperadas, pelo nome ou pela interface

try { string serverType = Repository.GetRepositoryID(typeof(StockServer)); string exchangeType = Repository.GetRepositoryID(typeof(StockExchange)); StockServer server = sellerIC.getFacet(serverType) as StockServer; if (server == null) {...} StockExchange exchange = sellerIC.getFacet(exchangeType) as StockExchange; if (exchange == null) {...}}catch (…) {

…}

Page 49: Versão 1 - julho/2013 Tecgraf PUC-Rio Novembro de 2013 API C# do SCS.

versão 1 - julho/2013

Invocando os métodos disponibilizados em cada faceta

• O cliente faz as chamadas aos métodos usando as respectivas facetas

try { // Obtém os símbolos de todas as ações string[] symbols = server.getStockSymbols(); // Mostra as ações com seus respectivos valores foreach (string symbol in symbols) { Console.WriteLine(symbol + " " + server.getStockValue(symbol)); } // Compra uma ação if (symbols.Length > 0) { String first = symbols[0]; Console.WriteLine("--Compra a ação :" + first); bool success = exchange.buyStock(first); if (success) { Console.WriteLine("--Ação " + first + " depois da negociação: " + server.getStockValue(first)); } else { Console.WriteLine("--Não foi possivel negociar a ação " + first); } }} catch (…) {…}