Programação

...now browsing by category

 

Herança, Polimorfismo e Classes Abstractas – Quick Tips #2

Terça-feira, Julho 6th, 2010

Quando, a nível profissional trabalhamos em certas áreas de negócio, por vezes torna-se muito complexo implementar alguns dos conceitos básicos de POO (Programação Orientada a Objectos) que aprendemos.

Nestes casos é necessário fazer um esforço extra, abstrairmo-nos dos problemas de implementação das regras de negócio, dos sistemas existentes e desenvolver uma plataforma que, além de conciliar as regras de negócio e regras de arquitectura de software, tira partido das melhores funcionalidades oferecidas pela linguagem a ser utilizada.

É certamente o caminho para uma manutenção acessível e escalável, que vai garantir a longevidade da plataforma.

Herança e Polimorfismo são alguns dos conceitos mais importantes de POO, vou falar um pouco de cada um e apresentar uma pequena demonstração.

 

Herança

Por vezes as próprias regras de negócio estão agrupadas em famílias, temos que aproveitar esse factor a nosso favor e desenvolver uma estrutura do mesmo tipo por forma a que a arquitectura final seja consistente.

Recorrendo à herança entre classes podemos desenvolver uma estrutura de classes agrupadas por família, e que por sua vez têm informação organizada e transversal a toda a aplicação.

Vamos olhar para um exemplo real:

public class Angariacao
{
    public string Nome          { get; set; }
    public string Morada        { get; set; }
    public string EpocaBaixa    { get; set; }
    public string EpocaAlta     { get; set; }
    public string Enquadramento { get; set; }
}

public class CasaDeCampo : Angariacao
{
    public int    Capacidade    { get; set; }
    public string Tipologia     { get; set; }
}

public class HotelRural : Angariacao
{
    public string Actividades   { get; set; }
    public string Exterior      { get; set; }
    public string AreaSocial    { get; set; }
}

 

Como podemos verificar facilmente depois de analisar o código apresentado anteriormente, existe uma lógica para agrupar todas as propriedades partilhadas pelas classes CasaDeCampo e HotelRural.

A maioria das propriedades que cada uma das classes teria, estão agora na classe Angariação e essas propriedades vão ser partilhadas nas classes  CasaDeCampo e HotelRural através de herança.

Temos um grande número de vantagens ao utilizar este conceito de POO, uma delas é a fácil manutenção: caso se tenha que alterar/adicionar/remover uma propriedade na classe base, essa alteração é reflectida de forma automática em todas as classes que herdam da classe base.  Torna-se também mais rápido e eficiente adicionar novas classes que herdem da classe base, pois já existem nela implementadas muitas das funcionalidades básicas bem como as propriedades partilhadas que são transversais à família de classes.

 

Polimorfismo e Classes Abstractas

Polimorfismo significa “tomar várias formas”, quando utilizado em POO significa que uma assinatura de um método pode ter várias implementações diferentes.

Uma classe abstracta não pode ser instanciada, apenas define as propriedades e métodos que as classes filho que vão herdar.

Para exemplificar este conceito vamos recorrer às classes apresentadas no exemplo anterior e continuar a explorar o mesmo conceito:

//A classe passou a ser abstracta
public abstract class Angariacao
{
    public string Nome          { get; set; }
    public string Morada        { get; set; }
    public string EpocaBaixa    { get; set; }
    public string EpocaAlta     { get; set; }
    public string Enquadramento { get; set; }

    //Definição do método a ser implementado nas
    //classes que herdam de Angariacao
    public abstract void ImprimirTipoClasse();

}

public class CasaDeCampo : Angariacao
{
    public int    Capacidade    { get; set; }
    public string Tipologia     { get; set; }

    //Quando o método tem a assinatura abstract na classe base
    //é obrigatório implementar o override nas classes que herdam
    //da classe base
    public override void ImprimirTipoClasse()
    {
        Console.WriteLine(string.Format("Tipo: {0}", this.GetType()));
    }
}

public class HotelRural : Angariacao
{
    public string Actividades   { get; set; }
    public string Exterior      { get; set; }
    public string AreaSocial    { get; set; }

    //Quando o método tem a assinatura abstract na classe base
    //é obrigatório implementar o override nas classes que herdam
    //da classe base
    public override void ImprimirTipoClasse()
    {
        Console.WriteLine(string.Format("Tipo: {0}", this.GetType()));
    }
}

 

Neste momento temos definida a família angariação, que tem como base  a classe Angariação e filhos as classes CasaDeCampo e HotelRural.

A classe Angariação é abstract porque na lógica de negócio a implementar não existem objectos da classe base.

Como na classe base está declarado o método ImprimirTipoClasse com a assinatura abstract, a implementação de este método é obrigatória nas classes filho.

Para validar estes conceitos, criei um programa muito simples e que demonstra o potencial da Herança, Polimorfismo:

    class Program
    {
        static void Main(string[] args)
        {
            //lista de objectos da classe base
            var list = new List<Angariacao>();

            //adicionar à lista objectos que 
            //herdam da classe base
            list.Add(new CasaDeCampo());
            list.Add(new HotelRural());

            foreach (var item in list)
            {
                //Imprimir no ecrã o tipo de objecto
                //Demonstração final de Polimorfismo
                item.ImprimirTipoClasse();
            }

            Console.ReadKey();
        }
    }

Que resulta no seguinte ecrã quando se executa a aplicação:

heranca_e_polimorfismo

 

 

Para concluir, podemos verificar ao analisar a execução do programa que, embora a lista seja de objectos da classe base, podemos adicionar objectos que herdam da classe base, e quando invocamos o método ImprimirTipoClasse, o resultado é a execução do método que está definido classe filho.

Para criar um exemplo mais real, se a classe base tiver um método abstract que se chama AdicionarAngariacao, quando executado no programa da mesma forma que no exemplo acima demonstrado, iria ser adicionada uma Casa de Campo e um Hotel Rural ao sistema de acordo com as suas propriedades partilhadas e específicas, pois cada uma das classes filho implementa o método AdicionarAngariacao da forma mais conveniente.

Nested ListViews em ASP.NET

Quinta-feira, Julho 1st, 2010

ASP.net_100_logo_5

Por vezes temos necessidade de integrar muitos dados num ecrã para os apresentar da forma mais conveniente ao utilizador.

O que acontece durante este processo é que por vezes enfrentamos algumas dificuldades em transpor a informação que temos organizada na camada de negócio para a camada de apresentação de uma forma simples e sem grandes  alterações na sua estrutura.

Por exemplo, quando temos uma classe Contacto que além das suas propriedades mais comuns, contém também uma propriedade que é uma estrutura de dados da classe Servico, por vezes a melhor solução é optar por utilizar ListViews encadeadas.

public class Contacto
{
    public int id { get; set; }
    public string nome { get; set; }
    public IEnumerable<Servico> servicos { get; set; }

    public Contacto()
    {
        servicos = new List<Servico>();
    }

    public IEnumerable<Contacto> ObterContactos()
    {
        for (int i = 0; i < 3; i++)
        {
            var c = new Contacto();
            c.id = i;
            c.nome = "nome_" + i;
            c.servicos = (new Servico()).ObterServicos(i);

            yield return c;
        }

        yield break;
    }
}

Como podem verificar no código apresentado anteriormente, a classe Contacto tem uma propriedade do tipo IEnumerable<Servico>, que é uma estrutura de dados da classe Servico.

public class Servico
{
    public int id { get; set; }
    public string descricao { get; set; }

    public IEnumerable<Servico> ObterServicos(int id)
    {
        var listaServicos = new List<Servico>();

        for (int i = 0; i < 3; i++)
        {
            var serv = new Servico();
            serv.id = i;
            serv.descricao = string.Format("servico_{0}_{1}", i, id);
            listaServicos.Add(serv);
        }

        return listaServicos;
    }
}

Numa situação em que temos que apresentar num ecrã a informação da classe Contacto, a melhor solução seria poder alimentar um único controlo com uma lista de elementos desta classe e, este se encarrega-se de agregar a informação.

Sugiro algo assim:

<div>
        <h2>Exemplo de Nested ListViews</h2>
        <asp:ListView ID="ListViewPai" runat="server">
            <LayoutTemplate>
                <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
            </LayoutTemplate>
            <ItemTemplate>
                <h5>Informacao da ListView Pai</h5>
                <p>Nome:<%#Eval("nome") %></p>
                <asp:ListView ID="ListViewFilho" runat="server" DataSource='<%# Eval("servicos") %>'>
                    <LayoutTemplate>
                        <h6>Informacao da ListView Filho</h6>
                        <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
                    </LayoutTemplate>
                    <ItemTemplate>
                        <div style="border:1px solid black; width:250px; margin:15px;">
                            <p>id:<%#Eval("id") %></p>
                            <p>descricao:<%#Eval("descricao") %></p>
                        </div>
                    </ItemTemplate>
                </asp:ListView>
                <hr />
            </ItemTemplate>
        </asp:ListView>
    </div>

Como podem verificar, a fonte de dados que alimenta a ListViewFilho é         “<%# Eval("servicos") %>” que é o nome da propriedade existente na classe Contacto e que é do tipo IEnumerable<Servico>.

Ou seja, cada item do ListViewPai vai alimentar o ListViewFilho com a sua propriedade Servico.

O que resulta num código de carregamento de dados extremamente simples, como podemos verificar:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                CarregarDadosListView();
            }
        }

        public void CarregarDadosListView()
        {
            ListViewPai.DataSource = (new Contacto()).ObterContactos();
            ListViewPai.DataBind();
        }
    }
}

Ao utilizar este método apenas basta alimentar o datasource da ListViewPai, depois é cada item desta listview quem se encarrega de dar informação a ser apresentada à ListViewFilho.

Faça aqui o download  do projecto de demonstração em VS2010

ASP.NET DataPager – EFDataPager

Terça-feira, Abril 20th, 2010

att9ae36 O EFDataPager é um Web User Control que permite paginação com Entity Framework ou qualquer outro tipo de repositório de dados. A grande diferença entre este DataPager e o controlo standard que é disponibilizado no Visual Studio é que ao contrário do controlo standard este apenas vai buscar ao repositório de dados a informação que está a ser apresentada na página seleccionada, o que permite uma melhoria substancial na performance de acesso a dados e tempos de carregamento da página web.

Exemplo de uma ListView com o DataPager do VS2008:

image_3

image_4

 

Como se pode verificar na Imagem1 e Imagem2 acima apresentadas, quando estamos a utilizar o Standard DataPager para controlar a paginação de uma ListView, este carrega todos os dados do repositório e posteriormente organiza-os por páginas.

O maior problema de este controlo é que, em cada postback efectuado, é carregada novamente para a ListView a informação de todas as páginas mesmo que, como podemos ver na imagem2, apenas estejam a ser apresentados 3 registos ao utilizador. Como consequência o tempo de carregamento da página da página é penalizado, pois são carregadas informações que não vão ser apresentadas ao utilizador,  o que gera um declínio na experiência de utilização.

 

Exemplo de uma ListView com o EFDataPager:

image_1

image_2

 

Por outro lado, ao utilizar o EFDataPager, apenas são carregados para a ListView os registos que são apresentados (Imagem3 e Imagem4), garantindo assim uma melhor experiência de utilização por parte do utilizador e um tempo de carregamento da página substancialmente menor.

Pode utilizar o EFDataPager com qualquer repositório de dados, incluindo com Entity Framework.

 

Implementação

Além de ser muito fácil de implementar o EFDataPager, é também um controlo extensível e facilmente personalizado para ir de encontro a necessidades mais específicas.

image_5

Para implementar o EFDataPager é necessário adicionar ao projecto o ficheiro ControloDataPager.ascx e o ficheiroPagerEventArgs.cs.

Depois é necessário, como em qualquer outro WebUserControl, registar o controlo na página em que este vai ser utilizado.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ControloListView.ascx.cs" Inherits="EFDataPager.UserControls.ControloListView" %>
<%@ Register src="ControloDataPager.ascx" tagname="ControloDataPager" tagprefix="UserControl" %>

<h1>Notícias</h1>

<div class="noticias-pager">
    <UserControl:ControloDataPager ID="ControloDataPager1" runat="server" ViewStateMode="Enabled" />
    <asp:Label ID="NumberOfRowsLoadedFromDataSource" runat="server"></asp:Label>
    <br />
    <asp:Label ID="NumberOfRowsLoadedFromDataSourceEN" runat="server"></asp:Label>
</div>

<asp:ListView ID="listviewNoticias" runat="server" >
    <LayoutTemplate>
        <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
    </LayoutTemplate>
    <ItemTemplate>
        <div class="noticias-title" >
            <h3><%#Eval("Titulo")%></h3>
        </div>
        <div class="body-container">
            <p><%#Eval("Descricao") %></p>
        </div>
    </ItemTemplate>
    <EmptyItemTemplate>
        <h1>Não existem notícias disponíveis neste momento.</h1>
    </EmptyItemTemplate>
</asp:ListView>

Depois é necessário implementar o método RegistarEventos, utilizá-lo no Page_Load, implementar os eventos registados no método  RegistarEventos e implementar o método CarregarDadosListview.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace EFDataPager.UserControls
{
    using EFDataPager.BusinessObjects;

    public partial class ControloListView : System.Web.UI.UserControl
    {

        protected void Page_Load(object sender, EventArgs e)
        {
            RegistarEventos();
            ControloDataPager1.PageSize = 5;
            ControloDataPager1.RowCount = GetNumberOfRows();

            if (!Page.IsPostBack)
            {
                CarregarDadosListview(ControloDataPager1.PageSize, 0);
            }
        }

        private void RegistarEventos()
        {
            ControloDataPager1.First    += new ControloDataPager.ListViewPagerFirstHandler(ControloDataPager1_First);
            ControloDataPager1.Previous += new ControloDataPager.ListViewPagerPreviousHandler(ControloDataPager1_Previous);
            ControloDataPager1.Next     += new ControloDataPager.ListViewPagerNextHandler(ControloDataPager1_Next);
            ControloDataPager1.Last     += new ControloDataPager.ListViewPagerLastHandler(ControloDataPager1_Last);
        }

        void ControloDataPager1_Last(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        void ControloDataPager1_Next(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        void ControloDataPager1_Previous(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        void ControloDataPager1_First(object sender, PagerEventArgs e)
        {
            CarregarDadosListview(e.pageSize, e.currentRow);
        }

        private void CarregarDadosListview(int pageSize, int currentRow)
        {
            var data = new DadosMock();
            listviewNoticias.DataSource = data.ObterDadosMock(pageSize, currentRow).ToArray();
            listviewNoticias.DataBind();

            var nRows = data.ObterDadosMock(pageSize, currentRow).ToArray().Count();
            NumberOfRowsLoadedFromDataSource.Text = string.Format("Número de elementos carregados: {0}", nRows);
            NumberOfRowsLoadedFromDataSourceEN.Text = string.Format("Number of binded elements: {0}", nRows);
        }

        private int GetNumberOfRows()
        {
            var data = new DadosMock();
            return data.ObterRowCount();
        }
    }
}

 

Está classe é um Mock para simular o comportamento de um repositório de dados.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EFDataPager.BusinessObjects
{
    public class DadosMock
    {
        public int ID { get; set; }
        public string Titulo { get; set; }
        public string Descricao { get; set; }

        public DadosMock()
        {

        }

        public DadosMock(int id, string title, string desc)
        {
            this.Descricao = desc;
            this.ID = id;
            this.Titulo = title;
        }

        public IQueryable<DadosMock> ObterDadosMock()
        {
            var lista = new List<DadosMock>();

            for (int i = 0; i < 18; i++)
            {

                var item = new DadosMock(i, string.Format("Titulo {0}", i), string.Format("Descricao {0}", i));
                lista.Add(item);
            }

            return lista.ToArray().AsQueryable();
        }

        public IQueryable<DadosMock> ObterDadosMock(int pageSize, int currentRow)
        {
            var lista = new List<DadosMock>();

            //only for generate test data
            for (int i = 0; i < 18; i++)
            {
                var item = new DadosMock(i, string.Format("Titulo {0}", i), string.Format("Descricao {1}", i, i));
                lista.Add(item);
            }

            return lista.ToArray().Skip(currentRow).Take(pageSize).AsQueryable();
        }

        public int ObterRowCount()
        {
            return ObterDadosMock().Count();
        }
    }
}

Com o recurso ao linq, podemos facilmente controlar a paginação dos dados pedidos ao repositório de dados através dos métodos Skip e Take.

Demo: http://blastersystems.com/efdatapager/

O EFDataPager e o projecto vs2008 de teste estão disponíveis em:

http://efdatapager.codeplex.com/

IE 8 & VS2005 Debug

Sábado, Março 13th, 2010

VisualStudioLogoO Internet Explorer 8 tem melhorias e novas funcionalidades. Entre elas está o LCIE (Loosely Coupled Internet Explorer).

Essencialmente o LCIE é um conjunto de mudanças internas na arquitectura do Internet Explorer 8 que têm com objectivo melhorar a performance, escalabilidade e robustez do browser.

Entre essas melhorias está uma em especial, que trouxe alguns problemas inesperados aos programadores que utilizam o Visual Studio 2005 juntamente o com Internet Explorer 8.

No IE7 cada janela do browser (UI Frame) tem o seu processo, todos os novos separadores e controlos ActiveX estavam residem nesse processo. O problema com este modelo é, quando um separador provoca um “access violation” ou “stack overflow”, o processo é terminado, logo todos os separadores que estão no mesmo UI Frame vão ser terminados.

ie-tabsPara isso não acontecer no IE8, cada separador tem um processo próprio, assim quando existe um erro provocado por um separador, apenas o processo do separador é terminado, não o processo da janela do browser.

Na imagem apresentada, o browser tem três separadores abertos, o que no IE7 se irá traduzir num único processo, mas no IE8 se vai traduzir em 4 processos como se pode verificar na imagem em baixo.task-manager

Um dos processos é do UI Frame e os restantes três pertencem cada um a cada um dos separadores activos na janela do browser.

É sem dúvida uma excelente melhoria face à versão anterior do browser, no entanto surgiram alguns problemas aos programadores no momento que estes fazem o debug de aplicações  web com o Visual Studio 2005 e IE8.

O que acontece é que se, ao executar o debug da aplicação já existir um processo com o Internet Explorer a ser executado, o debugger do Visual Studio para e ignora os “break points” porque não encontra qual o processo do Internet Explorer que está a ser depurado.

Para resolver esta situação é necessário desabilitar a funcionalidade “grouwth” do LCIE.

Os passos são os seguintes:

1 – Abrir o RegEdit

 

2- Percorer HKEY_LOCALMACHINE -> SOFTWARE -> Microsoft -> Internet Explorer –> Main

 

3 – Adicionar uma DWORD com o nome “TabProcGrowth”

 

4 – Colocar no valor de “TabProcGrowth”  0

 

Fontes:

http://blogs.msdn.com/ie/archive/2008/03/11/ie8-and-loosely-coupled-ie-lcie.aspx

http://weblogs.asp.net/abdullaabdelhaq/archive/2009/06/01/VS-Debug-Problem-with-IE8.aspx

IE8 e o modo de compatibilidade

Sexta-feira, Março 5th, 2010

internet-explorer Já foi anunciada a morte do Internet Explorer 6, a versão 7 do mesmo browser parece ter passado de moda muito depressa porque agora existe o IE8.

No passado mês de Fevereiro de 2010, no top 5 dos browsers mais utilizados na web estão as três últimas versões do Internet Explorer (IE6, IE7, IE8).

Esta situação provoca uma grande dor de cabeça nos developers de aplicações web, pois é necessário garantir a compatibilidade das aplicações com os browsers que detêm maior quota de mercado e ao mesmo tempo é necessário conseguir implementar nas aplicações novas funcionalidades disponíveis apenas nos browsers mais recentes.

O Internet Explorer 8 é a versão mais  recente disponibilizada pela Microsoft e a mais próxima aos standards do W3C, houve por isso mesmo alguma mudanças importantes. No entanto este browser apresenta algumas funcionalidades que garantem aos developers e às empresas a compatibilidade de este browser com as suas aplicações desenvolvidas para versões anteriores.

Está situação pode acontecer  em empresas que estejam a executar processos de migração para o Windows 7, e no qual não é possível instalar versões do browser anteriores à versão 8.

Existem várias formas de garantir a compatibilidade das aplicações com o IE8, como por exemplo, configurar no servidor web o modo de compatibilidade em cada uma das aplicações (mais info sobre como garantir a compatibilidade no IIS aqui, e no Apache aqui), no entanto neste artigo vou falar apenas nas funcionalidades que o IE8 disponibiliza para garantir este processo.

O Internet Explorer 8 tem 3 modos de funcionamento, estes são:

  • IE 8 Standards Mode – Este modo garante que as páginas vão ser processadas pelo browser utilizando os últimos  standards utilizados pela Microsost para esta versão de browser.

 

  • IE 7 Compatibility Mode – Com este modo o browser interpreta as páginas recorrendo ao DOCTYPE do IE7, contudo continua a ser utilizado o motor do IE8 para processar as páginas.

 

  • IE7 Mode – Com este modo as páginas vão ser executadas de acordo os standards do IE7 e o DOCTYPE do IE7.
Agora vou propor a análise de outro problema. Vamos supor  estamos a desenvolver uma aplicação web para uma máquina de windows 7 com IE8 com compatibility mode activo, não temos acesso ao servidor web nem podemos alterar a configuração do IE8.
 
Como desenvolver uma aplicação que utiliza todas vantagens que o IE8 disponibiliza e garantir que vai funcionar correctamente nesta situação?
 
Podemos garantir isso com uma alteração, incluindo  “meta tag” no cabeçalho da aplicação web que vai forçar o browser a sair do modo em que está a operar e processar as páginas da aplicação em causa com o motor e DOCTYPE do IE8 nativo.
 
Para isso basta inserir esta “meta tag” no cabeçalho das páginas:
<meta http-equiv="X-UA-Compatible" content="IE=8"/>
 
Veja as diferenças da utilização dos vários modos que o IE8 suporta em acção:
 
Nesta imagem podemos ver que o browser está configurado para correr em modo de compatibilidade, no entanto a ”meta tag” que está no cabeçalho obriga-o a comporta-se como o IE8 nativo, ou seja, a utilizar o motor de processamento do IE8 e o DOCTYPE do IE8.
 
IE8-mode
 

Nesta imagem podemos ver que o browser está configurado para correr em modo de compatibilidade, podemos verificar esta situação recorrendo ao Developer Tools, ferramenta incluída no IE8, que este está a utilizar o motor de IE8 em modo de compatibilidade e a utilizar o DOCTYPE do IE7.EmulateIE7-mode

 

Aqui podemos verificar que ao utilizar na “meta tag” o “IE=7”, o browser utiliza o modo e o DOCTYPE do IE7, embora nas preferências do browser esteja activo o modo de compatibilidade.

IE7-mode

 

Mais informação sobre o IE8 e os seus modos de funcionamento em:

http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx#DCModes

Tech Days 2010

Terça-feira, Fevereiro 9th, 2010

techdays2010_logo

Nos dias 20 a 22 de Abril de 2010, a Microsoft vai realizar no Lagoas Park o Tech Days 2010.

O evento vai contar com a presença de cerca de 40 oradores portugueses e estrangeiros para assegurar as mais de 90 sessões e 40 laboratórios técnicos sobre XNA, Visual Studio 2010, Expression Studio, Sharepoint, Silverlight, WPF, Office, Exchange, SQL Server, Windows 7, Windows server 2008 e Windows Azure.

Também vão existir sessões direccionadas à arquitectura de software, Best Practices no desenvolvimento de software e User Exprerience (UX).

Este é o maior evento em Portugal na área das TI, um evento a não perder neste ano de 2010.

Como não podia deixar de ser, a comunidade NetPonto vai estar representada no evento.

Até dia 5 de Março existe um desconto de 75€ na inscrição.   

Mais informações em: http://www.techdays2010.com/

ASP.NET Social Bookmarks

Quarta-feira, Janeiro 13th, 2010

SocialBookmarksO ASP.NET Social Bookmarks é um Web User Control que    permite partilhar informação com as mais variadas redes sociais.

Os utilizadores conseguem interagir de forma simples com o controlo, e para os programadores é um componente reutilizável, flexível e escalável.

O componente é implementado como qualquer outro controlo de ASP.NET, contém CSS, ícones, possui também de um método para executar a compressão de Url, bem como a utilização das API’s das redes sociais implementadas para permitir ao programador um processo simples e eficiente de  publicação de informação nas principais redes sociais.

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
    <link href="Stylesheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="SocialBookmarks" runat="server">
    <aspbook:Bookmarks ID="Bookmarks" runat="server"
        EnableViewState="False"
        ShowEmail="true" ShowTwitter="true" ShowFacebook="true"
        ShowFlickr="true" ShowPicasa="true"
        ShowGoogleBookmarks="true" ShowLinkedin="true"
        ShowMap="true" ShowFeeds="true"
        MyTitle="ASP.NET Social Bookmarks" ShowTitle="true"  />
    </form>
</body>
</html>

Além de ser simples e flexível, pode ser altamente customizado, possibilitando ao programador adicionar facilmente o acesso a novas redes sociais ou até novas funcionalidades.

As funcionalidades implementadas permitem publicar facilmente informação sem a necessidade de conhecer as API’s das redes sociais.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace AspNetSocialBookmarks
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Example();
        }

        public void Example()
        {
            Bookmarks.TweetToShare =
                    "Testing the new user control, ASP.NET Social Bookmarks";
            Bookmarks.TwitterUrlToShare = "http://www.blastersystems.com/blog";
            Bookmarks.TwitterUser = "brunoacpires";
            Bookmarks.TwitterTooltip = "Share on Twitter";
        }
    }
}

twitter

O ASP.NET Social Bookmarks Web User Control e o código fonte está disponível em http://socialbookmarks.codeplex.com/ sobre a licença LGPL.

Eventos e Delegates em .NET

Terça-feira, Novembro 24th, 2009

Este artigo tem como objectivo esclarecer o que é um delegate e um evento, bem como exemplificar a implementação e a sua utilização numa aplicação.

Delegates

Um delegate é um tipo de referência utilizado para encapsular um método com uma determinada assinatura.

Exemplo:


public delegate string DevolveStringDelegate();

Esta declaração de um delegate pode encapsular qualquer método que não tenha parâmetros de  entrada e devolva um objecto do tipo String.

 

Em exemplo de utilização de delegates

using System;
using System.Collections.Generic;
using System.Text;

namespace Delegates
{
    public class Program
    {
        //Declaração de um delegate que tem como assinatura 
        //uma variável do tipo String 
        delegate void testeDelegate(string s);

        static void Main(string[] args)
        {
            //texto que vai ser escrito na consola  
            string texto= "estou a ver um delegate a funcionar!";
            //Cria-se uma instância do delegate e no construtor passa-se 
            //como parâmetro o nome do método que se quer utilizar, neste  
            //caso o método é o metodoComAssinaturaString porque contém 
            //a mesma assinatura que o delegate, tem como parâmetro  
            //uma variável do tipo String e devolve void
            testeDelegate t = new testeDelegate(metodoComAssinaturaString);

            //invocação do método que o delegate está a referênciar 
            //caso esse método tenha parâmetros, estes são inseridos 
            //ao utilizar o método invoke do delegate 
            t.Invoke(texto);
        }

        public static void metodoComAssinaturaString(string texto)
        {
            Console.WriteLine(texto);
        }
    }
}

E ao executar o programa…

testeDelegate

 

Eventos

Agora que está esclarecido o que é um delegate e como se implementa, vamos utilizar esse conceito e avançar para a implementação de um evento.

Um evento é uma acção que é despoletada quando uma condição que está  estabelecida se torna verdadeira.

Diagrama_Eventos_e_Delegates

Seguindo o diagrama acima apresentado, vou dar um exemplo de um evento. Temos um calendário, como o google calendar (quem publica os eventos) por exemplo, que permite a inserção de uma reunião, depois configuramos o google calendar para nos enviar um e-mail a avisar da reunião (subscrever o evento), no entanto podemos não ter acesso ao e-mail na hora que está marcada a reunião, assim, configuramos o google calendar para nos enviar uma SMS para além do e-mail (subscrever o evento).

Assim, quando chega a hora da reunião recebemos o aviso por dois canais diferentes, email e SMS, e que contém a mesma informação (EventArgs) no entanto a fonte da informação é a mesma, o google calendar!

Vamos então demonstrar um exemplo prático

using System;
using System.Collections.Generic;
using System.Text;

namespace DelegatesAndEvents
{
    //classe que descreve a informação a ser publicada
    public class ProcessarInformacaoEventArgs : EventArgs
    {
        private int _progresso;

        public int progresso
        {
            get { return _progresso; }
            set { _progresso = value; }
        }

    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DelegatesAndEvents
{
    //declaração do delegate que tem como parametro a 
    //classe ProcessarInformacaoEventArgs
    //que é onde vai ser guardada a informação que é 
    //enviada quando é disparado o evento
    public delegate void TickHandler(object sender,
        ProcessarInformacaoEventArgs p);

    //classe que publica o evento
    public class ProcessarInformacao
    {
        //declaração do evento que utiliza o 
        //delegate TickHandler
        public event TickHandler tick; 

        //Este método serve apenas de exemplo 
        //de processamento de informação
        public void ProcessarInfo()
        {
            long time = 100000000000;

            TimeSpan t = new TimeSpan(time);

            while (t.Ticks > 0)
            {
                t = t.Subtract(new TimeSpan(1000));
                long aux = time - t.Ticks;
                long res = (aux * 100) / time;

                //sempre que executa um ciclo, vai 
                //ser disparado um evento
                //que vai ser recebido por todas as 
                //classes que o subscreveram
                //e envia a informação processada 
                //por cada ciclo da estrutura
                //de decisão while
                OnTick((int)res);
            }
        }

        protected void OnTick(int p)
        {
            //chama o construtor com parametros da 
            //classe ProcessarInformacaoEventArgs
            //e invoca o evento com a informação que foi recebida
            ProcessarInformacaoEventArgs args = new ProcessarInformacaoEventArgs(p);
            tick(this,args);
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace DelegatesAndEvents
{
    //programa que subscreve o evento da classe ProcessarInformacao
    public class Program
    {
        static void Main(string[] args)
        {
            ProcessarInformacao p = new ProcessarInformacao();

            //Subscreve o evento
            p.tick += new TickHandler(p_tick);

            //Executar o processo que vai disparar o evento
            p.ProcessarInfo();
            Console.Read();
        }

        //Aqui é processada a informação enviada quando o evento é disparado
        static void p_tick(ProcessarInformacaoEventArgs p)
        {
            Console.WriteLine(p.progresso);
            Console.Clear();
        }
    }
}

 

Resultado da aplicação – Apresenta a percentagem de informação já processada.

testeEventos

Pode descarregar todos os projectos de este post aqui.

Demos desenvolvidas em VS2005.

Data Validator RC2

Segunda-feira, Novembro 23rd, 2009

Está disponível para download a versão RC2 do Data Validator.

Lista de bugs corrigidos na versão RC2:

-Verificações das strings de input nos métodos caso sejam do tipo null
-Corrigido bug na função WebServiceRequestUri
-Bug de encoding no processamento do ficheiro XML corrigido

4ª Reunião Presencial da Comunidade NetPonto

Quarta-feira, Novembro 18th, 2009

No dia 21/11/2009 será realizada a quarta reunião presencial da comunidade NetPonto, em Lisboa. Para participar, efectue o registo de acordo com as instruções abaixo.

Agenda

09:30

Recepção dos participantes

10:00

Novidades do SQL Server 2008Henrry Pires

Nesta apresentação, o Henrry irá mostrar alguns dos novos recursos do SQL Server 2008 que considera mais interessantes.

11:15

Coffee-break

11:30

Ferramentas de Apoio ao Desenvolvimento de SoftwarePaulo Correia

Nesta apresentação, o Paulo irá mostrar algumas das ferramentas que utiliza no dia-a-dia, e que considera indispensáveis para aumentar a produtividade e resolver problemas.

12:45

Painel de Discussão

Nota: Ao final da reunião, normalmente escolhemos um restaurante próximo e fazemos um almoço em grupo para continuar o convívio e aproximar as pessoas. A participação é opcional.


Registo / Inscrição

Para participar, envie um e-mail para contacto@netponto.org e informe o seu nome completo, número de B.I., número de telefone e endereço de e-mail preferencial (caso seja diferente).
A entrada é gratuita e está apenas sujeita a confirmação via e-mail, no entanto, gostaríamos de aproveitar esta oportunidade para ajudar uma instituição de solidariedade, e para esta reunião de Novembro elegemos a Casa do Gil, e por isso pedimos que leve consigo no dia da reunião, 1 Kg (um quilo) de alimento não-perecível (arroz, feijão, massa, latas de conserva, etc…), que será doado para esta instituição.


Local

Novabase (Lisboa)
Av. D. João II, Lote 1.03.2.3, Parque das Nações
1998-031 Lisboa

Clique para ampliar o mapa.