9

Aby utworzyć nasze dane testowe, stosujemy następującą odmianę wzoru Builder (uproszczony przykład!): KlasęJak wygenerować kod na podstawie innej klasy?

próbki:

public class Person 
{ 
    public string Name { get; set; } 
    public string Country { get; set; } 
} 

Budowniczy:

public class PersonBuilder 
{ 
    private string name; 
    private string country; 

    public PersonBuilder() 
    { 
     SetDefaultValues(); 
    } 

    private void SetDefaultValues() 
    { 
     name = "TODO"; 
     country = "TODO"; 
    } 

    public Person Build() 
    { 
     return new Person 
        { 
         Name = name, 
         Country = country 
        }; 
    } 

    public PersonBuilder WithName(string name) 
    { 
     this.name = name;    
     return this; 
    } 

    public PersonBuilder WithCountry(string country) 
    { 
     this.country = country; 
     return this; 
    } 
} 

UWAGA: kontekst samego przykładu nie jest istotny. Ważną rzeczą jest tutaj, jak w tym przykładzie można zbudować klasę budowniczych, jak np. PersonBuilder, patrząc na klasę encji (Person) i stosując ten sam wzór - patrz poniżej.

Wyobraźmy sobie teraz, że klasa osoby ma 15 właściwości zamiast 2. Zaimplementowanie klasy budowniczej wymagałoby trochę monkeyworków, podczas gdy teoretycznie może ona zostać automatycznie wygenerowana z klasy Person. Możemy użyć generowania kodu, aby szybko skonfigurować klasę budowniczą, a następnie w razie potrzeby dodać niestandardowy kod.

Proces generowania kodu musiałby być świadomy kontekstu (nazwy i właściwości klasy osoby), więc proste generowanie kodu opartego na tekście lub magii regex nie jest tutaj właściwe. Rozwiązanie, które jest dynamiczne, a nie oparte na tekście i może być uruchamiane szybko z wnętrza studia wizualnego, jest preferowane.

Szukam najlepszego sposobu na generowanie kodu dla takich scenariuszy. Odbicie? Codesmith? Szablony T4? Szablony Resharper Live z makrami?

Czekam, aby zobaczyć kilka świetnych odpowiedzi :)

Odpowiedz

2

Rozwiązanie T4 jest dobrze zintegrowana opcja Visual Studio. Możesz użyć odbicia wewnątrz szablonu T4, aby wygenerować kod.

0

Jeśli jest tylko do testów, należy rozważyć ramy szyderczy jak RhinoMocks:

internal class PersonBuilder 
{ 
    private MockRepository _mockRepository; 
    private IPerson _person; 

    public PersonBuilder() 
    { 
     _mockRepository = new MockRepository(); 
     _person = _mockRepository.Stub<IPerson>(); 
    } 

    public PersonBuilder WithName(string name) 
    { 
     _person.Name = name; 
     return this; 
    } 

    public PersonBuilder WithCountry(string Country) 
    { 
     _person.Country= Country; 
     return this; 
    } 

    public IPerson Build() 
    { 
     _mockRepository.ReplayAll(); 
     return _person; 
    } 

} 

ten sposób Państwa budowniczy może rozwijać się wraz z potrzebą. Co więcej, nie musisz zmieniać swojej metody budowania. Po prostu dodaj metody "WithX".

+0

Już używamy szyderczo w naszych testach jednostkowych, ale nigdy nie myślałem o używaniu do tego macków :). Myślę, że byłby to świetny sposób na rozwiązanie tego konkretnego problemu, ale nie na pytanie ogólne, które ma szerszy zakres niż tylko testy. Ale i tak bardzo dziękuję za tę odpowiedź! –

2

Dodaliśmy funkcję w CodeSmith Generator 5.x, która pozwala wygenerować poza istniejącym kodem. Proszę spojrzeć na to documentation here. Możesz również użyć refleksji lub dowolnej biblioteki .NET w szablonie Generatora kodów CodeSmith.

Dzięki -Blake Niemyjski

0

Sprawdźcie do podejścia ABSE modelowania i jego IDE, AtomWeaver. ABSE to oparte na szablonach modelowanie i struktura generowania kodu, w której model (nie ma nic wspólnego z UML lub MDA) jest tworzony przez zastosowanie "bloków konstrukcyjnych" (Atomów). Atomy te są hybrydami typu szablon/program i mają świadomość kontekstową: atom może generować kod zgodnie z jego umiejscowieniem na drzewie oraz na obecności/nieobecności niektórych atomów.

Model hosta (w tym przypadku AtomWeaver) "wykona" model w celu uzyskania pożądanego kodu źródłowego. Model może być "źródłem": zmienić model i zregenerować tyle razy, ile to konieczne.

AtomWeaver nie jest zintegrowany z Visual Studio, ale może pracować z nim bez żadnych problemów.