b2aat6n
b2aat6n
b2aat6n
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Listing 1<br />
Einen generischen<br />
Typparameter verwenden.<br />
public interface IGenerator<br />
{<br />
T GenerateValue();<br />
}<br />
Datenbank liegt auf der Hand, auf diesen<br />
habe ich aus Zeitgründen jedoch verzichtet.<br />
Übergangsweise kann man sich damit<br />
behelfen, die CSV-Dateien mit einem ETL-<br />
Prozess (Extract, Transform, Load) in die<br />
Datenbank zu schaufeln.<br />
Die Komponenten Generators, Data-<br />
Pump, DbDataAdapter und CsvDataAdapter<br />
haben nur geringe Abhängigkeiten, wie<br />
Abbildung 6 zeigt. Der CsvDataAdapter ist<br />
nicht von den anderen Komponenten abhängig,<br />
weil er lediglich auf dem gemeinsamen<br />
Datenmodell aufsetzt.<br />
Einzelne Werte<br />
Für das Erzeugen eines einzelnen Wertes<br />
habe ich mich für die Verwendung eines<br />
Generators entschieden. Dieser hat die<br />
Aufgabe, zu einem gegebenen Typ einen<br />
Wert zu liefern. Die dabei verwendete Strategie<br />
bestimmt der Generator. So ist ein<br />
Generator denkbar, der zufällige Werte erzeugt.<br />
Genauso kann aber auch ein Generator<br />
erstellt werden, der eine Liste von Daten<br />
erhält und daraus zufällig auswählt.<br />
Die Beschreibung der zu erzeugenden<br />
Datenzeilen besteht also darin, pro Spalte<br />
einen Generator zu definieren. Ferner wird<br />
pro Spalte der Name der Spalte benötigt.<br />
Im Kontrakt der Generatoren habe ich<br />
einen generischen Typparameter verwendet,<br />
siehe Listing 1. Dadurch wird bereits<br />
zur Übersetzungszeit geprüft, ob der Rückgabewert<br />
der Methode GenerateValue zum<br />
Generatortyp passt.<br />
Die Generatoren werden in den Spaltendefinitionen<br />
verwendet. Da sie einen generischen<br />
Typparameter haben, muss dieser<br />
bei Verwendung des Generators entweder<br />
durch einen konkreten Typ oder an derVerwendungsstelle<br />
durch einen generischen<br />
Typparameter belegt werden. Für die Klasse<br />
ColumnDefinition würde das bedeuten,<br />
dass diese ebenfalls einen generischen Typparameter<br />
erhält, siehe Listing 2.<br />
So weit, so gut. Doch eine Zeile besteht<br />
aus mehreren Spalten. Daher müssen meh-<br />
Listing 2<br />
Spalten definieren.<br />
public class ColumnDefinition<br />
{<br />
public ColumnDefinition(string columnName, IGenerator generator)<br />
{<br />
ColumnName = columnName;<br />
Generator = generator;<br />
}<br />
public string ColumnName { get; private set; }<br />
public IGenerator Generator { get; private set; }<br />
}<br />
Listing 3<br />
Werte erzeugen.<br />
rere ColumnDefinition-Objekte in einer<br />
Liste zusammengefasst werden. Da natürlich<br />
jede Spalte einen anderen Typ haben<br />
kann, muss es möglich sein, beispielsweise<br />
eine ColumnDefinition sowie eine<br />
ColumnDefinition in diese Liste auf-<br />
LÖSUNG<br />
public static IEnumerable GenerateValues(this IEnumerable<br />
columnDefinitions) {<br />
return columnDefinitions<br />
.Select(x => x.Generator)<br />
.Select(x => x.GenerateValue());<br />
}<br />
Listing 4<br />
Eine Datenzeile generieren.<br />
public static Line GenerateLine(this IEnumerable values)<br />
{<br />
return new Line(values);<br />
}<br />
Listing 5<br />
Mehrere Zeilen generieren.<br />
public IEnumerable GenerateTestData(IEnumerable<br />
columnDefinitions, int rowCount)<br />
{<br />
for (var i = 0; i < rowCount; i++)<br />
{<br />
yield return<br />
columnDefinitions<br />
.GenerateValues()<br />
.GenerateLine();<br />
}<br />
}<br />
zunehmen. Dies ist jedoch mit C# 3.0 aufgrund<br />
der fehlenden Ko-/Kontravarianz<br />
noch nicht möglich. Würde man die Liste<br />
als List definieren, müsste die Liste<br />
Kovarianz unterstützen. Das tut sie jedoch<br />
nicht, Ko- und Kontravarianz stehen erst<br />
www.dotnetpro.de dotnetpro.dojos.2011 17