Alfred's profileHow Things (Should) WorkPhotosBlogListsMore Tools Help

Blog


    6/17/2009

    Pau que nasce torto não cresce direito

     

    Uma prática bastante comum no desenvolvimento de sistemas é o que eu chamo de CPOP [1]- “Copy & Paste Oriented Programming”.

    A prática é bastante utilizada, pois fornece um template inicial a partir da qual o módulo sendo trabalhado é rapidamente reproduzido e adaptado. Com isto economiza-se tempo no desenvolvimento.

    Por conta CPOP, é de suma importância que o modelo original tenha a melhor qualidade possível.

    Vamos pegar um exemplo: O “Guia do Desenvolvimento” de um determinado projeto em que trabalhei que dava o seguinte modelo para a implementação das classes na camada de acesso a dados.

    Friend Class AD_GrupoSerie

     

        Private Sub New()

        End Sub

     

        Public Shared Function Construtor(ByVal reader As IDataRecord) As EN_GrupoSerie

     

            If reader Is Nothing Then

                Throw New ArgumentNullException("reader")

            End If

     

            ' Obtém posição dos campos no data reader

            Dim iGrupoSerieIdx As Integer = reader.GetOrdinal("COD_GRUPO_SERIE")

            Dim iNomGrupoSerieIdx As Integer = reader.GetOrdinal("NOM_GRUPO_SERIE")

     

            ' Cria objeto da entidade de negócio

            Dim objGrupoSerie As EN_GrupoSerie = New EN_GrupoSerie()

     

            ' Alimenta propriedades da entidade de negócio

            objGrupoSerie.Codigo = reader.GetInt32(iGrupoSerieIdx)

     

            ' Para campo que pode ser nulo, é necessário atribuir valor default.

            If Not reader.IsDBNull(iNomGrupoSerieIdx) Then

                objGrupoSerie.Nome = reader.GetString(iNomGrupoSerieIdx)

            Else

                objGrupoSerie.Nome = String.Empty

            End If

     

            ' Retorna objeto que representa a entidade de negócio

            Return objGrupoSerie

     

        End Function

     

    End Class

     

    O código tem uma coisa legal que é a validação do parâmetro de entrada “reader” (isto é menos comum no código deste projeto do que deveria ser), mas o código tem oportunidades de melhoria tanto quando olhado isoladamente quando olhada no contexto em que o método é usado.

    DMTCRI[2]

    Primeiro vamos ao problema que considero mais relevante que é o contexto onde o método é usado: Este método é chamado pelo método AD_GrupoSerie_Acao.Selecionar dentro de um loop - uma vez para cada registro retornado do banco de dados.

    Public Class AD_GrupoSerie_Acao

        Public Function Selecionar(ByVal strNome As String) As List(Of EN_GrupoSerie)

     

            Dim resultado As List(Of EN_GrupoSerie) = New List(Of EN_GrupoSerie)()

     

            Dim db As Database = DatabaseFactory.CreateDatabase(strDBNome)

     

            If db Is Nothing Then

                Throw New ArgumentNullException("db")

            End If

     

            Dim command As DbCommand = db.GetStoredProcCommand("dbo.SPPJ_SELECIONAR_GRUPOSERIE")

     

            ' Alimenta parâmetros da pesquisa

            db.AddInParameter(command, "P_NOM_GRUPOSERIE", DbType.String, strNome)

     

            Dim rdr As IDataReader = db.ExecuteReader(command)

     

            While rdr.Read()

                resultado.Add(AD_GrupoSerie.Construtor(rdr))

            End While

     

            Return resultado

     

        End Function

     

    End Class

     

    Acontece que parte das operações realizadas dentro do método Construtor avaliam coisas que são imutáveis durante o tempo de vida do loop.

    Uma vez que o código entre no loop, reader nunca será Nothing e a posição das colunas nunca vai mudar. A gente está simplesmente fazendo o código repetir a se mesmo. Podemos evitar isto movendo o código que trata destas duas coisas para fora do loop.

    Friend Class AD_GrupoSerie

        Private reader As IDataRecord

        Private iGrupoSerieIdx As Integer

        Private iNomGrupoSerieIdx As Integer

        Private iIndAtivoIdx As Integer

     

        Public Sub New(ByVal reader As IDataRecord)

            If reader Is Nothing Then

                Throw New ArgumentNullException("reader")

            End If

            Me.reader = reader

     

            ' Obtém posição dos campos no data reader

            iGrupoSerieIdx = reader.GetOrdinal("COD_GRUPO_SERIE")

            iNomGrupoSerieIdx = reader.GetOrdinal("NOM_GRUPO_SERIE")

            iIndAtivoIdx = reader.GetOrdinal("IND_ATIVO")

        End Sub

     

        Public Function Construir() As EN_GrupoSerie

            ' Cria objeto da entidade de negócio

            Dim objGrupoSerie As EN_GrupoSerie = New EN_GrupoSerie()

     

            ' Alimenta propriedades da entidade de negócio

            objGrupoSerie.Codigo = reader.GetInt32(iGrupoSerieIdx)

     

            ' Para campo que pode ser nulo, é necessário atribuir valor

            If Not reader.IsDBNull(iNomGrupoSerieIdx) Then

                objGrupoSerie.Nome = reader.GetString(iNomGrupoSerieIdx)

                objGrupoSerie.IndAtivo = reader.GetBoolean(iIndAtivoIdx)

            Else

                objGrupoSerie.Nome = String.Empty

            End If

     

            ' Retorna objeto que representa a entidade de negócio

            Return objGrupoSerie

        End Function

    End Class

     

        Public Function Selecionar(ByVal strNome As String, ByVal iAtivo As Integer) As List(Of EN_GrupoSerie)

            Dim db As Database = DatabaseFactory.CreateDatabase(strDBNome)

     

            Using command As DbCommand = db.GetStoredProcCommand("dbo.SPPJ_SEL_GRUPO_SERIE")

                db.AddInParameter(command, "P_NOM_GRUPOSERIE", DbType.String, strNome)

                db.AddInParameter(command, "P_IND_ATIVO", DbType.Int32, iAtivo)

     

                Dim resultado As List(Of EN_GrupoSerie) = New List(Of EN_GrupoSerie)()

                Using reader As IDataReader = db.ExecuteReader(command)

                    Dim factory As New AD_GrupoSerie(reader)

                    While reader.Read()

                        resultado.Add(factory.Construir())

                    End While

                End Using

                Return resultado

            End Using

        End Function

    As operações foram movidas para o construtor de AD_GrupoSerie que está fora do loop em AD_GrupoSerie_Acao.Selecionar e com isto não se tem o custo de verificação do parâmetro por nulo e a localização da posição das colunas para cada linha do resultset.

    Dado ao fato do pessoal do projeto usar CPOP a torto e a direito, o mesmo erro foi replicado em dezenas de locais diferentes. Sair consertando tudo é inviável financeiramente, então é importante revisar no detalhe qualquer código que possa vir a ser utilizado como original (template) para o CPOP.


    [1] Ao procurar o verbete para DRY no Wikipedia, eu acabei encontrando uma entrada para “Copy and paste programing” que trata justamente do que eu vinha chamando de CPOP – Copy & Paste Oriented Programming. Eu ainda acho CPOP mais legal por conta da alusão a OOP.

    Por falar em OOP, a idéia não é fazer uma apologia ao CPOP. Se o cenário permitir, DRY nele!

    [2] DMTCRI - Don’t Make The Code Repeat Itself é uma alusão a DRY – Don’t Repeat Yourself, uma filosofia de programação que prega a redução da duplicação de código. Aqui a idéia que quero passar é a de se evitar fazer com que o programa execute repetidas vezes operações que sempre trarão os mesmos resultados.

    2/18/2009

    We need a tool that combines functionality of xsd.exe and sgen.exe

    I added a suggestion on Microsoft Connect asking for something with the combined functionality of xsd.exe and sgen.exe.

    Given an xml schema file (xsd), you could use xsd.exe to generate a set of classes that could be serialized in conformance with that schema.

    Then to perf things up a little bit, you could use sgen.exe to create an assembly containing specialized serializers for the classes generated previously.

    You would end up with two assemblies for something that, in my opinion, would be better handled with one. For instance, with only one assembly there would be no risks of mismatching versions of the Serializable and Serializer assemblies.

    You can work around having an extra assembly using sgen’s “/k” option which keeps on your project’s folder the temporary files used to create the serializer assembly. Among those files, there’s one with the source code.

    There are some caveats though:

    First, sgen only generates code in C#. If your project is in Visual Basic, then you have to take some extra steps to integrate the code into your code base.

    Second, each time you run sgen, it creates a new file with a random name. You’ll have to rename it to something that’s stable enough to be used in your project. This can be done with some pre or post build events, but things can eventually get wrong.

     

    If you feel my pain, please vote on:

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=416020

    2/16/2009

    TF26212: Team Foundation Server could not save your changes.

    I created a new WIT (work item type) to track progress of a set of activities we have here. Let’s call it “Setup”.

    I wanted to restrict the users that create a new instance of the work item. The way to do this in TFS is to put a restriction on the state transition from “” to the first state of your workflow: “FirstStep” in our case.

    To make things easier, I gave the group the same name of the WIT: “Setup”.

    So I ended with something along the following lines:

    <?xml version="1.0" encoding="utf-8"?>

    <witd:WITD application="Work item type editor" version="1.0" xmlns:witd="http://schemas.microsoft.com/VisualStudio/2005/workitemtracking/typedef">

      <WORKITEMTYPE name="Setup">

        <WORKFLOW>

          <STATES />

          <TRANSITIONS>

            <TRANSITION from="" to="FirstStep" for="[project]\Setup" />

          </TRANSITIONS>

        </WORKFLOW>

      </WORKITEMTYPE>

    </witd:WITD>

     

    The problem is that when I tried to save a new instance of the work item, I received the following message from TFS:

    TF26212: Team Foundation Server could not save your changes. There may be problems with the work item type definition. Try again or contact your Team Foundation Server administrator.

    That really doesn’t help…

    After some research I found a blog post with a solution to the problem.

    The problem is you should not have a WIT with the same name of a TFS group in whatever Team Projects you have.

    2/11/2009

    You probably shouldn’t be using ReDim Preserve inside a loop

    These days I was doing a code review when I went across a method which contained a ReDim Preserve inside a loop.

    I can’t show the real code because it is from a customer’s code base, but here’s a simplification of what I found:

        Sub CopyAndPasteOrientedProgramming()

            Dim c As New Customer()

            For i As Integer = 0 To 250000

                ReDim Preserve c.Orders(c.Orders.Length + 1)

                c.Orders(c.Orders.Length - 1) = New Order()

            Next

            Console.WriteLine(c.Orders.Length)

        End Sub

     

    I found the developer who checked in the code and went on to tell him to use a List(Of Order) and he replied “Oh, don’t bother with that. It’s just a piece of code that I copied from a similar class and since it doesn’t have a business rule for adding the elements, I took off the If statement.

    Wait a minute, I said. You’re telling me there’s more code like this scattered throughout the code base?

    Yup, he said.

    So to simplify, the business rule I’ll use will be the order being a multiple of 3:

        Sub ShowRedim()

            Dim c As New Customer()

            For i As Integer = 0 To 250000

                If i Mod 3 = 0 Then

                    ReDim Preserve c.Orders(c.Orders.Length + 1)

                    c.Orders(c.Orders.Length - 1) = New Order()

                End If

            Next

            Console.WriteLine(c.Orders.Length)

        End Sub

     

    The problem with the code is that for each iteration of the loop, a new array will be created with one more element than earlier and the previous array will be copied into the new one. Yeap… It’s going to create 250,000 arrays on the first sample and 83,334 on the second. Poor Garbage Collector!

    A smarter decision would be to use a generic List. If you don’t initialize its capacity, it’ll default to 16 when you add the first element. Then it will double in size each time it reaches its capacity. I’m too lazy to do the math but I guarantee you that it’s far less than the previous example.

        Sub ShowList()

            Dim c As New Customer()

            Dim o As New List(Of Order)

            For i As Integer = 0 To 250000

                If i Mod 3 = 0 Then

                    o.Add(New Order)

                End If

            Next

            c.Orders = o.ToArray()

            Console.WriteLine(c.Orders.Length)

        End Sub

     

    This is a very simple alternative. If you really want to be clever and you have an idea of the percentage of orders that will fulfill the criteria, you can initialize the List with a meaningful capacity.

    So please stop using ReDim Preserve inside loops!!!

     

     

    PS. List(Of T).ToArray() creates a new array, but when compared with the original code that doesn’t hurt, does it?

    TS: Visual Studio 2008 Team Foundation Server

    I've been working a lot with TFS lately and I knew there was an exam for TFS 2005 (70-510 -> TS: Visual Studio 2005 Team Foundation Server) but I wasn't sure if there was one for TFS 2008.
    It looks like there won't be one since there were few changes besides those found in Team Build in 2008.
    2/10/2009

    Warnings TF26171 and TF26204 during WIT import on TFS 2005

    When restricting the users or groups that can transition states of a work item type, there’s a little something you should pay attention to.

    Lets say you want to restrict who can create a given type of work item to users of a custom “NewTesters” TFS Group. The docs says you should do something as follows:

    <TRANSITION from="Resolved" to="Complete" for="[project]\AllTesters" not="[project]\NewTesters">
    </TRANSITION>

    On the “for” attribute some people may think that “[project]” is a place holder for the project's name, but it is meant as a literal.

    If your Team Project is named TheGreatestProjectEver, you should use "[project]\AllTesters" literally as stated in documentation and not " TheGreatestProjectEver \AllTesters"

    Using "TheGreatestProjectEver \AllTesters" will return:

    “Warning: TF26171: (User/group {0} is not found.

    TF26204: The account you entered is not recognized. Contact your Team Foundation Server administrator to add your account.”

    2/9/2009

    Book on MSBuild and TF Build

      
     
     
    Adding to my wish list at Amazon.
    2/7/2009

    TeamBuildTypes and Source Control Restructuring Gotcha

    As part of implementing branching for the project I’m currently working on, I had to do some restructuring of the source control folder structure.

    The structure was generally well organized except for the fact they didn’t take branching into consideration when setting up the folder structure:

    $

    • Project
      • AnalysisServices
      • Assemblies
      • DatabaseObjects
      • IntegrationScripts
      • Models
      • OldLabBranch
      • TeamBuildTypes
      • Etc.

    I wanted to create a branch in where AnalysisServices, Assemblies, DatabaseObjects and IntegrationScripts could be isolated in conjunction so new feature development could be done in parallel with regular maintenance without one breaking the other.

    Using the branching guidelines I’ve talked a couple of posts ago, I managed to structure the folders as below:

    $

    • Project
      • OldLabBranch
      • Main
        • Sources
          • AnalysisServices
          • Assemblies
          • DatabaseObjects
          • IntegrationScripts
        • TeamBuildTypes
      • Models
      • Etc.

    The problem with this setting is that your Team Build Types won’t show up in Team Explorer 2005 because it has a dependency of TeamBuildTypes being a direct child of your Team Project’s folder. Moving back TeamBuildType to $/Project did the trick and everything worked fine.

    $

    • Project
      • OldLabBranch
      • Main
        • Sources
          • AnalysisServices
          • Assemblies
          • DatabaseObjects
          • IntegrationScripts
      • Models
      • TeamBuildTypes
      • Etc.

    When we upgrade to TFS 2008, I’ll move back TeamBuildTypes to the place recommended by the guidelines as they really do make sense.

    2/5/2009

    Some of the properties associated with the solution could not be read

    There are times when loading a solution in Visual Studio 2005 you get a “Some of the properties associated with the solution could not be read” but the solution is nonetheless loaded.

    There’s a KB about it, but the problem we had here had nothing to do to what’s being described on the article.

    The problem lays on the fact that for some reason, the TFS source control section of the solution file got duplicated and there were multiple instances of it:

    GlobalSection(TeamFoundationVersionControl) = preSolution

    ….

    EndGlobalSection

     

    To fix the problem:

    1. Unbind the solution from source control
    2. Open the .sln with Notepad and make sure you delete all of the “GlobalSection(TeamFoundationVersionControl) = preSolution” sections from the file.
    3. Bind the solution to source control again.

    With that, Visual Studio will recreate the section properly and you should stop receiving the message.

    1/28/2009

    Branching and Merging

    This week I’m taking a look into branching and merging strategies in TFS.

    VSTS Rangers and MVPs have released guidance for both TFS 2005 and 2008.

    Even if you’re using 2005, if you want to dig into a little more details, you should take a look into the 2005 version of the guidance.

    Microsoft Team Foundation Server Branching Guidance – Home (for TFS 2005)

    TFS Branching Guide 2.0 – Home (for TFS 2008)

    And by the way, yesterday I ordered Juan-Luc’s Professional Team Foundation Server from Amazon. It should arrive in two or three weeks.

    1/24/2009

    TFS Podcast

    Recently I’ve been doing some stuff with TFS so I added TFS Radio to the set of podcasts I hear regularly.

    http://www.radiotfs.com/

    1/15/2009

    Running away from Windows Vista

    With the launch of Windows 7 beta, a couple of my Messenger buddies have started putting “Running Windows 7” as their quick message. I think I’ll put “Running away from Windows Vista” as mine. :P

    Just kidding. Despite all the bad press about Windows Vista, I’ve been using it on a daily basis for almost a year now on a desktop at home and a laptop at work. In both cases, the machines came with Vista pre installed and work fine.

    My desktop at the customers site is still XP as is an old desktop that I have at home. I also have a personal laptop with XP whose hard drive crashed last week. I’m thinking on installing the Windows 7 bits on it to take a spin.

    Stay tuned.

    1/3/2009

    Resoluções de 2009

    Uma das minhas resoluções de 2009 é praticar mais esportes.

    Em 2008 eu já vinha praticando moutain bike e caminhada(mais)/corrida(menos).

    Em 2009 espero não passar tanto tempo sem praticar estes dois esportes e quem sabe arrumar alguma outra coisa pra fazer.

    No dia 31 eu corri a São Silvestre. Sim eu corri! Corri sem parar os quatro primeiros quilômetros, mas corri.

    O resto eu alternei entre caminhada (mais) e corrida (menos), mas completei a prova e senti que tinha energia para ter exigido mais de mim mesmo correndo mais e caminhando menos.

     

     

     

    Minha meta atual é conseguir completar 5K correndo direto. Depois disto a meta passa ser baixar os tempos de 5K e começar a tentar completar 10K diretos. Quem sabe no final do ano eu consigo completar a São Silvestre correndo direto?

     

      

    12/7/2008

    Podcasts on iPod

    Recently my 2nd generation iPod Nano got broken and after a little research at Apple’s site I decided to buy an iPod Touch.

    I went to a store here in Brazil and bought one only to discover that it was a 1st generation iPod Touch while the one shown on Apple’s site was a 2nd generation one.

    The 2nd generation iPod has some features I really wanted so I asked for a friend to bring me one from the US:

    • Built-in sensor for Nike+
    • Hardware buttons for volume
    • Speaker

    By the way, it also has a faster ARM processor.

     

     

    Before getting the new toy, I used to automatically download audio podcasts via iTunes. I also used to manually download videos from Channel 9 to watch on my desktop. Now I setup iTunes to download automatically all the audio and video podcasts I’m interested in. Here are some of the technical ones:

     

    Title

    Description

    Alt.NET Podcast

    Alt.NET Podcast about TDD, BDD, DDD, DI, IoC, and other acronyms

    Channel 10

    [Channel 10]

    Google Developer Podcast

    The Google Developer Podcast features interesting news in the developer world from a Google perspective. Listen to interviews with Google Developers and the community as a whole.

    Hanselminutes

    Hanselminutes is a weekly audio talk show with noted web developer and technologist Scott Hanselman and hosted by Carl Franklin. Scott discusses utilities and tools, gives practical how-to advice, and discusses ASP.NET or Windows issues and workarounds

    .NET Rocks!

    .NET Rocks! is an Internet Audio Talk Show for Microsoft .NET Developers.

    OnMicrosoft (Video)

    Conversations & tips from expert IT Pro’s & Developers covering a wide range of programming, systems, & software issues: .NET Framework, WCF, WPF, ASP.NET  AJAX, Silverlight, PowerShell, VSTS, VSTO, LIN, SQL Server, Data-binding, and SharePoint.

    OnSoftweare (Audio + Video)

    Conversations & tips from the industry’s leading developers across a wide range of programming and development topics: Java, Agile, Software Engineering, Design Patterns, C++, C#, Ruby, Lean, Software Quality, Secure Coding, User-centric Design, and more.

    Videos – Channel 9

    videos

    Descriptions were taken from the feeds themselves. That’s why Channel 9 and 10 aren’t so descriptive.

    11/7/2008

    Fantastic Four

    To celebrate the announcement of .NET Framework 4.0, here are four links to stuff I found interesting enough to share with you guys:

    1. .NET 4.0's game-changing feature? Maybe contracts...
    2. What's New in the BCL in .NET 4.0
    3. Code Contracts - Make Coding Assumptions Explicit and Tool Discoverable in .NET
    4. Microsoft Solver Foundation - Customer Technology Preview

    The main point being that it looks like we’re going to gain Design by Contract (pre-conditions, pos-conditions, etc.) features in the next version of the framework.

    Although there are people not very happy about it being a feature of the framework library instead of the language, I’d like to remember that it is totally possible that in the future, the language incorporates syntax sugar that beneath uses the library’s features.

    LINQ, “using”, “lock” all use .NET Framework class library methods under the covers, so there’s still hope! If today we have “int?” as a shorthand for Nullable<int>, how cool would it be to have something like “Customer!” for a non-nullable Customer parameter, field or variable!

    Most of this design by contract stuff is based on ideas from Spec# – a research language developed by Microsoft Research.

    11/1/2008

    Poster do .NET Framework 4.0

    Durante o PDC que rolou lá nos “States” esta semana, a Microsoft liberou a primeira versão preliminar pública do .NET Framework 4.0, Visual Studio 2010 e os planos sobre um monte de outras coisas como o Windows Azure, Windows 7 e por aí vai.

    Eu já estou com a minha VM do VSTS 2010 aqui, mas ainda não tive tempo de mexer muito com ele.

    A primeira coisa que percebi foi que a Start Page parece ser feita com WPF. Estou bastante curioso para ver o que vem no C# 4.0.

    Eles também lançaram um poster sobre as novidades que vieram com a SP1 do Fx 3.5 e o que deve vir no 4.0.

    Você encontra uma versão online usando Deep Zoom aqui.

    Tem um monte de vídeos a respeito disto tudo lá no Channel 9 .

    Bem legal!

    9/21/2008

    TechEd 2008

    O TechEd está chegando aí (14 a 16/10) e contará com a presença de ninguém mais ninguém menos que Steve (Developers! Developers! Developers!) Balmer.

    Os preparativos já estão a toda. Este ano estarei ministrando duas palestras:

    1. DEV301 - 300- 14/10/2008 14:00 - 15:15 - Sala 2 Melhores Práticas com a Linguagem C# 3.0
    2. WEB301 - 300 - 15/10/2008 09:15 - 10:30 - Sala 7 Internet Explorer 8 Para Desenvolvedores (junto com Miguel Ferreira)

    Na palestra “Melhores Práticas com a Linguagem C# 3.0”, eu vou demonstrar os recursos que a linguagem ganhou na versão 3.0 e a melhor forma de usá-los. Também pretendo abordar os principais erros e gotchas que tenho encontrado por aí ao desenvolver o meu código e revisar código dos outros.

    Na palestra “Internet Explorer 8 Para Desenvolvedores” eu e o Miguel Ferreira (PM do Windows) vamos mostrar o que o IE8 está trazendo de novidade para os desenvolvedores.

    Além disto, estarei respondendo a perguntas no Ask The Experts. Para quem nunca participou de uma sessão destas, é uma chance de ter as suas dúvidas respondidas ali ao vivo e a cores. Imagina como um Fórum MSDN tête-à-tête. Imperdível!

    9/6/2008

    Object creation with generics

    Last week I was reviewing some code when I came across something that looked like.

    class TypeTranslator<TOrigin, TDestination> {
        public TDestination Convert(TOrigin value) {
            Type typeOfTo = typeof(TDestination);
            TDestination to = (TDestination)typeOfTo.InvokeMember(null, BindingFlags.CreateInstance, null, null, null, CultureInfo.CurrentCulture);

            // goes on and copies the contents of each property from the TFrom object instance to the TTo object instance
            return to;
        }
    }

     

    The idea is to translate entity types to data transfer types. The class receives the origin and destination types upon instantiation and when Convert is called it creates a new instance of the destination type and populates its properties from the origin type enumerating through all its properties via reflection.

    We all know that reflection is slow when compared to accessing the types and members directly, but the real problem on this code lays on the fact that it tries to instantiate a new object using a parameterless constructor, but there is no guarantee that the class has one.

    It has all been working based on the convention assumed on the project that these types will all have a public parameterless constructor. What happens if a new developer comes in and unaware of the convention decides to create a constructor with parameters? The compiler seeing that there's a constructor will not create the default parameterless constructor anymore. Since there's nothing else checking it, it will only fail at runtime.

    A runtime exception would be caught relatively early if they were using unit testing, but they aren't using it, so it depends on trusting the developer to do the proper tests.

    Well, I'm a developer, but I trust more on the compiler doing that job than on myself or whoever for that matter, so I proposed some changes:

    class TypeTranslator<TOrigin, TDestination> where TDestination : new() {
        public TDestination Convert2(TOrigin value) {
            TDestination to = new TDestination();
            // goes on and copies the contents of each property from the TFrom object instance to the TTo object instance
            return to;
        }
    }

    This way, the compiler will guarantee that the type used has a parameterless constructor. Finding issues at compile time is much cheaper than at runtime.

    Live Search - Se eu pudesse pelo menos experimentar...

    Eu sou usuário do Google a vários anos.É realmente uma ferramenta de busca fantástica.

    O Live Search deixava muito a desejar quando foi lançado. Eu ouvi dizer que melhorou muito, mas infelizemente já a alguns meses, eu não tinha como experimentar...

    Tanto de casa quanto nos diversos projetos que passei nos últimos meses, o acesso à internet era provido pela Speedy. Coincidência ou não, em nenhum destes lugares o browser conseguia abrir a página de resultados de busca (http://search.live.com/results.aspx?q=mulher+pelada&form=QBRE, por exemplo).

    Como usuário do Google, eu pensava... Ah.. Deixa pra lá, vou fazer a pesquisa no Google mesmo.

     

    Hoje eu resolvi gastar um minutinhos nisso e consultei alguns camaradas daqui de São Paulo e de fora do estado e o resultado foi o seguinte:

    Todo mundo que acessava via Speedy, não conseguia abrir o site.

    O pessoal de outros estados conseguia.

    Eu já desconfiava que fosse "sacanagem" do DNS da Telefônica, mas a experiência deixou isso mais claro.

    Fazendo uma busca por "live search speedy telefônica dns" no Google eu acabei encontrando algumas páginas com pessoas descrevendo problemas parecidos finalmente uma relação de servidores DNS em http://www.abusar.org/dns.html

    Configurei o meu DNS para o www.opendns.org (208.67.222.222 e 208.67.220.220) e Live Search voltou a funcionar.

    Salvei a relação de servidores DNS aqui  na máquina para o caso de precisar novamente.

    Tchau DNS da TelefoZica!

    8/30/2008

    Volta on IEEE magazine.

    I haven't played with it for a while but the Volta folks released an article on IEEE magazine.

    If you're in to developing distributed applications, you should take a look at it.