Bei meiner Arbeit mit REST muss ich immer so lange, unleserliche queryStrings aufbauen, ungefähr dieser Art:
Ich finde das sehr unleserlich und schwierig zu warten. Auch muss ich derlei Strings auch immer wieder modifizieren.
Recht betrachtet beschreibt so ein String ja ein
Nur die Leserlichkeit! Eine kleine Änderung -
Ein andere REST-Übung ist das Adden von Headern oder Parametern
Lauter so Zeug.
Derlei Header/Parameter sind offsichtlich auch nix weiter als String-Dictionaries.
Also habich gedacht, ein DictionaryString muss her, der String und Dictionary verquickt. Sodass man das Ding kompakt initialisieren kann.
Und er soll leserlich befüllbar sein, aber syntaktisch korrekten Output liefern. Output-Separator soll einstellbar sein, und InputSeparator(en) auch.
Herausgekommen ist dieses:
Das Besondere sind die implementierten Operatoren:
Der
Den Nutzen sieht man vlt. in der Test-Methode:
Zeile
Der DictionaryString hat nun 11 Einträge, und seine Ausgabe ist sone typische REST-Parameter-String-Gräuseligkeit (die man leider ja so benötigt):
Zeile
Also
Und ich kann (
query=bremer+dom&cat=web&pl=ext-ff&language=deutsch&extVersion=1.3.0
.Ich finde das sehr unleserlich und schwierig zu warten. Auch muss ich derlei Strings auch immer wieder modifizieren.
Recht betrachtet beschreibt so ein String ja ein
Dictionary<string, string>
in kürzest-möglicher Form - also durchaus pfiffig!Nur die Leserlichkeit! Eine kleine Änderung -
,
als Separator - brächte schon Erleichterung: query=bremer+dom, cat=web, pl=ext-ff, language=deutsch, extVersion=1.3.0
Ein andere REST-Übung ist das Adden von Headern oder Parametern
VB.NET-Quellcode
- request.AddHeader("Accept-Encoding=gzip,deflate,br")
- request.AddHeader("Connection=keep-alive")
- request.AddHeader("Content-Type=application/x-www-form-urlencoded")
- request.AddHeader("Host=www.startpage.com")
- request.AddHeader("Origin=https://www.startpage.com")
- request.AddHeader("Referer=https://www.startpage.com/")
- request.AddHeader("Startpage-Extension=ext-ff")
- request.AddHeader("TE=Trailers")
- '...
Derlei Header/Parameter sind offsichtlich auch nix weiter als String-Dictionaries.
Also habich gedacht, ein DictionaryString muss her, der String und Dictionary verquickt. Sodass man das Ding kompakt initialisieren kann.
Und er soll leserlich befüllbar sein, aber syntaktisch korrekten Output liefern. Output-Separator soll einstellbar sein, und InputSeparator(en) auch.
Herausgekommen ist dieses:
VB.NET-Quellcode
- Public Class DictionaryString
- Public Separators As String() = {", "}
- Public ReadOnly Dictionary As New Dictionary(Of String, String)
- Public Sub New(Optional separator As String = ", ")
- Me.Separators = {separator}
- End Sub
- Public Sub New(separators As IEnumerable(Of String), Optional entries As String = Nothing)
- Me.Separators = separators.ToArray
- If entries IsNot Nothing Then Merge(entries)
- End Sub
- Public Shared Widening Operator CType(ds As DictionaryString) As String
- Return ds.ToString
- End Operator
- Public Shared Operator +(x As DictionaryString, y As String) As DictionaryString
- x.Merge(y) : Return x
- End Operator
- Private Sub Merge(str As String)
- Dim entries = str.Split(Separators, StringSplitOptions.RemoveEmptyEntries)
- For i = 0 To entries.Length - 1
- Dim splits = entries(i).Split({"="c}, 2)
- If splits.Length <> 2 Then Throw New ArgumentException($"Der {i + 1}te Eintrag enthält kein Trennzeichen '='")
- Item(splits(0)) = splits(1).Trim
- Next
- End Sub
- Public ReadOnly Property Value As String
- Get
- Return ToString()
- End Get
- End Property
- Public Overrides Function ToString() As String
- 'Separators(0) ist der Output-Separator
- Return String.Join(Separators(0), From kvp In Dictionary Select String.Concat(kvp.Key, "=", kvp.Value))
- End Function
- Default Public Property Item(key As String) As String
- Get
- Dim s As String = Nothing
- Dictionary.TryGetValue(key, s)
- Return s
- End Get
- Set(value As String)
- key = key.Trim
- If value = "" Then Dictionary.Remove(key) Else Dictionary(key) = value
- End Set
- End Property
- End Class
Widening CType
erlaubt, den DictionaryString ohne weiteres an eine String-Variable zuzuweisen.Der
+
Operator impliziert +=
, und das ermöglicht, Strings als Einträge einzumergen.Den Nutzen sieht man vlt. in der Test-Methode:
VB.NET-Quellcode
- ''' <summary>Empfehlung: im Haltemodus durchsteppen und Lokal-Fenster beobachten</summary>
- Sub TestDicString()
- Dim ds = New DictionaryString({"&", ", "}, "a=b, x=ü, gg=55")
- ds += "gut=schlecht, weiss=schwarz, Kommunismus=Faschismus, Wahrheit=Geschmacksache"
- ds += "raiders=twix, Arbeit=Freiheit, Freiheit=Glücksache, egal=88"
- ds += "gut=, weiss=, Kommunismus=, Wahrheit=, raiders=, Arbeit=, egal=" ' lange einträge löschen, wg einfacher debuggen
- Dim s = ds("x") ' Standard-Dictionary-Verhalten
- s = ds!x ' alternative Schreibweise, vb-spezifisch
- s = ds!x & "45"
- ds += "a=c, x=, ja=nein, zz=" ' a wird geändert, x gelöscht, ja zugefügt, zz macht nix
- s = ds!x ' x ist verschwunden, Ergebnis also Nothing
- ds!x = "lkj" ' x wird zugefügt (Standard-Dictionary-Verhalten)
- s = ds ' Ausgabe als String
- End Sub
#3
: Initialisiert mit zwei Separatoren und drei Einträgen - letztere mit dem besser lesbaren ,
-Separator. (Output-Separator ist immer der erste der Separator-Liste)#4+5
: Fügt Einträge hinzu. Gute Lesbarkeit wg ,
-Separator, und weil auf zwei Zeilen verteilt.Der DictionaryString hat nun 11 Einträge, und seine Ausgabe ist sone typische REST-Parameter-String-Gräuseligkeit (die man leider ja so benötigt):
a=b&x=ü&gg=55&gut=schlecht&weiss=schwarz&Kommunismus=Faschismus&Wahrheit=Geschmacksache&raiders=twix&Arbeit=Freiheit&Freiheit=Glücksache&egal=88
Zeile
#6
entfernt die langen Einträge, einerseits um das Multi-Entfern-Feature vorzustellen, andererseits um die weiteren Operationen im Debugger leichter beobachtbar zu machen.Also
+=
zeigt sich hier als "Merge-Operator": Ich kann in einer Anweisung (zb Zeile#10
) Einträge ändern, zufügen, löschen - und ist trotzdem leidlich leserlich.Und ich kann (
#13
) den DictionaryString als normalen String benutzen - ihn etwa an eine Variable zuweisen