segunda-feira, 16 de fevereiro de 2009

Qualidade Interna não é negociável!!!

Olá Pessoas!

Atualmente estou a estudar o
SCRUM. Nestes estudos encontrei o livro "Scrum e XP direto das trincheiras", é um livro extremamente prático e didático, ótimo para quem está começando, como eu.

Em uma das minha leituras encontrei a declaração abaixo:

"Generally speaking, a system with high internal quality can still have a
low external quality. But a system with low internal quality will rarely
have a high external quality. It is hard to build something nice on top of a
rotten fundament."


Logo após o autor explica:

External quality is what is perceived by the users of the system. A
slow and non-intuitive user interface is an example of poor
external quality.

Internal quality refers to issues that usually aren’t visible to the
user, but which have a profound effect on the maintainability of
the system. Things like system design consistency, test coverage,
code readability, refactoring, etc.

Após esta declaração o autor comenta que a "Qualidade Interna" não é tema de discussão sobre o escopo de um projeto ou requisito, pois é responsabilidade da equipe manter a qualidade do sistema sob todas as circunstâncias e isso simplesmente é inegociável.

Resumindo, PARE de achar que tudo que você desenvolve resume-se a um único método ou uma única classe, ou ainda pior, a um monte de classes que só espalham código sem o mínimo de coesão, rastreabilidade e possibilidade de escalabilidade.

Ao invés disto, pesquise, leia, discuta, teste, ouça. Existem muitos recursos em livros, sites, artigos, blogs que vão ajudá-lo a encontrar argumentos suficientes para fazer da "Qualidade Interna" um tema inegociável em seus projetos.

Pense nisso!

[]'s

Ricardo Cunha

terça-feira, 10 de fevereiro de 2009

WCF, JSON, Dynamics CRM - Uma mistura interessante.

Olá Pessoas,

Atualmente quando analiso desenvolvimentos para o MS CRM vejo uma tendência muito grande dos desenvolvedores acreditarem que XML e ASP.NET Web Services são os únicos recursos para um acesso remoto aos Serviços do CRM, quando estamos customizando um Formulário ou um botão ISV via Java Script.

Contudo se analisarmos o cenário mais friamente chegaremos a conclusão de que nem XML, muito menos Web Services serão a melhor solução quando estamos pensando em ganhos de desempenho (por conta do empacotamento e envio destes formatos que causam um overhead considerável no tráfego da rede), muito menos simplicidade na arquitetura, porque certamente você precisará pensar uma camada só para tratar o retorno de chamadas que são realizadas através de Java Script, a fim de manipular os dados no formato XML, que convenhamos, dá uma baita dor de cabeça quando temos cenários mais complexos de envio e recebimento de informações.

Algumas das alternativas para sanar problemas como os citados acima são o WCF e o formato JSON que, juntos, aliam ganho de performance e maior simplicidade no design na aplicação.

Abaixo segue um exemplo da utilização destes dois recursos:

Importante: Estou considerando neste exemplo que você já possui os conhecimentos de como criar um projeto WCF, publicá-lo para acesso através de HTTP e referenciar o SDK do Microsoft Dynamics CRM ao seu projeto.


1. Definição do contrato do Serviço

[ServiceContract]
public interface IClienteService {

[OperationContract]
account Obter(Guid accountId);

}

2. Implementação do contrato

public class ClienteService : IClienteService {

public account Obter(Guid accountId) {

// return CrmService.Retrieve("account", accountId, new AllColumns());

}

}

3. Arquivo de configuração do Serviço



[WebConfig.jpg]



4. Configuração da chamada Java Script

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");

// Informando o caminho do serviço e o métod que será executado

var url = http://localhost:1700/ClienteService.svc/Obter;

// Configuração no formato JSON
var accountId = '{"accountId":"' + '{6f5cfcf2-ba2d-481c-bd85-5c03ba8a652d}' + '"}';

xmlHttp.open("POST", url, false);
xmlHttp.setRequestHeader("Content-type", "application/json; charset=utf-8");
xmlHttp.setRequestHeader("Content-Length", data.length);
xmlHttp.send(accountId);

// Método que disparado após a execução da pesquisa
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {

var account = eval('(' + xmlHttp.responseText + ')').d;

alert(account.accountid.Value);
alert(account.name);

}
}

No exemplo acima estamos fazendo uma consulta a base do MS CRM utilizando como "Proxy" um serviço WCF que expõe um tipo complexo do MS CRM, sem a necessidade de se criar uma camada adicional para tratar o retorno do MS CRM para um tipo qualquer, como XML, por exemplo.

Já no lado Client, fica claro que a configuração da pesquisa ficou muito mais simplificada. Além disto, devido a utilização do formato JSON podemos trabalhar com o objeto "account" da mesma forma se estivessemos manipulando este objeto no C#.

Um outro aspecto importante é quanto ao desempenho desta chamada, pois não se fez necessário o empacotamento no protocolo SOAP, livrando-nos assim de uma quantidade excessiva de tags XML. Neste caso as únicas informações submetidas são o valor -- {"accountId":"{6f5cfcf2-ba2d-481c-bd85-5c03ba8a652d}"}--, que está no formato requirido pelo padrão JSON, e os valores de Content-Type e Content-Length adicionados ao Header da requisição.

Como vimos com WCF e JSON podemos criar uma mistura no mínimo interessante como alternativa aos famigerados Web Services e XML no acesso as informações, via JavaScript, dentro da plataforma Dynamics CRM.

[]'s


Ricardo Cunha



segunda-feira, 2 de fevereiro de 2009

Dependecy Injection no MS CRM

Olá Pessoas,

Desde muito tempo sou amante dos Design Patterns e, por conta disto, sempre que tenho contato com uma aplicação de software tento de alguma maneira identificá-los para aperfeiçoar cada vez mais meus conhecimentos quanto a suas aplicações.


Quando desenvolvemos para o Microsoft Dynamics CRM temos acesso há um Pattern chamado Dependecy Injection que é extremamente útil e complexo, mas que, na maioria dos casos, os desenvolvedores nem sabem que estão utilizando tal conceito. Claro que na prática isto não importa muito, mas para nosso crescimento e aperfeiçoamento como desenvolvedores ter o conhecimento de tal mecanismo, ao menos na minha ótica, pode ser fundamental.

O Pattern Dependecy Injection, como o próprio nome sugere, permite que você injete uma dependência dinâmica a sua aplicação, a fim de prover uma certa "inversão de controle", pois esta "dependência externa" pode alterar completamente o comportamento do seu sistema.

No Microsoft Dynamics CRM nós vemos a implementação deste pattern através do mecanismo de Plug-ins.

Quando implementamos a interface IPlugin estamos criando a dependência externa citada na definição do pattern.

Veja o Exemplo Abaixo:

namespace MyPlugins {

public class PluginImplementation : IPlugin {

public void Execute(IPluginExecutionContext context) {
// implementação do seu método;
}
}
}

Após implementar a classe acima e registrá-la no MS CRM o PluginRegistration Tool encarrega-se de criar os registros nas tabelas PluginAssemblyBase, para armazenar o nome do assembly gerado "MyPlugins.dll", e na tabela PluginTypeBase, para armazenar o caminho completo até a classe que implementa a interface IPlugin, no nosso caso MyPlugins.PluginImplementation.
Após a pesquisa dos dados do assembly que você registrou no banco de dados será executado no kernel do MS CRM um trecho de código conforme apresentado nas linhas abaixo:

// O código abaixo executado pelo kernel do MS CRM.

// Criando a instância do plugin registrado pela ferramenta.
IPlugin plugin = (IPlugin) Assembly.Load("MyPlugin.dll").CreateInstance("MyPlugin.PluginImplementation");

// Disparando o método Execute da classe PluginImplementation, criado por você.
plugin.Execute("Instância da interface IPluginExecutionContext");

Com isto temos a "inversão de controle", conforme citado anteriormente, pois neste momento a execução do método "Execute()", que ocorre no kernel do MS CRM, passa a estar totalmente sob seu controle e assim vemos a utilização do pattern Dependency Inection. Simples não é?

Um outra arquitetura que explora muito este pattern e o próprio ASP.NET, aonde temos a possibilidade de fazer inúmeras configurações no web.config e machine.config, como HttpModules, HttpHandler, MembershipProvider, etc.


Se analisarmos bem estamos cercados pelos Design Patterns, só precisamos estar atentos para identificar suas vantagens e a partir daí utilizá-los da melhor forma possível em nossas aplicações.


[]'s


Ricardo Cunha