Možná už znáte koncept tzv. headless CMS systémů a náš produkt Kentico Kontent.
Možná také víte, že weby a aplikace v .NET mohou využívat obsah z Kentico Kontent zasazený do tzv. silně typovaných modelů. Ukážeme vám výhody a způsob použití silných typů z našeho Delivery .NET SDK. Na co se můžete těšit?
- Výhody, generátor typů
- Získávání silně typovaného obsahu
- Implementace dědičnosti (tento díl)
- Typování za běhu – proč (již brzy)
- Typování za běhu – použití (již brzy)
Jak si poradit s implementací dědičnosti?
Další zajímavé téma, které se týká silného typování, je dědičnost. V tuto chvíli ještě typy obsahu (content types) v Kentico Kontent nepodporují dědičnost – zkrátka od sebe neumějí dědit elementy a jiná nastavení. To nám ale nezabránilo, abychom přišli s rozumnou implementací dědičnosti na straně klientské aplikace.
Pojďme si to ukázat na příkladu.
V naší ukázkové MVC aplikaci máme typy obsahu Coffee (káva), Brewer (kávovar), Grinder (mlýnek) a Accessory (příslušenství). Všechny tyto typy představují nějakou formu produktu. A všechny mají společné tyto properties:
- Product name
- Price
- Image
- Product status
- Short description
- Long description
Pokud bychom změnili property v jednom typu obsahu, ostatní typy obsahu to neovlivní. Proto se naše SDK a generátor typů chovají stejně a nesnaží se vztahy dědičnosti samy implementovat. Implementaci dědičnosti můžete provést v kódu klientské aplikace.
Jak tedy zařídit, abyste mohli upravovat a odkazovat se na jednu společnou property namísto několika samostatných?
Generátor typů vytvoří například tyto dvě jednoduché třídy:
public partial class Coffee
{
public string ProductName { get; set; }
}
public partial class Brewer
{
public string ProductName { get; set; }
}
Za této situace už nemůžete napsat společnou nadřazenou (base) třídu Product se stejnou property ProductName a dědit z ní:
public class Product
{
public string ProductName { get; set; }
}
Existují dva způsoby, jak z kruhu ven
První a jednodušší cestou můžete jít, pokud budete v aplikaci chtít pracovat pouze s těmi properties, které se nacházejí ve všech typech obsahu. Druhou, lehce náročnější cestu zvolte ve všech ostatních případech.
1) První způsob: deserializace do nadřazeného typu
Tímto jednodušším způsobem zajistíte, že budete moci pracovat s property ProductName u typu Product, ne u typů Coffee, Brewer atd. Stačí napsat třídu Product se společnými properties, opatřit je JsonProperty atributy nesoucími kódové názvy elementů v Kentico Kontent:
public class Product
{
[JsonProperty("product_name")]
public string ProductName { get; set; }
[JsonProperty("price")]
public decimal? Price { get; set; }
// Jiné properties ...
}
I přesto, že v Kentico Kontent nemáte žádný typ obsahu Product, dokáže náš výchozí CodeFirstPropertyMapper při každém API requestu svázat vaše properties s odpovídajícími elementy podřízených typů obsahu jako Coffee nebo Brewer. Díky tomu můžete získat kolekci objektů Product standardním voláním metody GetItemsAsync:
List<Product> brewersAndCoffeeAsProducts = (await client.GetItemsAsync<Product>(new InFilter("system.type", "brewer", "coffee"))).Items.ToList();
Je ovšem dobré dát si pozor, aby elementy ve podřízených typech obsahu byly pojmenovány konzistentně – pokaždé jako ProductName.
2) Druhý způsob: doprovodné properties
Druhý – trochu náročnější způsob vám dovolí, abyste v kódu dále používali nejen properties, které jsou všem typům společné, ale i ty ostatní properties. Pokud tedy potřebujete se získaným obsahem pracovat nejen jako s typem Product, ale i jako například s typem Coffee, zvolte tento způsob.
Nejprve je potřeba podřízeným třídám nastavit dědění z nadřazené (Product). V podřízených třídách byste pak měli přidat ke společným properties jejich doprovodné, které obalí ty původní:
public partial class Coffee : Product
{
public override string ProductProductName
{
get { return ProductName; }
set { ProductName = value; }
}
public override decimal? ProductPrice
{
get { return Price; }
set { Price = value; }
}
// Ostatní properties ...
}
Od této chvíle je možné volat důvěrně známou metodu GetItemsAsync, tentokrát však s typovým parametrem <object>. (Takový způsob volání jsme si interně nazvali „typování za běhu“; dočtete se o něm příště.)
var brewersAndCoffeeAsProducts = (await client.GetItemsAsync<object>(new InFilter("system.type", "brewer", "coffee"))).Items;
Díky tomu už bude možné dělat obojí: jak pracovat jednotným způsobem se všemi společnými properties, tak přistupovat i ke všem ostatním.
foreach (var product in brewersAndCoffeeAsProducts)
{
product.ProductProductName += " (discounted)";
if (product is Coffee)
{
product.ShortDescription += " The price is now lower, the aroma stayed the same.";
}
}
A co dál? To je na vás
V tomto díle jste se dozvěděli, jak mít dědičnost v klientské aplikaci i přesto, že ji Kentico Kontent ještě prozatím nepodporuje. To se ale může velmi rychle změnit, hlavně podle vašich přání. Jakmile podporu dědičnosti zavedeme, můžete například připomínkami nebo vlastním kódem ovlivnit, jak bude dědičnost vypadat v Delivery .NET SDK a generátoru typů.
Jak vidíte, skvělé headless CMS v cloudu můžete vytvářet s námi.
Zajímá vás, jak to u nás chodí, a chcete vědět všechno mezi prvními? Sledujte nás na Facebooku, LinkedIn nebo Instagramu.