Domanda

Attualmente il progetto con cui sto lavorando non ha modelli completamente fissi (a causa di un'influenza esterna) e quindi mi piacerebbe avere una certa flessibilità nello scriverli. Attualmente sono replicati su tre diversi livelli dell'applicazione (db, api web e client) e ognuno ha una logica simile (vale a dire la validazione).

Mi chiedevo se ci fosse un approccio che mi permettesse di scrivere un file modello (diciamo in ruby), e poi farlo convertire quel modello nei file c # necessari. Attualmente sembra che stia scrivendo un sacco di codice boilerplate che può cambiare in qualsiasi fase, mentre questo approccio generato mi consentirebbe di concentrarmi su cose molto più importanti.

Qualcuno ha una raccomandazione per qualcosa del genere, una dsl / lingua in cui posso farlo, e qualcuno ha qualche esperienza riguardo qualcosa del genere?

È stato utile?

Soluzione

Questo può essere fatto facilmente con ANTLR . Se l'output è abbastanza simile, puoi semplicemente usare il meccanismo di template del testo & # 8212; altrimenti può generare un albero di sintassi astratto da attraversare.

Altri suggerimenti

Ho visto un sistema che utilizzava classi parziali e metodi parziali per consentire la rigenerazione del codice senza influire sul codice personalizzato. Il & Quot; motore delle regole & Quot; se sarà completamente generato da un diagramma di stato di Visio. Questo è fondamentalmente un flusso di lavoro mans povero ma molto facile da modificare. Il diagramma di Viso è stato esportato in XML che è stato letto usando PowerShell e T4 per generare le classi.

L'esempio sopra è di un DSL esterno. OSSIA esterno al linguaggio di programmazione in cui viene eseguita l'applicazione. In alternativa, è possibile creare un DSL interno che viene implementato e utilizzato in un linguaggio di programmazione.

Questo e il precedente l'articolo su DSLS di Code-Magazine sono abbastanza buoni .

Nel link sopra, Neal Ford mostra come creare un DSL interno in C # usando un'interfaccia fluida.

Una cosa che non ha ancora menzionato è che puoi mettere questo attributo [EditorBrowsable (EditorBrowsableState.Never)] sui tuoi metodi in modo che non appaiano intellisense. Ciò significa che puoi nascondere i metodi non DSL (se vuoi) sulla classe all'utente del DSL rendendo l'API fluente molto più rilevabile.

Puoi vedere un'interfaccia fluente scritta in diretta in questa serie video da Daniel Cazzulino su scrivere un contenitore IoC con TDD

In tema di DSL esterni hai anche la possibilità di Oslo (CTP al momento) che è abbastanza potente nella sua capacità di permetterti di creare DSL esterni che possono essere eseguiti direttamente piuttosto che per l'uso della generazione di codice che arriva a pensate che non è proprio un DSL.

Penso che tu sia sulla buona strada.

Quello che faccio di solito in una situazione come questa è progettare un linguaggio semplice che catturi le mie esigenze e scriverne un parser LL1 (Discesa ricorsiva).

Se la lingua deve contenere una sintassi C # non banale, posso citarla o racchiuderla tra parentesi che posso riconoscere e passarla al codice di output.

Posso fare in modo che generi una struttura ad albero di analisi, e generare ad esempio 3 diversi tipi di codice da quello, oppure posso semplicemente generare un codice al volo, usando una variabile di modalità con 3 valori, o semplicemente scrivere contemporaneamente codice su 3 diversi file di output.

C'è più di un modo per farlo. Se hai paura di scrivere parser (come alcuni programmatori), c'è molto aiuto altrove su SO.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top