quinta-feira, 25 de abril de 2013

Web config transforms (Visual Studio)

Às vezes as pessoas adicionam no projeto um arquivo copiado do web.config, só para para homologação / produção. Se você usar o publish do visual studio, isso não é necessário. Você apenas adiciona um arquivo a mais, web.Producao.config por exemplo, que terá apenas o que será alterado no web.config original, e cria o perfil Producao (exemplo) no Visual Studio. Quando for fazer o deploy, você seta aquele perfil, e manda fazer o deploy, que ele irá alterar o que é necessário, e fazer o deploy com o arquivo alterado.

Detalhado:
  • Ao lado do botão de play, tem um combo escrito Debug (ou Release). Clique na opção Configuration Manager;
  • Em Active Solution Configuration, clique em New;
  • Dê um nome à sua configuração nova (Producao?) e escolha qual a configuração antiga será copiada;
  • Vá no web.config, clique com o botão direito e clique em Add Config Transforms;
  • Surgirá, dentro do web.config, um arquivo chamado web.[sua configuração].config. Dentro dele, você pode colocar os atributos que quer mudar ou adicionar.

A diferença das tags é dois atributos a mais, dizendo o que deve ser feito e o critério usado para tanto. Ex:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <connectionStrings>
      <add name="connectionString" connectionString="X" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
    </connectionStrings>
</configuration>


Assim, se você adicionar coisas novas ao web.config, não terá que ficar fazendo merge, nem terá aquele risco de alguém substituir o web.config sem saber.

terça-feira, 16 de abril de 2013

CSS selectors: nth-child x nth-of-type

Quando descobri o nth-child, adorei. O efeito dele é aplicar um estilo a certos elementos de uma lista e a outros não. Por exemplo, tabelas listradas, que antes calculávamos na programação quais eram as linhas pares e ímpares para aplicar ou não um estilo.

Algumas vezes, me pareceu ter um comportamento estranho. De repente, eu pedia para ele pegar as linhas ímpares e ele pegava as pares. Recentemente descobri que o problema era quando havia um intruso entre os filhos. Por exemplo*:

<style>
    ul li:nth-child(2n)
    {
        background: red;
    }
</style>

<ul>
    <input type="hidden" />
    <li><input /></li>
    <li><input /></li>
</ul>

Até esbarrar com a situação e entender, eu achava que este código deveria colorir de vermelho sempre o segundo elemento LI a cada dois. Porém, sendo nth-child, ele considera também o hidden. Sendo assim, o primeiro LI é o segundo elemento desta lista.

Quando você tenta fazer um CSS genérico para o site, com itens gerados automaticamente, isso começa a ser um problema. Me deparei com isso hoje, ao precisar adicionar uma tag script (não podia separar em arquivo js porque inclui código C#).

A solução foi um selector que eu ainda não conhecia: nth-of-type. Este sim pega apenas os LIs.

<style>
    ul li:nth-of-type(2n)
    {
        background: red;
    }
</style>

<ul>
    <input type="hidden" />
    <li><input /></li>
    <li><input /></li>
</ul>


Não importa quantos hiddens sejam colocados ali, ele continua pintando de vermelho o segundo elemento de cada dois LI.



* Um UL não deve conter elementos fora LIs. Isto é apenas um exemplo.

Herança Múltipla em C#

Alguém já se pegou precisando fazer uma herança múltipla em C#? A própria ideia é bem estranha. Em tese, você herda algo genérico e extende. Porque misturar duas coisas?

Caso apareça essa necessidade, você tenha pensado bem e visto que não tem como, que você não pode transformar suas classes em interfaces, que você vai efetivamente usar os códigos separados que não pode colocar as duas classes como filhas da classe que você queria fazer herdá-las... Um milhão de aspectos a analisar. O bom seria que você pensasse muito antes de fazer.

Estou no terceiro parágrafo. Tem certeza mesmo que é isso que você quer? Ok. Vamos lá.


    public class Ornitorrinco : Pato, Castor
    {
    }

    public class Pato
    {
        public Boolean BicoMexendo { get; set; }

        public void MexeBico()
        {
            BicoMexendo = true;
        }
    }

    public class Castor
    {
        public Boolean CaldaMexendo { get; set; }

        public void MexeCalda()
        {
            CaldaMexendo = true;
        }
    }


A essa altura, o Visual Studio me diz que está esperando uma interface. É, não existe Herança Múltipla em C#. Pois é. Que triste, não? Aiai. Ok, ainda posso herdar as propriedades.


    public interface ITemBico
    {
        Boolean BicoMexendo { get; set; }
    }

    public interface ITemCalda
    {
        Boolean CaldaMexendo { get; set; }
    }

    public class Ornitorrinco : ITemBico, ITemCalda
    {
        public Boolean BicoMexendo { get; set; }
        public Boolean CaldaMexendo { get; set; }
    }

    public class Pato : ITemBico
    {
        public Boolean BicoMexendo { get; set; }

        public void MexeBico()
        {
            BicoMexendo = true;
        }
    }

    public class Castor : ITemCalda
    {
        public Boolean CaldaMexendo { get; set; }

        public void MexeCalda()
        {
            CaldaMexendo = true;
        }
    }


Uma das sugestões que vi na internet é criar um método em Ornitorrinco, inicializar um Pato / Castor dentro, e chamar o método dele. Mas como eu faço com que isso interfira nas MINHAS variáveis? Igualo o valor depois?

A ideia que tive veio de algo que adoro fazer: extender classes. Principalmente com String, ajuda bastante no entendimento do código. A parte que interessa nesse momento é que também é possível extender uma interface. O que me possibilita...

    public interface ITemBico
    {
        Boolean BicoMexendo { get; set; }
    }

    public static class TemBico
    {
        public static void MexeBico(this ITemBico temBico)
        {
            temBico.BicoMexendo = true;
        }
    }

    public interface ITemCalda
    {
        Boolean CaldaMexendo { get; set; }
    }

    public static class TemCalda
    {
        public static void MexeCalda(this ITemCalda temCalda)
        {
            temCalda.CaldaMexendo = true;
        }
    }

    public class Ornitorrinco : ITemBico, ITemCalda
    {
        public Boolean BicoMexendo { get; set; }
        public Boolean CaldaMexendo { get; set; }
    }

    public class Pato : ITemBico
    {
        public Boolean BicoMexendo { get; set; }
    }

    public class Castor : ITemCalda
    {
        public Boolean CaldaMexendo { get; set; }
    }


Agora eu posso fazer isso...

            var meuOrnitorrinco = new Ornitorrinco();
            var meuPato = new Pato();
            var meuCastor = new Castor();

            meuOrnitorrinco.MexeBico();
            meuOrnitorrinco.MexeCalda();
            meuPato.MexeBico();
            meuCastor.MexeCalda();

...sabendo que o código não está repetido e correndo risco de uma correção ou um refactor afetar uma coisa e não outra. É, eu sei, o último código ficou parecendo música da Xuxa.

Sim, é possível. Raramente será a solução correta. As propriedades usadas pelos métodos terão que ficar expostas. Se for fazer, tenha certeza de não usar o mesmo nome de método para duas interfaces que serão herdadas pela mesma classe.

Meu exemplo não é um Ornitorrinco a toa...

sábado, 13 de abril de 2013

MVC4 Partials

Hoje eu estava alterando uma View, para colocar uma Partial dentro dela.

Me deparei com um problema quando tentei renderizar a Partial. Apesar de eu estar passando uma propriedade model esperado como model para a função Partial (Html.Partial), ele continuava dizendo que eu tentava passar o model principal. E dava o erro:

The model item passed into the dictionary is of type '[model principal]', but this dictionary requires a model item of type '[model esperado]'.

O problema é que a propriedade era nula. Então o método Html.Partial estava pegando o pai da propriedade, que realmente era meu model principal. Por isso o erro. Resolvi isso colocando no construtor do model principal uma inicialização para a propriedade do model esperado.