Skip Navigation Links



Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de UsuĆ”rios
»CĆ©lulas AcadĆŖmicas«

Morcegando
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
FaƧa um pequeno teste com 10 questƵes de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programaĆ§Ć£o com nosso treinamento on-line de lĆ³gica de programaĆ§Ć£o
.:.
Veja nosso calendƔrio de treinamentos
Gostou da PƔgina?
Então

para um amigo!

Pesquisa personalizada
Pesquisar Dicas:

 






Quer saber mais?
Não deixe escapar essa oportunidade!
A Búfalo Informática tem os cursos certos para você:
::Treinamento para Asp.Net::
::Treinamento para VB.Net ::

Juntando o .NET ao COM+ : System.EnterpriseServices

Muita coisa mudou na arquitetura de componentes no Visual Studio .NET . Em primeiro lugar é importante relembrarmos rapidamente a arquitetura de componentes que utilizamos no VB 6.

O formato dos componente que criamos é chamado de COM. O padrão COM define como os components são moldados internamente e permite que qualquer linguagem compatível com o padrão COM utilize um componente COM.

Já o DCOM, abreviação de distributed COM, é um protocolo de rede que permite que um componente COM seja chamado remotamente pela rede.

A partir do momento que temos componentes centralizados em um servidor sendo chamados por um número indeterminado de clients precisamos ter um gerenciamento eficiente de recursos em RAM.
Estes componentes precisam compartilhar recursos, tal como conexões com o banco, além de poderem ter suas instâncias reaproveitadas entre a chamada de um client e outro.

O MTS foi o servidor responsável por todo esse gerenciamento na época do Windows NT. Ao surgir o Windows 2000 a dobradinha COM/MTS mudou de nome, passando a chamar-se COM+ .

No .NET o formato de componentes utilizado mudou muito, passou a se chamar CLS e traz diversas vantagens sobre o formato dos componentes COM.

Ao contrário dos componentes COM, porém, os componentes CLS não estão diretamente em código de máquina mas sim em um código intermediário, IL, que precisa ser executado por outro software, o
CLR. Assim sendo todos os componentes CLS rodam dentro de um ambiente controlado, o CLR.

Mas o CLR apenas controla a execução do código IL, não se encarrega de questões de escalabilidade importantes para um servidor de aplicações. De fato, não existe um servidor de aplicações exclusivo para componentes CLS. Mas o .NET possui um namespace chamado EnterpriseServices que permite que os serviços do COM+ sejam utilizados pelos componentes CLS.

Assim sendo, podemos construir nossos componentes no novo formato, o CLS, e inseri-los dentro do velho COM+ exatamente como temos feito com nossos componentes COM.

Vamos ver, passo a passo, como construirmos um componente CLS e inseri-lo no COM+ e como utiliza-lo tanto por uma aplicação .NET como por uma aplicação no VB 6.

Dentro do VS.NET devemos solicitar a criação de um novo projeto e escolhermos uma nova Class Library. Em nosso exemplo utilizaremos uma Class Library do VB.NET. Não esqueça de determinar o caminho em que o projeto ficará gravado (será mais fácil se for um diretório simples, próximo a raiz).

Defina o nome do projeto como sendo MC (abreviação de MinhaClasse ;-) . Vamos alterar o nome da classe, que inicialmente aparece como Class1 para MinhaClasse.

Precisamos então indicar ao VB que nossa classe fará uso do namespace System.EnterpriseServices.
Um namespace guarda algumas semelhanças com as bibliotecas de componentes : Para utiliza-lo é necessário adicionar uma referencia utilizando Project->Add Reference

Mas a referencia não basta. Para que as constantes e objetos contidos dentro do System.EnterpriseServices possam ser compreendidas dentro de nossa aplicação sem que tenhamos que digitar seu nome completo (ex. System.EnterpriseServices.objeto) é necessário importarmos os nomes de objetos e cia. que existem dentro deste namespace, declarando no inicio do código que faremos uso dele através da instrução Imports.

Imports System.EnterpriseServices
Imports System.EnterpriseServices.ObjectPoolingAttribute
Imports System.Runtime.InteropServices

Na utilização tradicional do COM+ normalmente criavamos nossos componentes e os configurávamos dentro do package do COM+. No .NET isso não acontece. Os parâmetros de configuração do COM+ são inseridos dentro do código do componente e o próprio .NET se encarrega de criar o pacote com a configuração determinada para o componente.

Desta forma no inicio da classe precisaremos inserir as configurações referentes ao COM+, veja :

<ProgIdAttribute("MinhaClasse"), _
JustInTimeActivation(), _
ObjectPooling(MinPoolSize:=5, MaxPoolSize:=5, Enabled:=True), _
ClassInterface(ClassInterfaceType.AutoDual)> _
Public Class MinhaClasse

End Class

Com isso estamos determinando o ProgId de nossa classe (o nome da classe), ativando a Just In Time Activation, definindo o Pooling de objetos e determinando que tipo de interface COM a nossa classe terá quando for compilada (Iunknow, IDispatch ou Dual).

A nossa classe precisa herdar as características de um objeto chamado ServicedComponent para que desta forma possa ser inserida no COM+. Para definirmos a herança devemos utilizar a instrução "InHerits"

Public Class MinhaClasse
Inherits ServicedComponent
...
End Class


O próximo passo é programarmos nossa classe. Vamos criar um método (função) chamado calcular que receba um número e multiplique por dois, algo bem simples.

Public Function Calcular(ByVal v As Int32) As Int32
Calcular = v * 2
End Function

Assim como nos componentes COM tradicionais, precisamos chamar setcomplete/setabort ao término do método. Podemos fazer isso de duas formas : Explicitamente ou fazendo um setcomplete implicito.

Para fazer um setcomplete implicito basta marcar o método com uma característica que é chamada de autocomplete. Veja :

<AutoComplete>Public Function Calcular(ByVal v As Int32) As Int32
Calcular = v * 2
End Function

Neste exemplo ao término do método está automaticamente sendo feito um setcomplete. Cômodo, mas não suficiente : e se você desejasse fazer um setabort ?

Para realizar explicitamente o setcomplete ou o setabort é necessário utilizar um objeto chamado ContextUtil (System.EnterpriseServices.ContextUtil). Veja como fica :


Public Function Calcular(ByVal v As Int32) As Int32
Calcular = v * 2
ContextUtil.SetComplete
End Function


Feito isso devemos especificar algumas características de compilação para a nossa classe. Essas características determinarão a configuração do package no COM+ que, sim, será criado automaticamente pelo .NET

No Project Explorer temos acesso ao AssemblyInfo.VB, que guarda informações para a compilação de nosso componente (lembrando que ele não se transforma em código de máquina mas sim em código IL).
Neste arquivo devemos inserir os seguintes parâmetros :

<Assembly: ApplicationActivation(ActivationOption.Library)>
<Assembly: ApplicationName("NetComponent")>

O Imports para o System.EnterpriseServices também deverá ser adicionado no inicio do arquivo AssemblyInfo.

Os dois parâmetros acima estão realizando a configuração do package no COM+ : Será criado um package chamado NetComponent dentro do COM+ e este será um Library Package.

Para que o assembly (DLL) de nosso componente possa ser inserido no COM+ é necessário que possua uma assinatura, essa assinatura o tornará único perante outros componentes.

Para criarmos esta assinatura precisamos utilizar um utilitário chamado SN.EXE com a chave -k . Isso irá gerar um arquivo SNK para o qual precisaremos apontar no arquivo AssemblyInfo através da seguinte instrução :


<Assembly: AssemblyKeyFile("c:\vbnet\artigo\mykey.snk")>

O caminho, claro, é apenas um exemplo que utilizei em meu micro.

Para gerarmos o arquivo mykey.snk devemos entrar em uma janela DOS, acessarmos o diretório onde gravamos a aplicação e utilizarmos a seguinte instrução :

SN -k mykey.snk

O arquivo SN assim como outros utilitários encontram-se divididos em 2 caminhos :

winnt\microsoft.NET\Framework\v1.0.2914

e

program files\microsoft.net\frameworkSDK\bin

Você deve encontra-los em seu micro e acrescenta-los ao path para facilitar seu trabalho. Feito isso podemos fazer o Build (menu Build->Build) e o assembly (DLL) de nosso componente será gerado.

Não podemos inserir esse componente diretamente no COM+. Devemos utilizar a aplicação RegSvcS para realizar o registro deste componente. Esta aplicação automaticamente fará a criação do package do COM+ para o componente, seguindo os parâmetros de configuração que informamos.

Entrando em uma janela DOS, encontraremos nossa DLL (MC.DLL) no diretório BIN imediatamente abaixo do diretório MC criado quando nós iniciamos o projeto. Podemos então utilizar RegSvcs MC.DLL

A partir deste ponto podemos entrar no COM+ e já encontraremos nosso package. Você lembra o nome ? Sim, NetComponent, o nome que definimos no Assembly.


O fato de termos definido nossa interface como Dual fez com que fosse criada uma interface padrão dentro do componente, interface essa cujo nome inicia-se com "_" e tem o mesmo nome da classe ("minhaclasse"). Dentro desta interface padrão está o nosso método ("Calcular") e todos os demais métodos das demais interfaces que nossa classe possui. A interface Dual no padrão COM gera algum ganho no momento do acesso ao componente porém no caso do .NET expõem métodos demais para cada componente.

Podemos experimentar os demais tipos de interface. Podemos desregistrar nosso componente com a seguinte instrução :

RegSvcs -u MC.DLL

E em seguida alterarmos o tipo de interface para AutoDispatch, recompilando e registrando novamente o componente.

Ao contrário da Dual uma interface padrão não é automaticamente gerada, portanto nosso método calcular some pois não pertence a nehuma das interfaces de nosso componente que estão definidas.

Assim sendo, no caso do AutoDispatch o nosso método não aparece, no caso do Dual aparece, mas em conjunto com diversos outros métodos. A solução para isso é criarmos uma interface personalizada
para o nosso componente. Assim sendo nossos métodos passam a fazer parte desta interface personalizada.

Veja como fica o código completo :

Imports System.EnterpriseServices
Imports System.EnterpriseServices.ObjectPoolingAttribute
Imports System.Runtime.InteropServices

<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)> _
Public Interface Imyinterface
Function Calcular(ByVal v As Int32) As Int32
End Interface

<ProgIdAttribute("MinhaClasse"), _
JustInTimeActivation(), _
ObjectPooling(MinPoolSize:=5, MaxPoolSize:=5, Enabled:=True), _
ClassInterface(ClassInterfaceType.AutoDispatch)> _
Public Class MinhaClasse
Inherits ServicedComponent
Implements Imyinterface


Public Function Calcular(ByVal v As Integer) As Integer Implements MC.Imyinterface.Calcular
Calcular = v * 2
End Function
End Class

Na interface definimos apenas a estrutura da função Calcular. Utilizamos na classe a instrução Implements para indicar que iremos implementar a interface. Ao fazermos isso o VB.NET nos obriga a implementar todos os métodos que a interface possui.

No todo da janela de código, nas combos de objeto e método podemos selecionar a nossa interface e o vb.net já nos abre a estrutura desta função calcular para implementarmos. Observe que o truque da síntaxe desta função é o Implements no final indicando que ela se refere a um método da interface que dissemos que iríamos implementar.

Ao realizarmos a instalação desta aplicação no COM+ observaremos que a nossa interface aparecerá na lista de interfaces da classe. Se entrarmos nas propriedades de nosso componente, porém, observaremos que seu caminho físico aponta para um arquivo chamado mscore.dll . Nosso componente não pode rodar fora do CLR, o que temos no COM+ na verdade é como uma pequena "casca" que expõem nosso componente CLS para o mundo COM e faz o interfaceamento entre o mundo COM e o mundo CLR.

Podemos a partir de então acessar nosso componente a partir de qualquer aplicação VB. Para isso basta utilizarmos o References para o componente (para acessarmos via early binding, mas o acesso também poderia ser feito via late binding) e utilizarmos o código a seguir :

Private Sub Command1_Click()
Dim x As Imyinterface

Set x = New MinhaClasse
MsgBox x.Calcular(20)
Set x = Nothing

End Sub


Observe que a variável foi definida como sendo do tipo da interface e, posteriormente, recebeu uma nova instância da "MinhaClasse", que contém a "ImyInterface".

Claro que, sem definirmos a interface no componente, poderíamos instanciar o componente com como qualquer outro componente. Mas os métodos herdados de outras classes seriam visíveis, como vimos um pouco antes pelo COM+ . Fazendo desta forma, com a criação de uma interface e sua utilização no código, apenas nossos métodos ficam visíveis no objeto (x, no exemplo).

Uma observação interessante é que a ativação do package ocorre de forma consideravelmente mais rápida em comparação com componentes criados em VB. Observando-se as propriedades do componente no COM+, em "Concurrency" observamos o threading-model "Any Apartment", equivalente ao "Free Threaded" que pode ser criado em C++. O VB 6 apenas utiliza o Threading model apartment e não o Free Threaded, desta forma o uso de componentes CLS dentro do COM+, apesar da "casca COM" necessária a seu uso acaba ganhando em performance/escalabilidade dos componentes COM criados pelo VB 6.


No VB.NET o nosso componente pode ser utilizado da mesma forma como chamaríamos qualquer componente CLS, bastando fazer o references e utilizar o seguinte código de exemplo :

Imports MC

Public Class Form1
Inherits System.Windows.Forms.Form

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim x As Imyinterface

x = New MinhaClasse()
MsgBox(x.Calcular(10))
x = Nothing
End Sub
End Class

É necessário o references tanto para o MC como para o System.EnterpriseServices para que o código acima funcione.

Desta forma concluimos que apesar de ter um modelo de componentes totalmente novo o .NET ainda precisa do COM+ como servidor de aplicações e continuará utilizando-o durante algum tempo. Além disso a facilidade de utilizar componentes CLS no COM+ e acessá-los a partir de aplicações legadas (ASP/VB6) tornará fácil a migração de aplicações atuais.


Dennes Torres
MCSD,MCSE,MCDBA





Envie seus comentįrios sobre este artigo

Nome :

E-mail :

Comentários :


Avise-me quando houverem novos comentįrios nesta pįgina

Veja abaixo os comentários já enviados :

Nome : Fabio Maia E-Mail : fabio@tagsystem.com.br
Ola,
Achei a matéria muito interessante e estava procurando a algum tempo esse exemplo. Mas deu um probleminha:

Gerei a DLL sem problemas, publiquei e quando fui adicioná-lo ao projeto
"Add Reference" ocorreu o seguinte erro:

A reference do 'MC' could not be added. Converting the type libery to a .NET Assembly failed. Type libery MC was exported from a CLR Assembly and can not be re-imported as a CLR assembly.

Vcs podem me ajudar?
Sera que posse gerar um COM que chame um PrintDialog dentro de uma pagina ASP.net?

Obrigado

Fabio
Nome : Daniel E-Mail : dferreira2002@hotmail.com
Segui o exemplo postado e ao adicionar o componente com referência a um novo projeto vb.Net deu o erro:

A reference do 'MC' could not be added. Converting the type libery to a .NET Assembly failed. Type libery MC was exported from a CLR Assembly and can not be re-imported as a CLR assembly.

Há alguma solução para isso?
Nome : Paulo Ribeiro E-Mail : prribeiro@iol.pt
Boas,
é um bom exemplo, mas eu quero instalar a aplicação no COM+ de um servidor, 'A' e aceder a ele de um outro computador B.

Help please,

Paulo
Nome : Dennes E-Mail : dennes@bufaloinfo.com.br

Quanto ao uso em máquinas remotas, o próprio COM+ tem o recurso de exportação do pacote.

Quanto ao References, esse erro ocorre porque você não deve usar a aba COM para fazer references e sim a aba .NET

[]'s

Dennes
Nome : Dalmo E-Mail : djdmix2@hotmail.com
Desculpe usar este espasso + ja n sei o k fazer +....
toda vez k eu passo a ferramenta d correção do norton ele aponta 3 erros k nao ha como corrigir, fala uma dll(mscore.dll), ja formatei o computador varias vezes e esse erro sempre ocorre, agora instalei o programa sound forge 8.0 e quando entro no programa tb da erro e diz k falta essa mesma dll, tem alguma forma d corrigir? Ha como eu baixar essa dll?
Se puderem me ajudar agradadesso desde ja..
Obrigado

Dalmo Citrangulo Sindra
Nome : Dalmo E-Mail :
Ha ja ia me eskecendu... uso windows XP profissional
Nome : Renan Mattos E-Mail : renanmattos@hotmail.com
PRezado Dennes, li o seu artigo. E gostaria de saber se poderia me ajudar em um problema que tenho com com+. Foi desenvolvido umas DLL em vb6 e roda bem no windows 2000. Entretanto quando instalo no XP ou 2003 não funciona. Existe alguma configuração diferente que tenha que ser feita no XP ou 2003. Li que no xp ou 2003 é restritivo.

cordialmente,
Renan Mattos.
Nome : Allard E-Mail : Allard@procergs.rs.gov.br
Oi dennis
muito bom teu artigo.

Fiz o componente e deu erro
A reference do 'MC' could not be added. Converting the type libery to a .NET Assembly failed. Type libery MC was exported from a CLR Assembly and can not be re-imported as a CLR assembly.

li nos comentarios a tua resposta:
"Quanto ao References, esse erro ocorre porque você não deve usar a aba COM para fazer references e sim a aba .NET"

a minha pergunta:
porque então colocar o dll no com+, se deve referenciar o dll direto, e não a referência com+? Tens ideia o que acontece se depois quer separar servidor web e vb(net), usando com+ remotamente? deve refazer as referências?

Obrigado,
allard
Nome : Bruno Amaral E-Mail : brunoonline@click21.com.br
Olá, Só pra acrescentar.

Provavelmente este código é para Framework 1.1.
No VS2005, deve-se adicionar o prefixo correspondendo o namespace.
E deve ser acrescentado esta tag. Senão é exibido um "warning", dizendo que a segurança a ser usada é a default.
<Assembly: EnterpriseServices.ApplicationAccessControl
(EnterpriseServices.AccessChecksLevelOption.ApplicationComponent)>

Bruno,
Extend Software.
Nome : daniel ferraz E-Mail : daniel_f777@itelefonica.com.br
E quanto ao acesso remoto do mesmo? Funciona igual ao COM do VB? Alguem tem algum exemplo?
Nome : Marcos Silva E-Mail : marcos.silva@e-xyon.com.br
Dennes,
Gerei um componente no c# que utiliza de um segundo componente .NET, gerrei a DLL e consegui instanciar no COMPONENTE SERVICE, funcionou, tudo OK.

O problema é que fiz tudo isto na minha máquina de desenvolvimento, quando copie a minha dll o tlb e a dll .net que é refenciada pelo meu componente para o servidor e tentei registrar no COMPONENTE SERVICE não consigo. Não apresenta erro, mas também não registra.

O que devo fazer ?
Nome : Bruno Melo E-Mail : brunomelodf@gmail.com
Excelente artigo! Completo e detalhado. Muito bom.
Obrigado.
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 5GQP6wOf E-Mail : box8s8ka@hotmail.com
28power68:Seriously, what's the cause for so many stupid caerhss in russia, all of? them are just a bunch of idiots, they drive drunk, or it's just that they suck at driving?At least the idiots will die
Nome : UxAw33UQQ E-Mail : 38494l69@mail.com
&quot;up with which I will not putovu&t;I&#39;qe always loved that locution. It was presented to us in linguistics class as an example of why the so-called &quot;rule&quot; disallowing prepositions at the ends of sentences is false. &quot;Put up with&quot; is an example of a petrified expression, i.e., a locution the word order of which can&#39;t be changed. Pardon the pedantry-- it&#39;s not aimed at you, since you&#39;re obviously in on the joke. I&#39;m mentioning all this for the benefit of readers who still labor under the delusion that one should never end a sentence with a preposition.Oh, and... congrats on spotting the dangler. Join me now as we cast stones at Ms. Freed.

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Conheça mais sobre o nosso site :

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



Quer saber mais?
Faça um curso na Búfalo Informática, Treinamento e Consultoria e
Prepare-se para o Mercado!
Veja o que a Búfalo tem para você.

ļæ½ BĆŗfalo InformĆ”tica, Treinamento e Consultoria - Rua Ɓlvaro Alvim, 37 Sala 920 - CinelĆ¢ndia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail:
contato@bufaloinfo.com.br