Persistence Ignorance – Why you should care about it

Think: what are the main concerns of an O/RM? You must have thought about performance and productivity. Think again. You probably want a “headacheless” technology to share great part of your work hours in the next months of your current project, don’t you?

If the answer is yes start chasing Persistence Ignorance. Do it tirelessly because it worth. Now why am I saying that?

Fortunately nowadays communities and development teams have started to care about software design and business abstraction. It means that in most of LoB applications data persistence have become a secondary concern. People no longer write tons of code because they have a database set up, but they need to persist data after writing and designing tons of business code.

This inversion of values is possible thanks (not only) to Persistence Ignorance. DOT.

If your O/RM choice was designed considering PI, you can test-drive your design cranking all the business code you want without – most important of all – spending too much time mapping your entities.

Even the decent O/RM cannot be 100% transparent to our entities. There is no pure-POCO objects that “completely ignore” the object-relational mapping.

The key here is to pick the technology that is most unobtrusive to your business code. We shall not become slaves of mapping technologies unless it’s a primary requirement.

Ignore Property Mapping with Fluent NHibernate’s Automapping model

Hello there,

It took me a lot of web-seeking over Stackoverlow’s questions, Fluent NHibernate’s Google group and James Gregory’s blog but I’ve finally discovered it. What if you want to tell NHibernate not to map one or more property(ies) from your entities?

It may appear to be a silly issue (and the answer is really quite simple though) but it was not in the first nor the second attempt that I solved it.

Fluent NHibernate provide a very extensible convention model, in a sense that you can create your own property ignoring convention, but the most direct way to ignore a property within mapping process is to use the OverrideAll method. Let’s consider the following SessionFactory setup:

var sessionFactory = Fluently
                .Configure()
                .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("MyConnString")))
                .Mappings(x => x.AutoMappings.Add(AutoMap.AssemblyOf<MyEntity>(mapConfig)
                    .OverrideAll(ign => ign.IgnoreProperty("MyPropertyToBeIgnored"))
                    ))
                .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true))
                .BuildSessionFactory();
            return sessionFactory;

Instead you could provide more information from the ignored property using the IgnoreProperties(Func predicate) overload, since Member is a core class from Fluent NHibernate with a bunch of reflection work.

You may also want to ignore more than one property in a row. This could be achieved by calling the IgnoreProperties(string first, params string[] others) overload, like:

.Mappings(x => x.AutoMappings.Add(AutoMap.AssemblyOf<MyEntity>(mapConfig)
    .OverrideAll(ign => ign.IgnoreProperties("FirstPropertyToBeIgnored", "SecondProperty", "ThirdProperty"))
))

However, inlining configuration can become maintenance-painful as your system grows up, so you should really consider to create your own property ignore convention, which will be approached here in a future post.

Stay craft.

Architecture and development pitfalls

Lately I have been having some thoughts about what makes our jobs more tricky and what we should do as developers and architects to avoid some headaches and pitfalls. From my latest projects experiences I can certainly list:

“…a good design will document itself in many ways” (Dave Anderson)

There’s no such cleaner way to express the software functionalities than a good and simplistic design. Moreover, UML and powerpoint documents easily get outdated and comments written in the code generally are not valuable for domain understanding.

The team must feel confortable to work and write pieces of code without fearing of breaking any “unknown modules”. First of all, there shouldn’t be “unknown modules”. Even a beginner developer should fluently “walk on the code” and recognizes its separation of concerns. Let’s remember that: maintainability matters.

Fortunately, we are not alone, there are some principles: KISS, YAGNI and Emergent Design might help us here. It doesn’t matter if you’re using a Dependency Injection Container to control your application’s dependencies if your software’s scope probably will never demand that. It’s useless, wasteful and meaningless: You Ain’t Gonna Need It! Don’t create an “unused monster” by upfront, evolve your architecture as the product need it. Avoid BDUF and be prepared for changes! They happen all the time, and your software will certainly change. You must accept that and more your design adapts itself for changes, more the architecture will evolve instead of being re-designed from scratch.

Furthermore, clean designs generally indicate “testable” softwares, which is amazing for the development team.

If you re-write a production code, you must assure (at least) its original functionality

Refactoring is one of the key factors of maintaining a legacy system. We all should know the ideal moment to refactor and whether it doesn’t worth. It may sounds pretty obvious, but my point is: we must guarantee that, at the end of the refactoring, the software functionality must covers at least its original state. The easiest and valuable way to achieve that is to start writing tests.

Tests can give us a quick regression and an instant feedback whenever someting goes wrong. This is extremely suitable when we write a huge portion of code and put it in place of legacy and current running production code. Tests demands that our codes are easy to test, and most of the time to achieve that the software design must be less-coupled under a good separation of concerns, which remind us of my first tip.

However, writing tests in legacy code is harder to approach than a simple blog post could ever do. My tip here is to do it only on demand (e.g: when you need to fix a bug or develop a new feature) and in an incremental way (remember TDD baby-steps).

Don’t let your test-suite get deprecated

If we have a set of unit-tests we should take care of it.

Tests are not only meant to be ran once (and most of the times that’s exactly what happens, because we almost always run the unit-tests only to assure our first developments), but tests should run at least before each software release.

Some fortunate people made out to apply continous delivery and integration in their companies and they have a build server to run the test-suite each time any code is committed (or pushed for git lovers). This is awesome to keep the code-base promptly tested, increase its quality and exterminate the commit-and-run “phenomenon”.

Even though, you must be asking yourself “why should we maintain our test-suite updated“?

Because when the tests are updated we have reasons to run them! And by running them:

  • We get instant feedback (tests are fast to run).
  • We’ll be the first to spot the “red lights of deathly errors“.
  • Tests are the first consumers of our code:
    • If any SUT is hard to test it means that it has more responsabilities than it should has.
    • They also show us how our code will be consumed or how it will behave in future maintenance.
  • Clean and behavior-driven tests are an excellent way to document software behaviors.
  • Developers are lazy: if the test-suite gets outdated, they probably WON’T keep writing tests on it. As the test-suite being regularly running the team’s sinergy and commitment about testing will keep growing up.

Pair programming for the win

Pair programming can be fun, dynamic and most of all, productive. For many things, two persons can do better than one, and in software development is not different. When I work in pairs these are the “rules”:

  • Choose another professional in the same/similar level and skills.
  • Swap the person who’s in charge of write the code and control the computer every 10 minutes (or 20 minutes in the first times).
  • Both of the professionals should be able to control the machine once both of them know what to do in the task.
  • Even the person who’s not writing code or controlling the machine must pay attention and stay focused on the current task.
  • If you’re not writing the code, try to think “outside-the-box” and look for possible issues at the code that’s being written. While the other professional writes the code seek for design impacts and maintenance issues.
  • Enjoy the might of instant-peer-review: review each line that is written by your pair. Wait for he/she to end a “line-of-thought” for make suggestions and corrections. By doing that you’ll show respect and professionalism.
  • Be prepared for conflicts. Know how to deal with suggestions and know how to give them (remember that programmers aren’t humble).

Isolate the boundaries

It’s very difficult to find nowadays softwares that doesn’t communicate with another systems. These are the main reason why software architects should care about isolate communications:

  • Boundaries isolation can help us with my first tip. It keeps the design under a good separation of concerns and people will know where to find the responsible codes that communicate with another systems.
  • Isolation increases the testability, making our lifes easier when we’re mocking objects in unit testing.
  • Isolation also help us to stub data from broken or unfinished communications. We can stub and simulate the communication request and responses so that our software doesn’t stay broken or prevented. All we have to do is to define a clear contract with the other point. This is extremely helpful when we’re starting new developments and we don’t want to block more than one professional because a communication is not finished yet (e.g: the UI guys cannot be blocked from designing the screens because the broken payment gateway still not making the payments).
There are a lot of concepts and techniques in order to isolate the software’s boundaries, but my favorite is the one defined by Eric Evans, in Domain-Driven Design: Tackling the complexity in the Heart of the Software (2004):

Anti-corruption layer: “[…]a mechanism that translates conceptual objects and actions from one model and protocol to another.”

Therefore, creating a layer responsible for dealing with the other’s side protocol is critical to keep our models untouched and not mixed with other system’s models.

I know there are a lot of content over the web with the practices above, but I wanted to give my words and my thinking about them, because they have been really helpful to me in these days.
That’s all folks, see ya next time.

Dilema: Lazy Loading ou DataContractSerializer? (Post-Aspirina)

Fala pessoal, beleza?

Sensibilizado com os muitos prováveis mortais que vão esbarrar neste problema, resolvi postar um troubleshooting sobre o que aconteceu comigo ontem.

Cenário: Você está usando Entity Framework 4, gerou classes POCO através do modelo conceitual (com ou sem T4), está com Lazy Loading habilitado e quer distribuir estas classes em um serviço WCF.

Após decorar todas as classes e estar aparentemente pronto, tudo começa com uma bela e abrangente exceção do WCF:

“The underlying connection was closed: The connection was closed unexpectedly.”

Se você tiver esperança, como funcionou comigo, vai querer ligar o tracing do WCF. Existem inúmeras formas de configurá-lo, a que eu usei foi simples e good-enough:

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\temp\NomeDoSeuArquivoDeLog.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

Adicione o trecho XML acima no Web.config do seu serviço e tudo estará pronto para começarmos a perseguir o verdadeiro problema. Se você está no mesmo cenário que eu estive e descrevi acima, vai encontrar no SvcTraceViewer.exe a seguinte mensagem da exceção:

“There was an error while trying to serialize parameter http://tempuri.org/:SUA_OPERACAO_AQUI. The InnerException message was ‘Type ‘System.Data.Entity.DynamicProxies.SUA_ENTIDADE_AQUI_7446BE543376C2D0E2C8BCE8BE89AC8659C6C2397A28812EBD37F48756075A0D’ with data contract name ‘SUA_ENTIDADE_AQUI_7446BE543376C2D0E2C8BCE8BE89AC8659C6C2397A28812EBD37F48756075A0D:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies&#8217; is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types – for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.’.  Please see InnerException for more details.”

A exceção acima esclarece bastante coisa. Entre linhas ela nos diz que o DataContractSerializer não sabe fazer resolução dos DynamicProxies gerados pelo Entity Framework (os DynamicProxies existem para que seja possível utilizar o recurso de Lazy Loading). A grosso modo, desabilitamos a criação de proxys do Lazy Loading ou interceptamos a criação do DataContractSerializer.

Opção 1: Desabilitar a criação de proxies para o Lazy-Loading

meuDataContext.ContextOptions.ProxyCreationEnabled = false;

Opção 2: Implementar um OperationBehavior que utilize o DataContractResolver e acioná-lo via atributo (nas operações do contrato do serviço).

  1. Crie um Assemly e referencie System.Data.Entity, System.Runtime.Serialization e System.ServiceModel
  2. Crie uma classe chamada ApplyDataContractResolverAttribute com o seguinte código:
public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior
{
   public ApplyDataContractResolverAttribute()
   {
   }

   public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
   {
   }

   public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
   {
      DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
      description.Behaviors.Find<DataContractSerializerOperationBehavior>();
      dataContractSerializerOperationBehavior.DataContractResolver =
      new ProxyDataContractResolver();
   }

   public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
   {
      DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
      description.Behaviors.Find<DataContractSerializerOperationBehavior>();
      dataContractSerializerOperationBehavior.DataContractResolver =
      new ProxyDataContractResolver();
   }

   public void Validate(OperationDescription description)
   {
      // Do validation.
   }
}

Pronto! Agora compile o assembly, referencie-o no serviço e decore as operações do contrato (em que deseja trafegar POCOs com DynamicProxy):

[ServiceContract]
public partial interface IMyService
{
	// Operação com DynamicProxys do Entity Framework
	[OperationContract]
        	[ApplyDataContractResolver]
	DynamicFooResponse DynamicFoo (DynamicFooRequest request);
	// Operação sem DynamicProxys do Entity Framework
	[OperationContract]
	FooResponse Foo (FooRequest request);
}

Guarde este assembly no seu WCF-Bag-Of-Tricks!  Bom pessoal, existem milhares de artigos sobre este problema (inclusive na MSDN), mas não podia deixar de fazer a versão português-comentada de um problema tão importante quanto este. Até a próxima!  Stay Lazy-Loaded!

Singleton Pattern: The truth behind

Olá galera,

O Singleton é um padrão super popular e muito se deve à sua facilidade de implementação. Entretanto, as implementações que muitos conhecemos e vemos por aí podem ter falhas, principalmente no que diz respeito a sincronismo de Threads. Dependendo do contexto, isso pode se tornar perigoso e quando menos esperamos, o erro está em um Singleton mal implementado. Esse tipo de falha é difícil de identificar em código legado, e aí o padrão simples custa caro.

Vou mostrar algumas formas diferentes de implementar o Singleton, cada uma com seus ganhos e perdas, e como o Rafael Tolotti costuma dizer, “tudo é um trade”. Algumas considerações:

  • Usei sealed em todas as classes para otimizar o JIT, reduzindo custo no dispatching de métodos virtuais (vide artigo sobre Virtual Method Tables e sobre Sealed Classes).
  • Mesmo sem decorar as classes com sealed é importante deixarmos os membros de instância e classe como private. Evita que o princípio do padrão seja quebrado em caso de herança entre classes (sub-classes poderiam instanciar a base-class).

1) Versão “non-thread safe

namespace Singleton.Sample.Implementations
{
    /// <summary>
    /// PS: Keyword "sealed" is used for JIT optimizations
    /// </summary>
    public sealed class Singleton_1_NonThreadSafe
    {
        private static Singleton_1_NonThreadSafe instance = null;

        private Singleton_1_NonThreadSafe() { }

        public static Singleton_1_NonThreadSafe Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Singleton_1_NonThreadSafe();
                }
                return instance;
            }
        }
    }
}

Comentários: Essa é a versão mais simples e popular do Singleton. Entretanto, se duas ou mais Threads caíssem na linha 16 poderíamos ter uma quebra do princípio e várias instâncias seriam criadas. Abordagem recomendada em cenários simplíssimos, onde por prerrogativa não haverá concorrência no acesso à instância Singleton.

2) Versão “Simple Thread-Safe”

namespace Singleton.Sample.Implementations
{
    /// <summary>
    /// PS: Keyword "sealed" is used for JIT optimizations
    /// PS 2: This class uses a critical zone to solve the concurrent memory-barrier issue.
    /// </summary>
    public sealed class Singleton_2_SimpleThreadSafe
    {
        private static Singleton_2_SimpleThreadSafe instance = null;
        private static readonly object syncRoot = new object();

        Singleton_2_SimpleThreadSafe() { }

        public static Singleton_2_SimpleThreadSafe Instance
        {
            get
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new Singleton_2_SimpleThreadSafe();
                    }
                    return instance;
                }
            }
        }
    }
}

Comentários: Versão simples para evitar que duas ou mais threads avaliem a expressão da linha 20 e instanciem o objeto. Para isso é utilizado um objeto imutável de sincronização (cadeado) (criado na linha 10 e trancado na linha 18). Pode apresentar problemas de performance pois um lock é gerenciado toda vez que a instância for acessada.

Obs: Existe uma variação para esta versão que evita que toda vez o lock seja acessado, usando uma condição adicional antes mesmo do lock. Porém ela se torna mais problemática ainda por apresentar brechas em relação ao modelo de gerência de memória do Framework e não sendo tão performática quanto outras implementações.

3) Versão Thread-Safe com Static Constructors e sem cadeados

namespace Singleton.Sample.Implementations
{
    /// <summary>
    /// Static constructor tells the compiler to lazy-load the type-initialization (by NOT marking the class with beforeFieldInit)
    /// and runs only ONCE per AppDomain (what makes it Thread-safe).
    /// </summary>
    public sealed class Singleton_3_ThreadSafeWithoutLock
    {
        private static readonly Singleton_3_ThreadSafeWithoutLock instance = new Singleton_3_ThreadSafeWithoutLock();

        static Singleton_3_ThreadSafeWithoutLock() { }
        private Singleton_3_ThreadSafeWithoutLock() { }

        public Singleton_3_ThreadSafeWithoutLock Instance
        {
            get
            {
                return instance;
            }
        }
    }
}

Comentários: Assim como comentei na classe, o segredo está no Static Constructor. Ano passado eu fiz um post sobre Static Constructors, sugiro que seja lido para melhor entendimento. O Static Constructor vai garantir que a inicialização dos tipos (nesta versão é in-line, de acordo com [09]) seja executada apenas uma vez por AppDomain, e também que as variáveis sejam inicializadas quando o primeiro membro estático da classe for acessado, o que de certa forma, garante o fake-lazy-load (digo “fake” porque se nenhum membro estático for acessado os type-initializers não executarão). Além do ganho de performance com o lazy-loading, o código fica bem “clean” e a menos que queiramos fazer um eager-loading (inicializando a instância dentro do Static Constructor), o Static Constructor deverá ficar vazio.

Clique aqui para baixar a solução de código usada no post.

Galera por hoje é isso vou tentar não sumir tanto do blog hehe.
Abraço!

Compilando Views com o ASP.NET MVC 2

Olá!

Com o lançamento do ASP.NET MVC 2 e o advento dos Html Typed-Helpers, é possível criar elementos HTML baseados em expressões lambdas.

Legal, e o que isso significa?

Podemos selecionar as propriedades do Model a serem ligadas ao controle HTML (da View) como se estivéssemos escrevendo uma função lambda. Com isso ganhamos tipagem e intellisense. E onde há intellisense, há compilação estática.

No ASP.NET MVC 1 isso não era possível, de modo que os Html Helpers trabalhavam com strings (passávamos o nome da propriedade por parâmetro) e as más notícias vinham em tempo de execução: tela amarela do ASP.NET + runtime error. Antes escrevíamos:

<%= Html.TextBox("Name") %>

No MVC 2 fazemos isso com uma expressão lambda, que usamos para selecionar a propriedade do model:

<%= Html.TextBoxFor(modelVar => modelVar.Name) %>

Ao habilitar a compilação das Views, podemos identificar model-bindings errados em caso de alteração das propriedades.

Porém, este novo recurso do MVC 2 não vem habilitado por padrão, é preciso modificar as configurações do projeto MVC. Para tanto, clique com o botão direito em cima do projeto MVC Application e escolha a opção Unload Project, conforme a figura 1:

Agora é possível editar o *.csproj/*.vbproj do projeto sem precisar abri-lo como arquivo pelo VS. Novamente, clique com o botão direito em cima do projeto e vá até “Edit [Nome-do-projeto].csproj”.

O VS abrirá o modo de edição XML do csproj/vbproj, altere o valor do nodo MvcBuildViews para true, salve o arquivo e pronto. Piece of cake.

Agora você já pode dar “Reload Project” e usufruir do recurso de compilação estática das Views. Entretanto, utilize este recurso com cuidado, pois dependendo do tamanho do projeto seu build poderá ficar bem mais lento e a necessidade (ou falta de) de compilar as Views pode não justificar seu uso. Assim como quase tudo em desenvolvimento de software, depende do contexto.

Até mais ver!

Programadores e Exceptions: relação entre tapas e beijos?


Tratar exceções é fácil.

Tão fácil que muitos programadores deixam passar batido ou não têm cautela ao fazer isso.

Aliás, cautela é a palavra chave aqui: ou você é cauteloso ou sai duplicando logs, piorando a responsividade do sistema, dificultando futuras depurações, “engolindo” erros importantes ou gerando muitos side-effects (o que acaba sendo bem comum e traumático).

Como quase tudo, não se trata apenas de frameworks, application blocks ou camadas de infra-estrutura recheadas de configurações e políticas de exception handling. O lance está muito mais nos fatores humanos (as vezes psicológicos): nas boas práticas de quem escreve o código.

E foi pensando nisso que algumas pessoas escreveram sobre esse assunto, inclusive eu.

Primeiro erro, o mais clássico e tentador: silenciar as exceções.

DON’T

 try
 {
     this.FacaAlgoPerigoso();
 }
 catch { }

Há inclusive quem chame isso de silenciator anti-pattern. Se a exceção ocorre, é por algum motivo, e ele precisa ser notificado, ou no mínimo, logado. Logar em um flat file? banco de dados? Event Viewer? Resposta óbvia: depende da necessidade e do contexto. O importante é não deixar que a vida siga sem tratar a exceção.

Para falar a verdade, existem raríssimos casos em que colocar um bloco catch vazio vai lhe conduzir ao sucesso, e trabalhar com políticas de tratamento (e.g: System.ServiceModel.IErrorHandler) onde seu código pode entrar em recursão e gerar StackOverflowException ou OutOfMemoryException pode ser um deles.

Segundo erro: propagar exceções por descargo de consciência.

Se você não sabe o que fazer para tratar exceções, não trate-as.

DON’T

 try
 {
     this.FacaAlgoPerigoso();
 }
 catch (Exception)
 {
     throw;
 }

É feio, redundante, polui o código e não agrega valor ao resultado final.

Terceiro erro: tratar exceções por descargo de consciência.

Parecido com o erro anterior, porém mais crítico, pois pode afetar o resultado final. Imagine que em cada camada da sua aplicação n-tier, onde n > 10, você resolve logar a exceção ou mandar um SMS para o usuário com a mensagem de erro. Além de desperdiçar espaço para log, não parece ser algo user-friendly. Em vez de fazer isso, pergunte-se:

Para evitar este erro comum, além de responder as questões acima, lembre-se:

  • Se você não sabe o que fazer para tratar exceções, não trate-as.
  • D.R.Y (Don’t Repeat Yourself).

Quarto erro: não usar, ou usar errado hierarquia nas exceções.

Caso não possua, crie exceções extremamente específicas a trechos dentro do seu código que poderão gerar erros. Mas quando for tratá-las, nunca trate exceções mais genéricas antes.

DON’T

 IMeuProviderDeAutenticacao provider =
 this.container.Resolve<IMeuProviderDeAutenticacao>();
 try
 {
     bool result = provider.Autenticar(umUsuario,umaSenha);
 }
 catch (Exception)
 {
     // Tratar exceção
     throw;
 }
 catch (UsuarioInexistenteException)
 {
     // Tratar exceção
     throw;
 }
 catch (SenhaInvalidaException)
 {
     // Tratar exceção
     throw;
 }

Esse é um erro básico que muitas vezes não chega a ser provocado, pois não criamos hierarquia para as exceções.

Quinto erro: controlar fluxos de negócio em blocos catch.

Jamais controle fluxos com blocos catch. O código escrito em um catch deve exclusivamente tratar o erro ocorrido, e isso inclui apenas orquestrar toda infra-estrutura utilizada para que o erro seja registrado e devidamente exibido ao usuário. Exceptions não são if statements.

DON’T

 try
 {
     decimal valorFrete = meuPedido.CalcularFrete();
 }
 catch (CEPInvalidoException)
 {
     meuPedido.ResetarFrete();
     IPedidoService service = this.container.Resolve<IPedidoService>();
     service.CancelarPedido(meuPedido);
     OnPropertyChanged("ResetarCarrinho");
 }

Sexto erro: sobrepor informações de uma exceção (throw; vs throw ex; ).

Quase imperceptível. No .NET, toda vez que um código usa throw ex; a exceção tem seu stacktrace sobre-escrito e a linha inicial do erro passa a ser a que contém a cláusula throw ex;. Isso dificulta muito a depuração (para aqueles que não usam TDD 🙂), pois a sensação que temos é que a história não nos foi contada por completo, ou pelo menos alguns passos foram pulados.

Aprendi com meu colega de trabalho Tiago Dondé que a solução mais simples para isso é usar throw; :-). Existem inúmeros artigos falando desse truque, o mais sucinto e famoso – com um código bem fácil de entender – é o do Oleg Tkachenko.

Estes erros que cometemos ao tratar exceções, assim como muitos outros, já foram identificados e escritos em outros blogs e artigos. Eu apenas condensei os mais importantes por já ter tido experiências em que a boa prática (ou falta de) tenha influenciado bastante na performance do software e na produtividade em correção de bugs (principalmente).

Fica uma lista de referências:

http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx – Apesar de antigo e desatualizado, contém muitas dicas e code-samples para tratar exceções, principalmente em sistemas concorrentes.

http://www.codedwarf.com/cs.html – Pequena lista de convenções de C#, que inclui tratamento de exceções.

http://msdn.microsoft.com/en-us/library/seyhszts.aspx – Dicas do MSDN para tratamento de exceções, principalmente na customização de exceções.

O importante é que com cautela e um pouco de estudo, códigos que tratam exceções sejam eficazes e evitem futuros desastres. Evitem, mas não impeçam.

Padrão MVVM para aplicações Silverlight e WPF – Parte 1

Olá pessoal!

Após um intervalo de tempo bem grande (suficiente para terminar minha graduação e descansar um pouco), voltei a postar aqui no blog :-). E com prazer, pois neste post voltarei a tratar um assunto que não mexia a algum tempo: Silverlight.

Porém, o foco não é falar sobre as novidades do Silverlight 4, nem como podemos desenvolver aplicações financeiras ou de entretenimento para Windows Phone 7 utilizando essa plataforma RIA. Afinal, para isso recomendo os vídeos do MIX 2010 (como este overview) ou o excelente material do Channel 9.

Falarei sobre um padrão arquitetural de apresentação bem específico ao WPF e Silverlight: o MVVM (Model-View-ViewModel).

O MVVM nasceu da necessidade de separarmos as responsabilidades na camada de apresentação, facilitando a vida da equipe de design gráfico com a redução de impactos nas alterações das Views e aumentando a testabilidade do sistema, por possuir naturalmente o domínio desacoplado da lógica de visualização.

O modelo de desenvolvimento de RIAs proposto pela Microsoft compreende na colaboração entre dois tipos de equipe: designers e desenvolvedores. Com o advento do Expression Blend e das APIs de desenvolvimento WPF e Silverlight para .NET 3, 3.5 e 4, isto passou a ser possível de uma forma bem menos traumática e integrada. Mas o mercado exigia mais.

E aí entra o MVVM. Pense na idéia de isolar os designs das telas de qualquer fator de infra-estrutura, comunicação externa ou alguma dependência que impeça a continuidade dos layouts. Imagine que enquanto essas telas são feitas sua equipe de desenvolvimento pode projetar e desenvolver o domínio do sistema, onde a coisa pega e geralmente mora toda a complexidade do seu software, linhas e mais linhas de LoB, controle transacional orientado a aspectos, specifications, DSLs e toda aquela tropa. Você não vai querer isso no meio dos seus bindings, conversões e validações do WPF, vai?

Some isso ao fato de você poder testar seu domínio sem se preocupar com escrever longos testes de integração e UI automation, que permeiam desde os code-behinds de seus XAML até suas classes de mapeamento relacional.

A idéia aqui é testar “a cola entre os dois mundos”, que por sinal se chama “ViewModel” (mundialmente conhecida e batizada pelo Fowler como Presentation Model). MVVM é só um nome bacana para aplicações que trabalham com marcações XAML. Tudo começou neste post do John Grossman, lá no início da era WPF & Silverlight.

Para falar a verdade, o MVVM se distingue do resto da família (MVC, MVP, Presentation Model, Mxxx …) por fatores tecnológicos bem específicos, como:

  • Uso dos DataBinds bi-direcionais e a interface INotifyPropertyChanged (do namespace System.ComponentModel) para disparar alterações nos modelos de visualização (a.k.a ViewModels).
  • Conversão e formatação de valores através dos Converters (interface IValueConverter no System.Windows.Data).
  • Validação de valores integradas ao modelo de DataBinding da plataforma (ValidatesOnDataErrors = True) e ao Validation Application Block (da Enterprise Library).
  • Modelo de eventos utilizando a interface ICommand do namespace System.Windows.Input.

Para mais informações, o Channel 9 possui um vídeo bem curto e interessante sobre o funcionamento do MVVM, mas vou comentar os elementos do MVVM apresentando um framework auxiliar. Por falar em frameworks, existe um link interessante com uma lista dos principais toolkits que ajudam na implementação do MVVM. Praticamente todo desenvolvedor que trabalha com este padrão possui uma coleção de classes bases, interfaces e templates para geração de código que aumentam o reuso e produtividade.

Nos exemplos que colocarei aqui, utilizarei o MVVM Light Toolkit, ele é bem simples, de fácil instalação (basta descompactar os arquivos na pasta de templates do Visual Studio) é compatível com as últimas versões do Silverlight e WPF e até onde usei, não me causou incomodações.

Após descompactar o template, crie um projeto Silverlight com o template do Light Toolkit:

Na figura acima, o projeto da esquerda contém exatamente a estrutura que o MVVM Light Toolkit gera ao criarmos um projeto. Já a figura da direita é a estrutura final de um cenário de Master-Detail utilizando MVVM, que será mostrado na parte final desta série.

Em uma leitura top-down do solution-explorer, ao expandirmos a pasta “References” veremos dois binários do Light Toolkit: Galasoft.MvvmLight.dll e Galasoft.MvvmLight.Extras.dll. São as bibliotecas que contém suporte para operações básicas de ViewModels, comandos genéricos, thread-handling, janelas de mensagens, notificações de propriedades alteradas, etc.

  • Models: O template gera uma pasta chamada “Models“, como o ASP.NET MVC Framework e o Ruby on Rails, onde geralmente são criadas classes que representam os limites do domínio da aplicação, como Application Services [1][2], objetos que realizam orquestração de fluxos (e.g: Transaction Scripts), classes de acesso relacional ou até mesmo entidades de negócio. A título de simplicidade, no exemplo do Master-Detail coloquei as entidades (Jogador e TimeFutebol) direto nesta pasta, mas o comum é que isto seja feito em assemblies separados.
  • Skins: pasta para colocarmos os “Skins” da aplicação, que básicamente são arquivos XAML com dicionários de recursos gráficos (e.g: animações, estilos, fontes, imagens) que podem ser compartilhados por toda aplicação.
  • ViewModel: onde grande parte da mágica acontece. Nesta pasta vão todas as “classes-cola” entre o mundo de design (Views) e desenvolvimento (Models). São abstrações que encapsulam todas informações e comportamentos que as Views necessitam e possuem, servindo como DataContext das mesmas. É nas ViewModels que iremos encontrar tratadores de comandos, propriedades auto-calculadas das Views (e.g: o título de uma aba de emails não lidos), propriedades utilizadas para fazer binding na tela (e.g: lista de clientes para ser exibida em uma ComboBox), estados de controles, etc. Por possuírem alto nível de acoplamento com outras camadas (View e Model) quase sempre as ViewModels são projetadas com interfaces e injetadas por containers de IoC. O MVVM LightToolkit resolve a inversão de controle nas ViewModels utilizando Service Locator, que é o motivo da classe ViewModelLocator ser criada junto com o projeto.
  • ViewModelLocator (opcional): implementação do Service Locator pattern. Conhece e gerencia o ciclo de vida de todas ViewModels do sistema. É declarada nos recursos da aplicação (dentro do App.xaml), para que todas as telas (Views) possam referenciá-la e obter o contexto dos dados. Uma forma bem simples de simular um container de implementações :-).

O template ainda cria uma MainPage.xaml referenciando sua respectiva ViewModel, cujos bindings, validadores e conversores veremos no próximo post, com exemplos de código e mais explicações sobre o modelo de interação do MVVM :-).

Referências:

[1] http://dddsample.sourceforge.net/characterization.html
[2] http://martinfowler.com/eaaCatalog/serviceLayer.html

[]z

Microsoft Application Architecture Guide 2nd Edition


Olá pessoal

Neste final de semestre a única coisa que consegui postar aqui é sobre o lançamento do livro de arquitetura do patterns & practice, que foi no dia 04 de novembro.

Pra quem não conhece, é um e-book sobre arquitetura de aplicações utilizando .NET e Enterprise Library, disponibilizado gratuítamente em PDF pela Microsoft Press (mas que pode ser comprado como livro na Amazon).

O livro é dividido em várias seções, desde introdução à arquitetura de software até capítulos bem específicos, como camada de visualização, camada de negócio, camada de acesso à dados, arquitetura de aplicações RIA (e.g: Silverlight), arquitetura de aplicações Web (inclusive ASP.NET MVC!), arquitetura com serviços WCF, etc.

Pelo que notei de diferente da versão anterior, olhando por cima, aplicações SharePoint e WorkFlow agora ganharam um capítulo específico. E pra finalizar, assim como na versão anterior, um capítulo inteiro dedicado à Enterprise Library 4.1 🙂

Ainda não li, e estou longe de ler (prioridades a frente), mas creio que possa ser uma fonte inicial interessante pra quem não tem muita experiência com arquitetura utilizando .NET.

Se alguém já leu (ou está lendo) e quiser me dar o feedback, seria bem interessante!

Alguns links:

Forewords sobre o livro
MSDN
CodePlex
Amazon

Link direto para download no MSDN

Static Constructors – Mito ou realidade?

Se tem uma coisa que as pessoas que trabalham com C# pouco conhecem e utilizam, podem apostar, são Static Constructors.

E sinceramente, eu demorei bastante para saber de sua existência. Estava pesquisando sobre corretas implementações do Singleton Pattern e em uma delas, me flagrei necessitado a usar um Static Constructor.

Portanto, antes de falar sobre Singleton aqui, achei melhor dedicar um post exclusivo para os construtores estáticos.

Em sua essência, Static Constructors têm como principal objetivo inicializar os membros estáticos de uma classe antes que:

  • Qualquer instância desta classe seja criada; ou
  • Qualquer membro estático seja referenciado dentro do application domain.

Isso nos dá um recurso poderoso de inicialização centralizada dos membros estáticos ou uma opção caso queiramos executar alguma ação de setup da classe apenas uma vez por AppDomain (o que pode garantir thread-safe nas soluções em que for usado).

Mas para alguns isso pode soar estranho, afinal C#, assim como a maioria das linguagens OOP atuais, possui o recurso de type initialization. Deste modo, é comum encontrarmos trechos de código como:

class Program
{
       static int count = 1000
}

Porém, é possível ainda que a mesma variável count seja inicializada desta forma:

class Program
{
       static int count;
       static Program()
       {
              count = 1000;
       }
}

De acordo com a especificação do C# (ECMA 334), existem algumas regras básicas para usar Static Constructors:

  • Só pode existir um StaticConstructor por classe.
  • O Static Constructor não pode possuir parâmetros.
  • O Static Constructor somente pode acessar membros estáticos da classe.
  • O Static Constructor não pode ter modificador de acesso.

Superadas essas limitações, por que utilizar Static Constructors e não type-initializers?

Vamos supor que na classe Program exista um método que utilize a variável estática count.

Ao NÃO escrevermos um construtor estático, o compilador do C# marcará a classe com o atributo beforeFieldInit.

E o que isso quer dizer?

Conforme o ECMA do CLI, beforeFieldInit specifies that calling static methods of the type does not force the system to initialize the type.”.

Em outras palavras, não é garantido a inicialização da variável ao acessar o método dependente, e sim ao primeiro acesso de uma variável do mesmo tipo (int no caso).

Se a classe possuir construtor estático, o compilador não decorará a classe com beforeFieldInit, nos garantindo que as variáveis estejam inicializadas:

  • Antes do primeiro acesso a qualquer campo estático ou de instância; ou
  • Antes da primeira invocação para qualquer método estático, de instância ou virtual.

Isso soluciona alguns problemas de inicialização de recursos, incluindo os campos estáticos utilizados na sincronização de Singleton Patterns (que veremos no próximo post!)

Além de centralizar a inicialização de membros estáticos, os construtores estáticos nos garantem a inicialização dos tipos antes de qualquer utilização dependente posterior, evitando exceções com type-initializers.

Até a próxima, espero poder ter tempo pra postar em breve!