Ha az alkalmazáskódnak tudnia kell, hogy MongoDB vagy Cassandra van mögötte — az tervezési hiba. Nem feltétlenül katasztrófa, de hiba. Az üzleti logika ne függjön az infrastruktúra döntéstől. A PolyPersist ezt az elvet valósítja meg .NET-ben, egységes interfészeken keresztül, dokumentum-, oszlop- és blob tárók fölött.
Mi a probléma pontosan?
Az ORM-ek részben megoldják ezt a kérdést, de csak az SQL világban. Ha egy projekt MongoDB-t használ dokumentumokhoz, Cassandrát idősoros adatokhoz, és S3-at fájlokhoz — mindegyikhez külön hozzáférési réteget kell írni. Ezek nem kompatibilisek egymással, nem cserélhetők, és minden projekt újra megírja ugyanazt.
A cloud-agnosztikus fejlesztés ráadásul elvárja, hogy ne legyen mélyen beleégetett Azure vagy AWS függőség az üzleti logikába. Ez elvben helyes, de megvalósításhoz egységes interfészek kellenek. A PolyPersist ezeket adja.
Hogyan működik?
A könyvtár három store típust absztrahálja:
- DocumentStore — MongoDB, in-memory (fejlesztéshez, teszteléshez)
- ColumnStore — Cassandra, Amazon Redshift, Google BigQuery
- BlobStore — Azure Blob, Amazon S3, Google Cloud Storage, MinIO, GridFS, FileSystem
A fogyasztó kód csak az interfészekkel dolgozik (IDocumentStore, IBlobStore, IColumnStore).
Az, hogy mögötte MongoDB vagy in-memory implementáció fut, dependency injection szinten dől el — nem a kódban.
Ez lehetővé teszi, hogy teszteléshez in-memory, production-ban Mongo fusson, anélkül, hogy az üzleti logikához nyúlna bárki.
Multiplatform interfészek
A PolyPersist nem csak C#-ban él. Az összes store interfész definícióját
a UniContract tool generálja — ez garantálja, hogy a IDocumentStore,
IBlobStore és IColumnStore kontraktus pontosan ugyanaz
C#-ban, Java-ban és Python-ban. Ha az interfész változik, mindenki változik egyszerre.
Ez azt jelenti, hogy egy Java-ban írt service ugyanazon a kontraktuson dolgozik, mint egy C# microservice — anélkül, hogy kézzel kellene szinkronizálni a két definíciót. A multiplatform konzisztencia nem emberi fegyelem kérdése, hanem a toolchain biztosítja.
Tervezési döntések, amelyek számítanak
Az ETag alapú optimista zárolás minden entitásnál, minden adatbázisnál egységes. Ez nem magától értetődő — Cassandra és MongoDB egészen máshogy kezelik a konkurenciát. Az egységesítés kompromisszumot jelent, de a fogyasztó kód szempontjából ez a helyes döntés.
Minden entitáson van PartitionKey. Ez Cosmos DB-vel és DynamoDB-vel való kompatibilitás miatt kell —
de ha nem kell, egyszerűen üresen marad. Jobb, ha ott van és nem kell, mint ha kell és nincs ott.
Async-first a tervezés. Minden operáció Task-alapú.
Adatbázis-hozzáférés mindig I/O bound — a szinkron API csak problémákat okoz hosszabb távon.
Az interfészek definícióját a UniContract tool generálja — ez biztosítja, hogy a C#, Java és Python implementációk konzisztensek maradjanak egymással.
Mire jó ez a gyakorlatban?
Elsősorban három helyzetben értékes: ha el akarod kerülni a cloud provider lock-in-t az adatkezelési rétegben; ha különböző projektek különböző adatbázisokat használnak, de egységes fejlesztői élményt akarsz; vagy ha tesztelés során in-memory implementációval akarsz dolgozni, éles kódban pedig valódi adatbázissal.
Nem cél, hogy minden adatbázis ugyanolyan legyen — különbségek vannak, és számítanak. De a különbségek az implementációs rétegbe tartoznak, nem az üzleti logikába. Ezt az elvet valósítja meg a PolyPersist.