Core Concepts

Value Objects: More Than a String

Why Not Just a String?

GPALFile and GPALUrl convert implicitly to and from string, so GPALFile saveFile = @"c:\temp esults.txt"; and GPALUrl url = "youtube.com"; read exactly like a normal string assignment. Any method that expects a string still accepts them. There's no overhead to declaring them this way. The extra capability is simply there if and when you reach for it.

Why Not Just an Array, Either?

GPALGrid and GPALDatabase don't convert to or from a string. They're not stand-ins for a primitive, they're the structured object you'd otherwise build yourself. GPALGrid is the rows-and-columns shape GPAL hands back from .GetGrid() instead of a flat list of strings. GPALDatabase wraps a connection and dialect so the SQL you pass it just runs, instead of you managing a connection object on the side.

GPALFile saveFile = @"c: emp esults.txt";

GPALUrl youtubeUrl = "www.youtube.com";


// each carries behavior GPAL uses directly

youtubeUrl

.WithStorageType(WebsiteStorageType.cookie)

.WithStorageDomain("youtube.com");

browser

.GoTo(youtubeUrl)

.RunDelete(WebsiteStorageType.cookie);


// GetGrid hands back rows and columns

browser.GetGrid(out IGPALGrid<string> results);

string firstPrice = results[0][1];

results.SaveToTabbedText(saveFile);

NOTE

This isn't just convenience for your code. GPAL's own internals read GPALFile's parsed representation, GPALUrl's storage scope, and GPALGrid's shape when you call higher-level methods. The object is the mechanism, not a wrapper around one.

The Exception: GPALElement

GPALElement breaks this pattern on purpose. It has no implicit conversion to or from string and isn't meant to stand in for a primitive at all. It's a plain data object representing an element GPAL found, returned to you in CallIfFound and CallIfNotFound handlers so you can inspect it.

WARNING

Unlike GPALFile, GPALUrl, GPALGrid, and GPALDatabase, GPALElement cannot be assigned from or compared to a string. Read its properties -- .Text, .TagName, .GetAttribute(...) -- rather than treating it like one of the value objects above.

💬 Ask GPAL