Mapeamento de IDL para C# Tecgraf PUC-Rio Novembro de 2013 versão 1 - julho/2013 Mapeamento de interface • O IIOP.NET não implementa o padrão CORBA completamente e conta com algumas diferenças, mas é compatível com outros ORBs • Em C#, uma interface IDL é mapeada para uma interface com o mesmo nome da interface IDL e é usada como o tipo referenciado pelos usuários • A implementação de um servant deve implementar essa interface e estender a classe abstrata MarshalByRefObject • A classe MarshalByRefObject é o mapeamento de uma referência remota em C#, e é utilizada pelo IIOP.NET para representar objetos CORBA versão 1 - julho/2013 Mapeamento de interface • Atributos definidos na interface são mapeados para um par de métodos get e set (Properties) • Atributos readonly são mapeados apenas para métodos get (Properties) • Parâmetros in são mapeados para parâmetros conforme o tipo correspondente • Parâmetros out são mapeados para parâmetros out do tipo correspondente • Parâmetros inout são mapeados para parâmetros ref do tipo correspondente versão 1 - julho/2013 Mapeamento de interface // IDL module exemplo { struct Pessoa { string nome; long idade; }; interface CadastroPessoa { attribute string empresa; void incluiPessoa (in Pessoa p); void alteraPessoa (inout Pessoa p); }; }; // C# public interface CadastroPessoa : IIdlEntity { string empresa { get; set; } void incluiPessoa(Pessoa p); void alteraPessoa(ref Pessoa p); } versão 1 - julho/2013 Mapeamento dos tipos primitivos versão 1 - julho/2013 Mapeamento dos tipos primitivos • Observações – Tipos unsigned em IDL são mapeados para tipos signed em CLS – Não existe representação para fixed nem long double versão 1 - julho/2013 Mapeamento de struct • Um struct IDL é mapeado para um struct C# que possui uma variável para cada campo • A classe possui o mesmo nome do struct IDL versão 1 - julho/2013 Mapeamento de struct // IDL struct StructType { long field1; string field2; }; // C# public struct StructType : IIdlEntity { // instance variables public int field1; public string field2; // constructors public StructType(int f1, String f2){ field1 = f1; field2 = f2; } } versão 1 - julho/2013 Mapeamento de sequence • Um sequence IDL é mapeado para um array CLS uni-dimensional com o mesmo nome versão 1 - julho/2013 Mapeamento de array • Ainda não há mapeamento para arrays no IIOP.NET versão 1 - julho/2013 Mapeamento de typedef • O IIOP.NET não possui uma construção para typedef • O tipo original é usado versão 1 - julho/2013 Mapeamento de enum • O enum IDL é mapeado para um enum CLS com o mesmo nome • O tipo Int32 é usado para representar cada valor da enumeração versão 1 - julho/2013 Mapeamento de enum // IDL enum TrafficLight { red, yellow, green }; // C# enum TrafficLight {red, yellow, green}; versão 1 - julho/2013 Mapeamento de union • O union IDL é mapeado para uma classe com o mesmo nome, que possui os métodos: • de acesso ao valor determinante • de acesso e modificação para cada possível valor das opções definidas no tipo e para o valor default versão 1 - julho/2013 Mapeamento de valuetype • O valuetype IDL é mapeado para uma classe abstrata com o mesmo nome • É responsabilidade do desenvolvedor criar a classe que implenta essa classe abstrata, garantindo a correta recomposição do estado do objeto no processo de unmarshal • O IIOP.NET convenciona que a classe com a implementação do valuetype deve ter o mesmo nome, seguido do sufixo Impl • Além disso, deve ser marcada como serializable e ter um construtor sem parâmetros versão 1 - julho/2013 Mapeamento de valuetype // IDL valuetype Node { public long id; public Node next; }; // C# [ImplClass("exemplo.NodeImpl")] [RepositoryID("IDL:exemplo/Node:1.0")] [Serializable] public abstract class Node : IIdlEntity { public int id; public Node _next; } versão 1 - julho/2013 Mapeamento de valuetype • O desenvolvedor deve criar a classe que implementa a classe abstrata gerada a partir do valuetype [Serializable] public class NodeImpl : Node { public NodeImpl() { } } versão 1 - julho/2013 Mapeamento de valuetype • Quando entregar somente implementações de ValueTypes em uma DLL, caso o programa não referencie nenhum tipo da DLL, a mesma não será carregada • Lembre-se então de carregá-la com Assembly.Load(“<nome-da-dll>”) versão 1 - julho/2013 Mapeamento de ANY • O tipo any usado na IDL é mapeado para a classe C# System.Object – Quando um método receber um any, pode-se passar qualquer objeto e o IIOP.NET se encarregará da conversão – Quando um any for recebido, basta ser convertido para o tipo esperado • Alternativamente pode-se utilizar a opção –mapAnyToCont para o compilador de IDL, e assim o tipo IDL any passará a ser convertido em um container org.omg.CORBA.Any versão 1 - julho/2013 Mapeamento de ANY // IDL CORBA::ULong ExtractFromULongAny(const CORBA::Any& arg); // C# OrbServices orb = OrbServices.GetSingleton(); int arg2 = 89; omg.org.CORBA.TypeCode ulongTC = orb.create_ulong_tc(); Any any = new Any(arg2, ulongTC); int result2 = m_testService.ExtractFromULongAny(any); • Exemplo onde é necessário enviar um unsigned long em um any • Utiliza-se o container org.omg.CORBA.Any para forçar o marshaller a usar o tipo diferente, já que o int C# é signed versão 1 - julho/2013 Mapeamento de ANY // C# OrbServices orb = OrbServices.GetSingleton(); TypeCode wstringTC = orb.create_wstring_tc(0); Any any = new Any("myString", wstringTC); myObject.Test(any); • A FAQ do IIOP.NET menciona um problema do JacORB (não especifica qual versão) para receber Any’s com typecode 30 (valor de tipo encapsulado) • Isso geralmente ocorre quando uma string .NET é convertida em um Any. • O código acima mostra como evitar esse problema versão 1 - julho/2013 Módulos • Um módulo IDL é mapeado para um namespace C# com o mesmo nome // IDL module tecgraf { // namespace C# namespace tecgraf.openbus.DRMAA {} module openbus { module DRMAA { ... } versão 1 - julho/2013 Conflitos de nomes • Em geral, os nomes usados na IDL são mapeados diretamente para os mesmos nomes em C# • Conflitos de nomes no mapeamento são resolvidos usando um prefixo _ no nome em C# versão 1 - julho/2013