SAAS com NHibernate e Múltiplos Bancos de Dados
Olá pessoal.
Últimamente pesquisei sobre alguma forma de desenvolver uma aplicação SAAS (Software as a Service) com o NHibernate.
Imagine o seguinte cenário, eu preciso que em tempo de execução o NHibernate troque o banco de dados dependendo do domínio que acessa a aplicação.
Por exemplo, se eu entrar na aplicação pelo endereço cliente1.com.br será carregado o banco de dados cliente1 que terá todas as informações deste cliente e as informações de cores e tamanhos da interface gráfica. O mesmo acontece para o endereço cliente2.com.br e cliente3.com.br.
Uma das formas que encontrei de conseguir isto é aproveitando a total extensibilidade do NHibernate e plugar nele um ConnectionProvider customizado. o ConnectionProvider é o objeto que fornece as coneções para o NHibernate.
Eis o provider customizado:
public class MultiDbConnectionProvider : DriverConnectionProvider
{
public override IDbConnection GetConnection()
{
IDbConnection connection = Driver.CreateConnection();
try
{
connection.ConnectionString = SaasUtil.GetConnectionStringFromInstance();
connection.Open();
}
catch (DbException)
{
connection.Dispose();
throw;
}
return connection;
}
}
Não é muito complicado, eu apenas sobrescrevo o método GetConnection que cria uma nova conexão passando a connection string específica para aquele determinado cliente.
É preciso também mudar o arquivo de configuração para o novo provider:
<property name="connection.provider"> My.Namespace.DbSpecificConnectionProvider, MyAssembly </property>
Eu fiz um pequeno teste e funciona perfeitamente, porém não tenho muita certeza de como o NHibernate vai se comportar a nível de cache.
ASP.NET MVC 4: ASP.NET Web API
Olá pessoal.
Hoje vou falar de um novo recurso presente no ASP.NET MVC 4 e que é bem interessante, se trata do ASP.NET Web API, um framework desenvolvido para criarmos uma Web API para nossa aplicação.
Web API são um conjunto de serviços expostos através da internet que possibilita a integração entre a aplicação e diversos clientes que vão desde uma página acessando a aplicação via Ajax até um aplicativo nativo em um dispositivo móvel acessando diretamente a aplicação. Exemplos comuns de Web API são as APIs do Facebook, do Twitter e do LinkedIn.
O que é possível com o ASP.NET Web API?
Para começar, criar uma Web API é como criar um controller comum do ASP.NET MVC, exceto que ele herda da classe ApiController e não retornará uma View, mas sim dados serializados em XML, JSON ou dados de formulários criptografados. O tipo de dado retornado pode ser definido no lado servidor ou negociado com o cliente de forma dinâmica. Veja dois exemplos abaixo:
public class ProdutoController : ApiController
{
public HttpResponseMessage GetProduto()
{
Produto produto = new Produto();
produto.Codigo = 1;
produto.Valor = 100.00M;
produto.Nome = "TESTE";
HttpResponseMessage<Produto> response = new HttpResponseMessage<Produto>(produto,
new MediaTypeHeaderValue("application/json"));
return response;
}
}
Ao chamar o endereço http://localhost:{PORTA}/api/produto/getproduto, irá aparecer o objeto Produto serializado em XML.
<Produto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Nome>TESTE</Nome> <Valor>100.00</Valor> <Codigo>1</Codigo> </Produto>
Mudando a linha onde tem:
MediaTypeHeaderValue(“application/xml”)
por
MediaTypeHeaderValue(“application/json”)
o mesmo Produto é retornado em JSON:
{“Codigo”:1,”Nome”:”TESTE”,”Valor”:100.00}
Outro recurso bem interessante é que podemos retornar um objeto IQueryable e realizar consultas nele diretamente pela chamada da URL!
Usando as convenções de URL do protocolo OData. Por exemplo, imagine o seguinte método em nosso ProdutoController:
public IQueryable<Produto> GetListaProdutos()
{
return repository.GetProdutos().AsQueryable();
}
Usando as convenções do OData, podemos por exemplo, determinar o filtro da lista pela URL:
http://localhost:{PORTA}/api/produto/getlistaprodutos?$orderby=Nome
Estes recursos são muito úteis quando queremos disponibilizar algum tipo de integração com nossa aplicação, seja apenas para consultar os dados quanto para executar algum tipo de função como postar uma mensagem no mural do Facebook por exemplo.
Isso é apenas uma parte do que podemos fazer com o ASP.NET Web API.
Novidades do Visual Studio 11 – Editor de CSS
Olá pessoal, hoje vou falar de mais novidades sobre o Visual Studio 11, dessa vez sobre as melhorias no editor de CSS.
A nova versão do Visual Studio vem com grandes novidades no editor de CSS, para melhorar a produtividade, a organização do código e a compatibilidade entre navegadores.
Color Picker
Nas versões anteriores do Visual Studio, o intellisense do editor de CSS nos fornecia uma lista de valores de cor pré definidos como Silver, Yellow, Green etc. O Visual Studio 11 substitui esse intellisense de cores por um color picker mais robusto e com mais opções de cores, podemos escolher entre as cores pré definidas ou adicionar uma nova cor.
Se você clicar em (+), irá se expandir um color picker semelhante ao do Adobe Photoshop para seleção de cores. Podemos também definir o canal alfa que será automaticamente convertido em uma cor CSS3 RGBA. Com o recurso de “Pick”, podemos selecionar uma cor de um site aberto no navegador ou de um aplicativo aberto.
Código Coss-Browser
Desenvolver um site compatível com todos os navegadores as vezes se torna um pouco repetitivo quando há propriedades específicas para cada navegador, por exemplo -moz-border-radius, -webkit-border-radius e -o-border-radius. O Visual Studio 11 possui um suporte para gerar todas as propriedades de navegadores específicos automaticamente, por exemplo, basta apenas escrevermos transition no editor de CSS:
Em seguida, se apertamos o [TAB], o Visual Studio 11 irá gerar o código de transition específicos para cada navegador para oferecer o suporte cross-browser. Também é possível alterar o valor de apenas uma propriedade e propagar a alteração para as outras.
Hierarquia de CSS
Preciso nem falar muito sobre esse recurso, basta olhar a imagem para entender do que se trata:
Agora podemos identar o código CSS para tornar mais legível uma relação pai-filho de regras. Na versão anterior do Visual Studio, para fazer algo parecido, era necessário desabilitar a identação automática de CSS.
Finalmente temos um editor de CSS robusto, cheio de recursos e não mais preso ao Internet Explorer. A nova versão do Visual Studio, irá tornar o desenvolvimento de estilos CSS mais fácil e rápido, com muitos recursos que faziam falta como o color picker. e o suporte à estilos compatíveis com outros navegadores.
O Novo Entity Framework 4.3
Para quem ainda não sabe, foi lançado recentemente a nova versão do Entity Framework 4.3
Entre algumas novidades estão as seguintes:
Code First Migration – É a novidade mais interessante e que muitas pessoas esperavam, agora quando alteramos nosso modelo, o banco de dados não precisa ser recriado do zero novamente. Com o novo recurso de migração as alterações no modelo serão atualizadas no banco de dados.
Remoção da tabela EdmMetadata.
Data Annotations em propriedades não públicas – Agora as anottations aplicadas em propriedades private, internal e protected não serão ignoradas pelo Entity Framework.
Você pode ver mais detalhes sobre o Entity Framework 4.3 clicando no link abaixo:
http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-released.aspx
Como Formatar Datas com string.Format no C#
Este exemplo abaixo, mostra como podemos formatar um objeto de data DateTime em diversos formatos usando o String.Format.
Quando trabalhamos com data, às vezes é necessário o uso de formatos de data customizados, como por exemplo, uma data no formato mm/yyyy de uma fatura, uma data de um chamado aberto sem os segundos, ou ainda uma data por extenso para o rodapé de um relatório.
Para criar os formatos de data customizados, usamos algumas letras específicas onde cada letra significa uma parte da data. y (ano), M (mês), d (dia), h (hora 12), H (hora 24), m (minuto), s (segundo), f (fração de segundo), F (fração de segundo, mostrando zeros após a unidade inteira ex: 0.2000), t (P.M ou A.M) e z (time zone).
// Criando uma data 09/03/2008 16:05:07.123
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);
String.Format("{0:y yy yyy yyyy}", dt); // "8 08 008 2008" ano
String.Format("{0:M MM MMM MMMM}", dt); // "3 03 Mar Março" mês
String.Format("{0:d dd ddd dddd}", dt); // "9 09 Dom Domingo" dia
String.Format("{0:h hh H HH}", dt); // "4 04 16 16" hora 12/24
String.Format("{0:m mm}", dt); // "5 05" minuto
String.Format("{0:s ss}", dt); // "7 07" segundo
String.Format("{0:f ff fff ffff}", dt); // "1 12 123 1230" fração de segundo
String.Format("{0:F FF FFF FFFF}", dt); // "1 12 123 123" fração de segundo sem zero
String.Format("{0:t tt}", dt); // "P PM" A.M. ou P.M.
String.Format("{0:z zz zzz}", dt); // "-6 -06 -06:00" time zone
Quando usamos o separados de data “/” e o separador de tempo “:” eles serão substituídos pelo separador de data e de tempo definidos na cultura atual com o DateTimeFormatInfo.DateSeparator e o DateTimeFormatInfo.TimeSeparator.
// a cultura alemã substitui o separador de data "/" pelo "."
String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9/3/2008 16:05:07" - Português Brasileiro (pt-BR)
String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9.3.2008 16:05:07" - Alemã (de-DE)
Como Excluir Várias Entidades no NHibernate
Quem já usou o Nhibernate, provavelmente já sentiu falta de algum recurso onde podemos remover de uma vez vários itens, pois com o método Delete do objeto de sessão só é possível deletar um objeto por vez.
Há uma forma de implementar uma exclusão múltipla no NHibernate usando a cláusula IN no HQL:
var idObjetos = new List<int>() { 5,3,6,7 };
_session.CreateQuery("DELETE FROM Produto p WHERE p.Id = IN :idObjetos")
.setParameterList("idObjetos", idObjetos)
.executeUpdate();
ObjectContext global no Entity Framework: Usar ou não?
Algumas pessoas que usam o Entity Framework, já deve ter se perguntado, será que é recomendado utilizar uma única instância global do ObjectContext ou é melhor uma instância em cada escopo de execução?
A resposta é, depende do cenário. Para aplicações onde terá uma única execução como um Windows Forms, ou aplicações web que não variam com o usuário como um editor de imagens online por exemplo, pode ter vantagens usar uma única instância do ObjectContext como reduzir o número de objetos na memória e gerenciar melhor como estes objetos serão usados. Você, no entanto, precisará gerenciar cuidadosamente o consumo de memória de seu aplicativo, porque o ObjectContext irá manter uma referência de cada entidade recuperada através dele, a menos que você use uma consulta NoTracking ou execute de forma explícita.
Para aplicações ASP.NET ou serviços, o recomendado é você não utilizar um único ObjectContext global por diversas razões, incluindo problemas de execução (O ObjectContext não é thread-safe, ou seja, não suporta multi-threading), muitas referências a entidades em memória (porque o contexto mantém referências a objetos recuperados através dele, como mencionado acima) e a consistência dos dados (como os dados no banco de dados evolui ao longo do tempo, e pode ficar fora de sincronia com os dados no seu repositório de dados a menos que você explicitamente defina a consulta utilizando OverwriteChanges e MergeOption).
Observações:
Pessoal, este texto acima é parte de uma contribuição minha na wiki do Technet da Microsoft onde explico sobre o ObjectContext com base em um texto do próprio pessoal da Microsoft, gostaria de opiniões sobre o texto, se está bem explicado, se falta mais detalhes etc..
Passei na Prova 70-519 e Agora sou MCPD
Hoje dia 25/01/2012 passei na prova 70-519 e agora sou um MCPD em “Designing and Developing Web Applications Using Microsoft .NET Framework 4″
Vou comentar um pouco sobre a prova.
Eu considerei a prova muito difícil, tinham questões em que todas as respostas poderiam ser as certas, cabendo apenas escolher a mais adequada.
Não estudei muito para esta prova, pois como não fiz nenhum curso, meu conhecimento é completamente autodidata e eu não sabia o que estudar.
Como eu sabia que a prova exigia uma certa vivência, como no próprio site da certificação diz, desde a primeira prova que eu fiz (70-515) eu venho tentando adquirir experiência criando vários projetos simples como treino, utilizando Entity Framework, ASP.NET MVC, ASP.NET Web Forms, várias formas de autenticação, várias formas de captura de erros na aplicação. E isso ajudou, e muito.
Desejo boa sorte a quem deseja realizar este exame, e qualquer dúvida entre em contato comigo pelo formulário do site.
Sum com Linq e valores Nullable
Vamos imaginar a seguinte situação.
Temos uma lista de produtos com nome e valor, o valor do produto pode ser nulo:
public class Produto {
public string Nome { get; set; }
public decimal? Valor { get; set; }
}
vamos agora tentar obter o valor total dos produtos:
List lista = db.GetProdutos(); decimal soma = lista.Sum(c => c.Valor);
Ao rodar o código, se houver um produto com valor nulo, tomamos um erro.
The cast to value type ‘Decimal’ failed because the materialized value is null. Either the result type’s generic parameter or the query must use a nullable type.
Como resolver este problema?
Para resolver é bem simples, precisamos apenas usar um comando muito útil no C# e que pouca gente conhece, o Null Coalescing (??):
decimal soma = lista.Sum(c => c.Valor ?? 0);
ou com Linq:
decimal soma = (from p in lista
select p.Valor ?? 0).Sum();
No exemplo acima, com o ?? estou dizendo que é para retornar o Valor diferente de nulo ou 0, Semelhante ao If abaixo:
(p.Valor != null) : p.Valor ? 0
Segue abaixo um código completo mostrando o funcionamento da dica, basta criar um novo projeto Console Application e inserir o código abaixo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class Produto
{
public string Nome { get; set; }
public decimal? Valor { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Produto> lista = new List<Produto>();
lista.Add(new Produto
{
Nome = "Teste 1",
Valor = (decimal)54.2
});
lista.Add(new Produto
{
Nome = "Teste 2",
Valor = null
});
lista.Add(new Produto
{
Nome = "Teste 3",
Valor = 65
});
decimal soma = (from p in lista
select p.Valor ?? 0).Sum();
Console.WriteLine(soma);
Console.ReadKey();
}
}
}






