Erro ao tentar atualizar o NuGet Package Manager

Ao tentar atualizar o Nuget esses dias eu vinha recebendo um erro. Analisando o log, via se que o problema estava relacionado assinatura digital do pacote.

clip_image001

O erro é um problema conhecido do NuGet no Visual Studio 2010 SP 1: http://docs.nuget.org/docs/reference/known-issues

Embora você possa solicitar um patch junto ao suporte da Microsoft usando as instruções encontradas em http://support.microsoft.com/kb/2581019, eu não atualizo extensões com uma frequência que justifique a instalação deste patch.

No próprio documento de problemas conhecidos estão listados os passos necessários que eu reproduzo aqui na ordem correta e em português para a sua conveniência.

1. Abra o Visual Studio como administrador (Run As Administrator). Isto é necessário para poder desinstalar a versão atual do NuGet

2. Desinstale o NuGet

3. Reinicie o Visual Studio

4. Abra o Extension Manager (Tools -> Extension Manager), vá em Online Gallery, faça uma busca por Nuget e instale-o.

HTH

 

Alfred Myers

Cannot obtain value of local or argument ‘variableName’ as it is not available at this instruction pointer, possibly because it has been optimized away

… onde variableName é o nome da variável local ou parâmetro cujo valor você deseja inspecionar.

 

 

Na palestra do sábado passado (19/Mai/2010) eu falei sobre o acesso ao código-fonte do .NET Framework.

Um dos problemas quando você dá step-into o código do .NET Framework é que muitas vezes os valores das variáveis locais e parâmetros não são exibidos.

Isto ocorre por conta de otimizações feitas durante a compilação JIT.

Shawn Buke, um dos responsáveis pela liberação do código do Framework, postou sobre como resolver isto no começo de 2008.

http://blogs.msdn.com/b/sburke/archive/2008/01/29/how-to-disable-optimizations-when-debugging-reference-source.aspx

 

Eu já tinha cruzado com este artigo e até twitei a respeito, mas os twits se “perdem” com o tempo. Por aqui vai ficar mais fácil de encontrar.

Estamos Contratando

Pessoal,

Temos vários projetos bacanas vindo por aí e para dar conta do recado, estamos contratando gente aqui para a ITGROUP.

Eu estou aqui desde setembro de 2006 e o que posso dizer é que o ambiente é bacana e o que não faltam são chances de trabalhar com coisas legais.

Se você se encaixa num dos perfís abaixo, mande um currículo para rh [at] itgroup.com.br.

Qualquer coisa manda uma Direct Message lá no Twitter em @AlfredMyers

 

– Analista de Sistemas .NET Jr

Buscamos profissionais dinâmicos, com paixão por tecnologia, facilidade de aprendizado e comunicação, com bons conhecimentos em programação, orientação a objetos, plataforma Microsoft .NET, Office e SQL Server.

Cursando a partir do segundo semestre de uma faculdade de tecnologia ou bacharelado na área, boa leitura em inglês e certificações Microsoft serão considerados diferenciais.

– DBA SQL Server Pleno

Buscamos profissionais dinâmicos, com facilidade de aprendizado e comunicação, com experiência em implementação da infraestrutura em alta disponibilidade, modelagem de dados relacional, tunning e operação de bancos de dados de missão crítica com altos volumes de dados e bons conhecimentos em modelagem multidimensional, ETL e soluções de BI com uso do Microsoft SQL Server e seus recursos avançados Analysis Services, Integration Services e Reporting Services.

Conhecimentos em desenvolvimento nas plataformas .NET, Office e SharePoint completam o perfil.

– Analista de Sistemas MSCRM

Buscamos profissionais com experiência em implantação do Microsoft Dynamics CRM 4.0, com conhecimento em configuração, parametrização e desenvolvimento de componentes customizados. Sólidos conhecimentos em programação, orientação a objetos, plataforma Microsoft .NET e SQL Server são primordiais, conhecimentos em metodologias de gestão de projetos e arquitetura são importantes e certificações Microsoft serão consideradas diferenciais. Dinamismo, facilidade de aprendizado e boa comunicação oral e escrita completam o perfil.

– Analista de Testes

Buscamos profissionais com experiência na elaboração de planejamentos de testes, realização de testes funcionais e homologação de sistemas. Conhecimentos em programação, plataforma Microsoft .NET e SQL Server, bem como em metodologias de gestão de projetos serão consideradas diferenciais. Dinamismo, facilidade de aprendizado e boa comunicação oral e escrita completam o perfil.

 

 

P.S: Ah… Também precisamos de analistas funcionais, mas eu não tenho o perfil necessário. Caso interesse, mande um e-mail para rh [at] itgroup.com.br pedindo detalhes.

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.

Resoluções de 2009 – O resultado

No início do ano eu fiz um post sobre a minha resolução de praticar mais esporte em 2009:

“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. “

Bom, o ano não acabou mas estamos no finalzinho e apesar de eu ter uns treinos de corrida planejados até o fim do mês, o que eu fizer até lá não vai mudar muito o quadro geral.

Em 2008 eu corri um total de 183,93Km de abril quando comecei a logar site até dezembro. Agora em 2009 eu já corri 496,68Km incluindo a corrida de 5Km de agora a pouco e tenho planejados mais 32Km até o final do mês. Pouco mais de 500Km num ano para quem era sedentário como eu não está nada mal.

 

image

Melhor ainda é saber que eu poderia ter corrido ainda mais se eu não tivesse estressado joelho, tornozelo e articulações em abril e maio quando corri 80Km em cada um dos dois meses. Isto e outras desculpas fizeram com que eu parasse em junho e fosse retomando devagar (por conta de várias outras desculpas).

 

image

Uma das desculpas que vale a pena mencionar é que em março eu comprei um XBOX. Correr depois de virar noite jogando definitivamente não dá certo.

Espero virar menos noites jogando e assim não ter desculpas para deixar de correr… Vamos ver se vou conseguir isto, já que já tenho encomendados Mordern Warfare 2 e Halo ODST que receberei em Janeiro… Vamos ver!

Mas voltando ao esporte: Esse negócio de registar as corridas no site da Nike e a possibilidade de você montar objetivos por lá é bem interessante porque te motiva a treinar com mais frequência. O problema é que se você for meio obsessivo como eu e não estabelecer metas razoáveis, você vai acabar deixando outros esportes de lado. Foi o que aconteceu com o mountain bike. Andei muito pouco esse ano. Acho que não cheguei a ir uma vez sequer à Serra do Japi. Pretendo retomar as pedaladas em 2010.

Sobre a prática de outros esportes:

Em julho comecei um curso de vela e arrais, que não cheguei a concluír. Pretendo retomar já em Janeiro.

Em outubro comecei a jogar futebol com o pessoal lá da ITGROUP. Uma vez por semana. Um pouco de esporte e muita diversão. Isso é praticamente certo continuar no ano que vem.

O resultado disto tudo é que perdi um bocado de barriga e a disposição melhorou muito. Muito bom!

EWS Managed API 1.0

O Exchange 2010 está sendo lançado hoje e com isto eles liberaram também a versão final do Exchange Web Services Managed API 1.0 que poderá ser rodado contra Exchange 2007 SP1 ou Exchange 2010.

O EWS é uma fachada de Web Services que foi liberado pela primeira vez com o Exchange 2007. O uso no lado do cliente era feito tipicamente através de um “Add Web Reference” da vida, mas a usabilidade não era lá essas coisas.

O EWS Managed API, é irmão “inteligente” do proxy que fornece uma API consistente e de boa usabilidade.

Caso tenham que conversar com o Exchange, sugiro que dêem uma olhada:

 

Documentação:

http://msdn.microsoft.com/en-us/library/dd633710.aspx

 

Download:

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=c3342fb3-fbcc-4127-becf-872c746840e1

ILMerge

Ontem durante o Ask The Experts no TechEd Brasil 2009, alguém perguntou se era possível combinar diversos assemblies em um só para não ter que distribuí-los separadamente.

Um exemplo disto seria pegar um executável como MeuExecutavel.exe e alguns assemblies dependentes como MinhaDllA.dll e MinhaDllB.dll  e juntá-os todos em um único assembly como MeuAssemblao.exe.

A resposta é: Sim é possível e para tanto você pode usar o ILMerge

Occam’s razor

Eu já vinha escutando o podcast do pessoal do StackOverflow há alguns meses e por conta disto já tinha ouvido falar no site.

Cheguei a visitar o site algumas vezes, mas nunca gastei muito tempo por lá. Hoje enfim decidi me registrar.

O login via Open ID é bem bacana – integra com sua conta no GMail e alguns outros. Pena que não com o Windows Live ID.

Mas chega de enrolação e vamos para o assunto de hoje:

Dando uma olhada nos posts de C#, eu acabei cruzando o tópico “How could I refactor this factory-type method and database call to be testable?

Todas as sugestões dadas envolvem uma reestruturação radical do código. O pobre coitado deve ter ficado assustado. Eu estou!

Por coincidência, eu venho trabalhando bastante com testes unitários ultimamente e uma das necessidades que tenho é justamente a de isolar os testes do banco de dados.

O problema é que eu ainda não estou convencido de que se deva sair alterando todo o sistema só para substituir o banco de dados por um dublê, mock ou o que quer que você chame.

Deve ter um jeito mais fácil de fazer isto.

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.