APIs do Exchange Server

No decorrer dos anos foram criadas diversas APIs para acessar as funcionalidades do Exchange Server

Com o Exchange Server 2007, a Microsoft iniciou um trabalho forte de consolidação destas APIs e com isto diversas APIs deixaram de ser suportadas entre as versões 2003 e 2007 e outras deixaram de ser instaladas como parte do produto sendo disponibilizadas em download a parte (Microsoft Exchange Server MAPI Client and Collaboration Data Objects 1.2.1, por exemplo).

Com a transição do Exchange Server 2007 para 2010, as APIs foram consolidadas ainda mais. Vejam:

Exchange 2007 Exchange 2010 Mantido
Active Directory Services Interfaces (ADSI)   FALSO
CDOEXM Evaluation Criteria   FALSO
CDOSYS SMTP/NNTP Event Sinks   FALSO
CDOWF Evaluation Criteria   FALSO
Collaboration Data Objects for Exchange (CDOEX)   FALSO
Collaboration Data Objects for Windows 2000 (CDOSYS)   FALSO
Exchange Backup and Restore API   FALSO
Exchange OLE DB Provider (ExOLEDB)   FALSO
Exchange Rules   FALSO
  Exchange Server Protocols FALSO
Exchange Store Event Sinks   FALSO
Exchange Web Services Evaluation Criteria Exchange Web Services VERDADEIRO
Exchange Web Services Managed API 1.0 Exchange Web Services Managed API 1.0 VERDADEIRO
Exchange writer for the Windows Volume Shadow Copy Service Exchange Writers for Volume Shadow Copy Service VERDADEIRO
HTTP/Web Distributed Authoring and Versioning (WebDAV)   FALSO
Incremental Change Synchronization (ICS)   FALSO
Lightweight Directory Access Protocol (LDAP)   FALSO
Messaging Application Programming Interface (MAPI) Messaging API VERDADEIRO
Outlook Object Model (OOM) Microsoft Office Outlook Object Model VERDADEIRO
Outlook Web Access (OWA) Outlook Web App Customization VERDADEIRO
SMTP Event Sinks   FALSO
Transport Agents Transport Agents VERDADEIRO
Web Forms Evaluation Criteria   FALSO
WebDAV Notifications   FALSO
  Windows PowerShell FALSO
WMI Evaluation Criteria   FALSO

 

A grande aposta são nos Exchange Web Services e a sua contra-partida no lado do cliente, o EWS Managed API. Realmente é uma API muito promissora mais ainda faltam alguns recursos existentes no MAPI, como por exemplo, a habilidade de se criar propriedades nomeadas (ou estendidas na nomenclatura do EWS) para anexos.

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.

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?

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.

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!

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!

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.

Download gratuito de música – Legalizado e com remuneração do artista

Na semana passada eu descobri o Álbum Virtual da Trama.

Eles estão com uma idéia bem legal que é a de todo mês eles definem um orçamento e rateam a grana para os artistas que estão no site baseado no número de downloads.

Na semana passada haviam 3 bandas/artistas:

Cansei de Ser Sexy – Bem legalzinho

Tom Zé – Pura viagem. Provavelmente não escutarei novamente

Macaco Bong – Ainda não escutei.

Os álbuns ficam disponíveis por tempo limitado, então é bom estar checando o site de tempos em tempos para ver o que aparece de novo por lá.

Tem um videozinho lá no YouTube falando do projeto: