Mostrando postagens com marcador C#. Mostrar todas as postagens
Mostrando postagens com marcador C#. Mostrar todas as postagens

quinta-feira, 30 de dezembro de 2010

Sabe o que é modificador internal? Sabe mesmo???

Pois é, o post começa com algo bem básico do C#, coisa do primeiro dia de aula mesmo: Modificadores de Acesso. Só pra relembrar:

  • public : Sem restrição de acesso.
  • protected : Acessado pela classe que o define e pelas classes derivadas dela.
  • internal : Acessado apenas de dentro do mesmo assembly.
  • private : Acessado somente de dentro da classe (mesmo se forem instancias diferentes).

Isso todo mundo já sabe (ou deveriam saber). O ponto em que quero chegar é que, dizer que "membros ou tipos internal só podem ser acessados dentro do mesmo assembly" não é uma completa verdade.

InternalsVisibleToAttribute

O atributo InternalsVisibleTo introduz ao assembly o conceito de Friend Assembly. Com isto os membros ou tipos marcados com o modificador de acesso internal podem ser acessados de outro assembly. Vamos ver como funciona:

Nesta solução podemos ver que existem 3 Projetoprojetos, sendo 2 projetos do tipo ClassLibrary e 1 ConsoleApplication.

Adicionamos o projeto AssemblyA como referencia no projeto MyConsoleApplication. Depois o projeto AssemblyB como referencia no projeto AssemblyA e MyConsoleApplication.

Ele ficará como a imagem ao lado. Podemos ver que existem algumas classes já declaradas.

No AssemblyB temos uma classe com modificador de acesso internal e outra com o modificador de acesso public (Como dizem os nomes).

Agora vamos tentar instanciar a classe AssemblyB.MyInternalClass de dentro da cBuild Faillasse AssemblyA.MyPublicUtilClass e compilar a aplicação para ver o que acontece.

O Visual Studio não deixa compilar a aplicação. Ele nos mostra o motivo do build failed em duas mensagens de erro:

  1. O tipo AssemblyB.MyInternalClass não tem construtor definido.
  2. O tipo AssemblyB.MyInternalClass não é acessível devido ao seu nível de proteção.

Como a classe está definida com o seu modificador de acesso sendo internal o Visual Studio segue a regra que descrevemos mais acima e não deixa ela ser acessada (no caso instanciada).

Esses mesmos dois erros ocorreriam se tivéssemos tentado o acesso a esta classe no assembly MyConsoleApplication.

Nesse momento entra em ação o atributo InternalsVisibleTo que faz uma alteração a nível de assembly fazendo com que AssemblyA possa instanciar a classe em questão.

Segue o trecho que pode ser colocado em qualquer arquivo de código mas que por boas práticas deve ser colocado no arquivo AssemblyInfo da pasta Properties do projeto.

AssemblyInfo

Com isto compilamos novamente a aplicação e podemos ver que agora temos acesso a classe MyInternalClass de dentro do assembly AssemblyA.

Também podemos verificar que apesar do acesso a classe MyConsoleApplicationMyInternalClass ter sido alterado em relação ao assembly AssemblyA, o assembly MyConsoleApplication ainda continua ser ter acesso. Se fosse necessário que o assembly MyConsoleApplication pudesse acessar também a classe MyInternalClass bastaria colocar mais um atributo (permite múltiplos) no AssemblyInfo especificando isto.

Considerações Importantes

Não são muitos os casos onde é aconselhada esta prática. Ela é exigida em casos onde a organização do projetoSistem.Workflow.Activities a exige:

  • Casos onde existe um projeto de teste e é necessário o acesso a membros internal para o teste.
  • Quando se desenvolve um ClassLibrary que é composto por vários assemblies mas requerem acesso a membros existentes entre eles. Este é o caso do assembly System.Workflow.Activities.

O exemplo que implementei foi o de mais fácil compreensão. Existem algumas regras que devem ser seguidas para a utilização desde atributo. A regra mais importante é a respeito dos Strong Names:

  • Se o assembly que se quer ter os membros internal visíveis tiver um strong name o assembly que o consumirá também deverá ter. No atributo InternalsVisibleTo deverá constar, separados por vírgula, o nome do assembly mais a public key dentro da string que é passada ao construtor.
  • Se o assembly que se quer ter os membros internal visíveis não tiver um strong name o assembly que o consumirá também não deverá ter.

Enjoy

quinta-feira, 1 de outubro de 2009

Acessando propriedades da MasterPage

Sei, não é nenhuma mágica acessar dados da MasterPage através de um WebContentForm (página de dentro da MasterPage) e todo mundo já deve ter feito.
protected void Page_Load(object s, EventArgs e)
{
    this.Master.SkinID = "GreenSkin";
}
Mas nem tudo é tão simples. Lembrando que a propriedade Master da classe Page é apenas outra Page logo damos de cara com a necessidade de um Cast em caso de criarmos algo mais personalizado. Imaginando agora que o nome da classe da minha MasterPage é "Site" e tem uma propriedade TituloMenu que preciso acessar na minha página de conteúdo. Pra isso geralmente fazemos o seguinte:
protected void Page_Load(object s, EventArgs e)
{
    ((Site)this.Master).TituloMenu= "Home";
}
Muito bem, assim o Cast nos ajuda a acessar nossa classe de MasterPage e assim podemos acessar nossa propriedade em nossa classe derivada. Agora que vem o pulo do gato. E se não precisássemos fazer o cast? É simples, basta informar logo abaixo da diretiva @Page da página aspx qual o tipo da nossa MasterPage:
<%@ MasterType TypeName="MasterPageSample.Site" %>
Com isso nossa página passa a reconhecer a propriedade Master como sendo do tipo da nossa MasterPage, no caso Site.
protected void Page_Load(object s, EventArgs e)
{
    this.Master.TituloMenu= "Home";
}
Se clicarmos em cima da propriedade Master vamos ver o que acontece por tráz disso tudo. Quando criamos a diretiva MasterType o Visual Studio cria no arquivos auxiliar designer.cs da página uma propriedade com o mesmo nome (Master) porém escondendo a propriedade da classe base:
public new Site Master
{    
get    {return ((Site)(base.Master));}
}
Sei que não é a coisa mais impressionante do mundo mas achei interessante essa "tipagem" que o Visual Studio faz pra nós. Lembrei de publicar isto porque ví no livro de certificação e ainda hoje acabei usando em um projeto. Enjoy

quarta-feira, 22 de abril de 2009

Dynamic em C# 4.0

Sendo entregue com o Visual Studio 2010 e o Framework 4.0 o C# 4.0 promete, e muito. Dentre as novidades que estão por vir está o DLR, que possibilita linguagens dinâmicas como Iron Ruby e Iron Phyton serem compatíveis com .NET. Então estou postando aqui um vídeo que mostra como o dynamic pode nos ajudar bastante no desenvolvimento das aplicações do dia a dia. No vídeo é mostrado como interagir com XML com dynamics. Só pra se ter uma idéia um acesso como myElement.Attribute["lastName"].Value pode ser acessado apenas como myElement.lastName.

segunda-feira, 2 de fevereiro de 2009

Silverlight: Interoperabilidade

Mais um exemplo de Silverlight pode ser conferido aqui. E esse quase acertei no
Free Image Hosting at www.ImageShack.us
Design. Neste exemplo mostro como é possível interagir com a página HTML diretamente de dentro do Silverlight. Da mesma forma que podemos fazer com que o Silverlight responda a eventos disparados na página HTML.


    public HtmlElement HtmlDiv { get; set; }

    public HtmlElement HtmlButton { get; set; }

 

    public Page()

    {

      // Required to initialize variables

      InitializeComponent();

      this.HtmlDiv =

        HtmlPage.Document.GetElementById("myDiv");

 

      this.HtmlButton =

        HtmlPage.Document.GetElementById("btnId");

 

      this.HtmlButton.AttachEvent(

        "onclick",

        new EventHandler<HtmlEventArgs>(ToSilverlight_OnClick)); 

    }

Nesse caso, estou apenas escrevendo e lendo dentro do innerHTML de uma div na página através dos métodos da classe ScriptObject GetProperty e SetProperty. De dentro do Silverlight associo um evento de um botão HTML comum e digo que o Silverlight passará a responder a esse evento.

    public string DivInnerHTML

    {

      get

      {

        return this.HtmlDiv.GetProperty("innerHTML").ToString();

      }

      set

      {

        this.HtmlDiv.SetProperty("innerHTML", value);

      }

    }

Como podemos ver a forma como o Silverlight interage com a página através de código gerenciado torna a vida de nós desenvolvedores muito mais fácil.

segunda-feira, 17 de novembro de 2008

Voltando em grande estilo

Sei que passei um bom tempo sem postar. Fiquei um pouco atarefado após o casamento e a troca de emprego. Trabalhando direto com desenvolvimento em várias outras coisas surgindo ao mesmo tempo quase não parei para me dedidar ao meu blog. Mas isso não quer diser que fiquei parado no tempo. Nesse período tenho estudado sobre as novas e não tão novas tecnologias da Microsoft. Tenho usado Linq to Object com frequencia, Linq to XML também já passou pelas minhas mãos mas no momento o que mais está me fascinado é o Silverlight 2. Tenho estudado a algum tempo um pouco sobre ele e WPF, mais precisamente desde o lançamento do Release do Beta 2. Agora com o lançamento do RTW vi que era necessário entrar de vez nessa onda antes que ela passe eu eu tenha que correr atrás. Já tenho alguns exemplos de Silverlight 2 publicados no meu site e em breve pretendo disponibilizar mais junto com alguns tutoriais que pretendo colocar aqui mesmo. Até a próxima.

terça-feira, 26 de fevereiro de 2008

Extension Methods

Imagine a seguinte situação: Você tem uma aplicação que faz um cálculo qualquer. Para isso pega o valor de duas TextBox e apresenta o resultado em um Label. O que devemos ter cuidado é que C# é uma linguagem de programação de tipagem forte (strongly typed). Ao receber os dados dos TextBox você tem que primeiro converte-los para inteiros (neste caso). Aproveitando o código, validei a entrada de caracteres inválidos com o método TryParse da Classe Int32, que, em caso de falha na conversão nos retorna o valor padrão do Int32, ou seja, o “0”.

using System;

public partial class _Default : System.Web.UI.Page

{

protected void Button1_Click(object sender, EventArgs e)

{

int numero1;

int numero2;

Int32.TryParse(TextBox1.Text, out numero1);

Int32.TryParse(TextBox2.Text, out numero2);

Label1.Text = (numero1 + numero2).ToString();

}

}

No entanto, com os Extensions Methods podemos tornar nossa tarefa mais fácil. Cria uma nova classe e coloque o código como abaixo:

using System;

namespace Vitor.Canova.NET

{

public static class Extensoes

{

public static int ToInteger(this string field)

{

int valor;

Int32.TryParse(field, out valor);

return valor;

}

}

}

Pronto, nosso método vai extender a toda e qualquer string que for utilizada graças a palavra this no início da declaração dos parâmetros. Ela avisa ao compilador que aquele método pode ser usado por qualquer objeto do tipo defifido após essa palavra, no caso uma string. Agora vejamos como fica o código da página:

using System;

using Vitor.Canova.NET;

public partial class _Default : System.Web.UI.Page

{

protected void Button1_Click(object sender, EventArgs e)

{

Label1.Text = (

TextBox1.Text.ToInteger() +

TextBox2.Text.ToInteger()

).ToString();

}

}

Como podemos ver, o método pode ser invocado como se já pertencesse ao tipo string nos facilitando a conversão, sem falor no fato do Intellisense mostrar ele na lista de opções. Alguns fatos que devemos prestar atenção é o fato da classe é método de extensão serem do tipo static, o que faz com que não precisemos instanciar a classe para utiliza-la. Vale lembrar que foi adicionado o namespace da classe a página que vai utiliza-la também.

segunda-feira, 28 de janeiro de 2008

Planilha ASP.NET

Férias não tão longas quanto gostaria mas consegui relaxar um pouco. O problema é que acabei deixando o Blog um pouco de lado. Mas pra recompensar aí vai uma dica bem legal. Hoje vou ensinar um truque que aprendi lendo um post do Mauricio Junior no site www.juliobattisti.com.br. Ele ensina como modificar uma página aspx para que o Browser interprete-a como um arquivo Excel. Quando fui fazer o mesmo pela primeira vez, vi que a lógica estava principalmente no ContentType da página, que foi alterada para application/vnd.ms-excel. Bom, vamos lá é bem fácil. Crie uma página aspx normal e coloque uma tabela html com os dados que você quer no Excel, eu a chamei de Planilha. Rode o projeto. O Código e a página devem parecer como estas abaixo: Logo após crie uma página com um link para Planilha.aspx. Na diretiva Page de Planilha.aspx coloque ContentType="application/vnd.ms-excel" e certifique-se que a ViewState está desabilitada. Rode novamente o projeto e clique no link. O Browser, ao acessar a Planilha.aspx vai interpretá-la como um arquivo Excel e vai fazer o seu Download.

sexta-feira, 7 de dezembro de 2007

Intellisense sempre a espreita

Um recurso interessante que podemos contar no desenvolvimento de aplicativos, seja Web ou Desktop, é o intellisense. Clique para ver maiorPra quem não conhece pelo nome, intellisense é aquele “menu” de classes, métodos propriedades e etc que aparece enquanto você digita o código. Muita gente não sabe, mas o intellisense não aparece apenas quando digitamos algo como Me ou this. Na verdade você pode acioná-lo teclando CTRL + tecla de espaço. Ele é útil também para que não se digite nomes errados e/ou de entidades que não pertençam ao atual escopo. Um exemplo disso pode ser visto a seguir: Clique para ver maiorClique para ver maiorNa primeira imagem tento procurar uma variável que foi definida dentro do escopo do laço foreach. Na segunda imagem crio a mesma antes do laço e posso utilizá-la. Podemos ver que o intellisense enxerga melhor que nós o escopo de visibilidade das entidades. Porém, nem tudo são flores. Lembre-se que alguns objetos podem conter referências a objetos diferentes em tempo de execução. Um exemplo disso é o sender dos eventos.  Clique para ver maior Clique para ver maiorNo modo de edição aparecem apenas os métodos básicos herdados de sua classe base. Mas em tempo de execução ele tem a referência do objeto que disparou o evento e pode conter as mesmas propriedades e métodos da mesma.

sábado, 26 de maio de 2007

Escondendo aplicação .NET na área de notificação

     Todo mundo já sabe que as aplicações .NET precisam da ajuda do Framework para rodarem, assim como Java precisa da JVM. Pois bem, isso faz com que a aplicação se torne um pouco mais lenta, algo que se pode notar enquanto o programa carrega, por exemplo.     Se você criar uma aplicação pequena, que faça algo simples, mesmo assim ela vai carregar um bocado de memória logo no início. Se essa aplicação é executada várias vezes ao longo do dia, convém não fechar a mesma, mas fica complicado aquele programa ocupando espaço na barra de tarefas.     Por isso, vou ensinar agora como fazer sua aplicação ir para a área de notificação (ao lado do relógio) quando for minimizada. Assim, com um duplo clique, ela volta num piscar de olhos para a tela principal para poder ser utilizada.     Crie um novo projeto no Visual Studio, ou adiciona em um projeto que você já tenha. Clique para aumentar     Aqui eu chamei o projeto de SendToNotifyArea (bem sugestivo, não!?). Você pode simplesmente fazer isso em algum outro projeto que você tenha. Vá até a ToolBox e em Commom Controls procure por NotifyIcon. O NotifyIcon é um controle relativamente fácil de utilizar, não tem grandes segredos, basta você prestar bem atenção o que cada uma de suas propriedades faz. Clique para aumentar     Arraste ele para a sua aplicação e selecione um ícone para o NotifyIcon clicando na seta que aparece ao lado do controle na parte inferior da janela de design da aplicação. Esse será o ícone que ficará aparecendo ao lado do relógio na área de notificação, por isso convém escolher um ícone que não seja muito comum por ali e que lembre um pouco a aplicação em si. Por exemplo, colocar o ícone igual ao de "novo e-mail" do Outlook Express é um problema certo. Free Image Hosting at www.ImageShack.us     Agora, nas propriedades do NotifyIcon você pode preencher as propriedades BalloonTipIcon, BalloonTipText e BalloonTipTitle conforme você achar necessário. Só acho interessante que no BalloonTipText apareça como se faz para aparecer de novo o aplicativo.     Caso deseje que o ícone fique fixo na área de notificação deixe a propriedade Visible como true. BalloonTipIcon : O ícone que aparece no balão BalloonTipText : Texto que aparecerá no balão BalloonTipTitle: Título que aparecerá na parte superior Clique para aumentar     Agora é no braço, temos que setar o evento que vai chamar tudo isso. Nas Propriedades do Form, clique no raio para selecionar os eventos e procure o evento Resize. Dê um duplo clique para ir ao modo Code.     Digite as seguintes linhas: private void Form1_Resize(object sender, EventArgs e) {        // Faz a aplicação sumir da barra de tarefas.       this.ShowInTaskbar=false;        // Mostra o balão com as informações que selecionamos.        // O parâmetro passado refere-se ao tempo (ms)        // em que ficará aparecendo. Coloque "0" se quiser        // que ele se feche somente quando o usuário clica-lo.       notifyIcon1.ShowBalloonTip(3000);        // Ativa o ícone na área de notificação,        // para isso a propriedade Visible deveria ser setada        // como false, mas prefiro deixar o ícone fixo lá.        // notifyIcon1.Visible=true; }     Esse não é o final. Agora temos que voltar tudo atrás para que o Form volte a aparecer.     Vá novamente no painel de propriedades, mas agora do NotifyIcon, clique no raio para selecionar os eventos e procure o evento MouseDoubleClick. Dê um duplo clique para ir ao modo Code.     Digite as seguintes linhas: private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) {       // Faz a aplicação aparecer na barra de tarefas.       this.ShowInTaskbar=true;       // Levando o Form de volta para a tela.       this.WindowState=FormWindowState.Normal;        // Faz desaparecer o ícone na área de notificação,        // para isso a propriedade Visible deveria ser setada        // como true no evento Resize do Form.        // notifyIcon1.Visible=false; }     Bom, com isso você consegue fazer sua aplicação ficar rodando sem incomodar ninguém.     Ah, outra coisa, existem aplicações, como o MSN, que ao clicar no X o programa faz a ação que expliquei acima ao invés de fechar. Caso deseja que isso ocorra, ao invés de colocar os códigos no evento Resize, coloque no evento FormClosing, com um detalhe, você deverá incluir as seguintes linhas a mais: [no FormClosing]        e.Cancel=true; // Cancela o evento padrão, de fechamento.        this.Visible=false; // Faz o Form desaparecer. [no MouseDoubleClick]        this.Visible=true; // Faz o Form reaparecer na tela. Clique Falow