2009-08-20 5 views
6

Un paio di giorni fa ho visto l'utilizzo di CoClassAttribute in un modo che non avevo immaginato prima.Interfacce "Nuovo aggiornamento"


[ComImport, CoClass(typeof(Foo)), Guid("787C1303-AE31-47a2-8E89-07C7257B1C43")] 
interface IFoo { 
    void Bar(); 
} 

class Foo : IFoo { 
    public void Bar() { 
     Console.WriteLine("Oh retado!"); 
    } 
} 

in uso come:


class CoClassDemo { 
    public static void Show() { 
     var a = new IFoo(); 
     a.Bar(); 
    } 
} 

Questo dovrebbe non mi hanno sorpreso dal interoperabilità COM fa esattamente che fin dai primi giorni di .NET Framework. Semplicemente non ho prestato molta attenzione quando scavavo attraverso il codice di interoperabilità COM in .NET Reflector.


method public hidebysig static void Show() cil managed 
{ 
    .maxstack 1 
    .locals init (
     [0] class ConsoleApplication1.IFoo a) 
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication1.Foo::.ctor() 
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: callvirt instance void ConsoleApplication1.IFoo::Bar() 
    L_000d: nop 
    L_000e: ret 
} 

È successo che fuori dal contesto di interoperabilità COM, ho subito ho immaginato questo essere utilizzato come tempo di compilazione iniezione di dipendenza di un povero uomo .

Tutto quello che c'è da fare è eliminare il prefisso "I" convenzionale sul nome dell'interfaccia (così come COM Interop).

Quindi sarebbe una questione di cambiare l'attributo Coclasse per scambiare un'implementazione per un altro, scherno, ecc

Due inconvenienti vedo anticipo stanno avendo ricompilare (che praticamente scenari limiti di prova a tempo di sviluppo) ed eventuali problemi che circondano le dipendenze circolari quando le interfacce e le implementazioni vengono distribuite a diversi assiemi.

Qualcuno ha giocato con questa tecnica? Eventuali altri svantaggi? Altri usi?

+8

Hai mai frequentato un corso al liceo? "Usa lo strumento giusto per il lavoro giusto." È una cattiva idea utilizzare uno strumento progettato per l'interoperabilità COM per fare qualcosa di completamente e completamente diverso. Questo rende il tuo codice impossibile da capire per il prossimo ragazzo che deve mantenerlo. Ricorda, il prossimo sarà probabilmente te, anni dopo aver dimenticato esattamente perché hai fatto questa cosa pazza. –

risposta

10

So che questo ha almeno due post sul blog nel weekend - mine e Ayende's.

Per la maggior parte del codice, questo deve essere considerato semplicemente come una curiosità. Penso che sarebbe un abuso usare questo per l'iniezione di dipendenza, quando le strutture IoC/DI stabilite possono fare il lavoro molto meglio e così semplicemente.

In particolare, questo approccio si basa sulla porta di uscita di §17.5, un'estensione specifica di Microsoft per le specifiche ... vuoi che il tuo codice venga eseguito su Mono? Non l'ho provato, ma non esiste una ragione specifica da compilare sotto gmcs/dmcs.

Jon aveva un better example di usarlo in codice concreto - per deliberatamente deridere la COM, ma quello era per giocare con .NET 4.0/dynamic. Ancora; questo non si applica alla maggior parte del codice "normale".

Quindi no; non farlo - è solo un divertimento a parte.

+0

Per ora, lo vedo anche come una curiosità. Sto ancora elaborando questo frammento di informazioni in un thread in background nella mia testa e sono ancora interessato a sapere se ci sono altri usi "creativi" di questa tecnica. –