Jarda Jirava

Vývojář a architekt řešení postavených na technologii .net framework. Zabývám se jak vývojem webových aplikací za pomoci asp.net, tak také desktopových aplikací winform. Při návrhu řešení a samotném vývoji pak využívám dlouholetých zkušeností se zpracováním obchodní logiky a pravidel aplikací získaných z vývoje komerčních aplikací pro finanční a bankovní instituce.

Microsoft MVP

Microsoft MVP - Client App dev

Silverlight minesweeper

Get Microsoft Silverlight

Navrhi COOL design a vyhraj zkušební let po Evropě!

Poslední příspěvky

asp.net providers

7
XII

Vlastní .net provider - část 2.

Bázová třída pro RandomService

Tak abychom mohli vytvořit a dále i volat ze statické třídy RandomService konkrétní implementace, musíme ještě vytvořit abstraktní třídu, jejíž metody a případně vlastnosti budou poté implementovat konkrétní instance, které budeme tvořit, případně je vytvoří třetí strana.

Tato bázová třída má stejné metody jako statická třída, ovšem s tím rozdílem, že nejsou definovány jako statické, ale jako abstraktní. Tudíž interface takové třídy bude vypadat

public abstract class RandomBaseProvider: ProviderBase {
	public abstract int Random();
	public abstract int Random(int lowerBound, int upperBound);
	public abstract int Random(int lowerBound, int upperBound, int inicialization);
}
Samozřejmě nesmíme zapomenout na to, že tato třída musí být poděděna z ProviderBase, jinak by celé naše snažení nebylo na správné cestě a setkali bychom se s několika problémy.

Pojďme ale dále, máme vytvořeno rozhraní, výchozí třídy, které definuje přístup jakým způsobem budou volány konkrétní implementace z aplikace. Co nám tedy zbývá? Vedle napsání právě oné vlastní implementace ještě musíme zařídit, že budeme moci definovat a konfigurovat providery z konfiguračního souboru aplikace.
Je nutné říci, že abstraktní třída nemusí mít přesně stejný interface jako statická třída.

Konfigurační sekce pro vlastní provider

Již se blížíme k závěry celého našeho snažení, tato část je skutečně už jen tou pověstnou třešinkou na dortu. Zbývá nám totiž dodefinovat celkem dvě vlastnoti pro naši konfigurační třídu. Asi nemá význam se tady příliš rozepisovat, když pohled na kód řekne víc, než tisíce slov. Tady to je:

	public class RandomServiceSection: ConfigurationSection {
		[ConfigurationProperty("providers")]
		public ProviderSettingsCollection Providers {
			get {
				return (ProviderSettingsCollection)base["providers"];
			}
		}

		[StringValidator(MinLength = 1)]
		[ConfigurationProperty("defaultProvider",
				DefaultValue = "RandomProvider")]
		public string DefaultProvider {
			get {
				return (string)base["defaultProvider"];
			}
			set {
				base["defaultProvider"] = value;
			}
		}
	}

A máme vše připraveno.

Vlastně, ještě zbývá malá drobnost, samotná registrace do konfiguračního souboru a definice providerů. Toto již určitě znáte i z předchozích verzí, kdy jste si chtěli registrovat vlastní sekce v konfiguračním souboru. Tudíž nás budou v tuto chvíli zajímat oddíly configSections a především její podsekce kam přidáme definici našeho RandomServiceSection typu.

Poté už jen zaregistrovanou sekci uvedeme v život její definicí v sekci a to takto:

	
		
		
	

V této ukázce jsem zaregistroval dva providery, jeden generuje náhodná čísla pomocí třídy Random, ten druhý pak má seznam náhodných čísel uložených v databázi a vrací je postupně. Pro tento provider platí, že bude inicializován zároveń s předaným názvem connection stringu.

Závěr

Tvorba vlastního providera není příliš složitá, na co je důležité dát si pozor, aby rozhraní, které bude takový provider definovat byl pokud možno co nejvíce univerzální a nebyly do něj zahrnuty specifické - implementační - záležitosti, které by způsobily, že napíšeme pouze jednu implementaci takového provideru. Smyslem našeho snažení by měla být co největší nezávislost a možnost volby, jakým způsobem budeme implementovat požadovanou funkčnost.

Publikováno pod: asp.net providers
7
XII

Self promotion

Všechno dnes stojí na reklamě, důvtipném a neotřelém marketingu, propagaci. Tak si říkám, když už si píšu pár poznámek a něco málo vím, mohl bych toho využít a udělat si vlastní promotion.

http://providers.aspweb.cz

Tak jako několik desítek ostatních i já jsem se přihlásil do soutěže LCD za web se stránkami věnovanými Provider pattern. Snažím se na nich přiblížit popisem a příklady fungování i používání tohoto návrhového vzoru v prostředí .NET 2.0. Sám jsem tento návrhový vzor začal používat před nějakým tím časem, kdy byl k dispozici pouze .NET 1.1 a je pravda, že je dostatek situací, ve kterých se dá tohoto vzoru použít. Proto jsem si říkal, že nebude od věci zpřístupnit své znalosti i ostatním českým vývojářům. A doufat, že se mi třeba odvděčí posláním svého hlasu pod číslem 1312.

Jádrem celého webu je pak jednoduchý systém, založený na, jak jinak, provider patternu. Vlastní implementaci ContentProvideru, která umožňuje zobrazování příspěvků, jejich přidávání, stejně tak jako reakci na příspěvky. Zdrojové kódy pro tento provider budou k dispozici v blízké době. Přeci jen mé rozhodnutí přišlo takříkajíc na poslední chvíli a nerad bych dával v plén něco neodzkoušeného a neprověřeného více návštěvami.

Přeci jen jsou tyto stránky především informační, a nesnažím se myslet jen na sebe, dalšími kdo se přihlásil do soutěže byl i Tomáš Petříček, který postavil pěknou aplikaci. A přehled zajímavých řešení postavených na ASP.NET 2.0 přinesl B. Stanik T. v upoutávce Zajímavé projekty v soutěži LCDZAWEB.CZ (škoda, že jsem se do nich nevešel, že by to skutečně nikomu nic nepřineslo???).

Jenom malý povzdych na okraj

Škoda že můj poskytovatel webového prostoru zatím neumožňuje provozovat ASP.NET 2.0 stránky, určitě by to stálo za to. Navíc bych tak mohl využít a odzkoušet ten malý publikační systémek i zde.

Publikováno pod: asp.net providers , personal
7
XII

Vlastní .net provider - část 1.

Pojďme se přesunout na chvíli od vestavěných providerů k těm, které si vytvoříme podle obrazu svého. Jednotlivé kroky si předvedeme na jednoduchém příkladu.

Něco málo úvodem o ProviderBase třídě

ProviderBase třída je výchozí třídou, v případě, že chceme psát vlastní providery, stejně tak jako od ní dědí všechny dostupně providery v .NET Frameworku 2.0. Tato třída je tedy novou třídou v novém frameworku, vyznačuje se svojí jednoduchostí a obsahuje pouze minimum (jednu) metod s minimem vlastností (slovy dvě).

Nejdříve se podíváme na metodu virtual Initialize(string name, NameValueCollection config). Tato metoda nám umožňuje napsat vlastní inicializaci pro provider a to díky kolekci config ve které najdeme všechny parametry, které jsou definovány u definice providera v konfiguračním souboru. Tak jsme například získali odkaz na connectionString u prvního MsSqlSiteMapProvidera. Je nutné zdůraznit, že tato metoda, se volá pouze jedenkrát za životní cyklus a v případě vícenásobné inicializace je vyvolána výjimka InvalidOperationException. Pro všechny providery pak platí, že běhové prostředí .NETu zajišťuje (samozřejmě v případě správného použití), aby k instancování konkrétní implementace ProviderBase docházelo pouze v jednom Threadu.

Definujeme Interface našeho providera

Nyní již víme, jak budeme moci napsat vlastní implementaci pro vlastní provider, co je ovšem důležité, definovat rozhraní pro komunikaci, tak abychom mohli skutečně využít všech výhod, které nam tento návrhový vzor přináší. Pro tento účel definujeme dvě třídy.

Statická třída pro našeho providera

Statická třída představuje obecný interface, pomocí kterého budeme přistupovat ke konkrétní implementaci providera. Jak už jsem uvedl, jedná se o statickou třídu - taktéž novinku v .NET 2.0 - jejíž všechny metody a vlastnosti jsou statické.

Důležitou součástí takové třídy je inicializace providerů, kteří jsou definováni v konfiguračním souboru aplikace. Toto můžeme zajistit následující částí kódu (metodou)

private static void Initialize() {
1. if (provider == null) {
2. 	lock (lockObject) {
3. 		if (provider == null) {
4. 			RandomServiceSection section = (RandomServiceSection)WebConfigurationManager.GetSection("system.web/randomService");
5. 			providers = new RandomProviderCollection();
6. 			ProvidersHelper.InstantiateProviders(section.Providers, providers,	typeof(RandomProviderBase));
7. 			provider = providers[section.DefaultProvider];
8. 			if (provider == null)
9. 				throw new ProviderException("Unable to load default RandomProviderBase");
10.		}
11.	}
12.}
}
Projděme si jednotlivé řádky:
1.-3. kontrolujeme, zda ještě není instancován žádný provider - pro znalé představují řádky 1-3 tzv. DoubleCheckedSingleton design pattern.
4. načteme si příslušně označenou sekci z konfiguračního souboru, která obsahuje seznam dostupných providerů.
5. instancování kolekce providerů, kterou budeme používat 6. volání této konstrukce nám zajistí nainstancování všech dostupných providerů - zároveň volá metodu Initialize 7. přiřazení výchozího providera, se kterým se bude momentálně pracovat 8.-9. ošetření případu, kdy neexistuje výchozí provider

Po inicializaci providera už nám zbývá jenom definovat rozhraní, pro tento vzorový případ jsem definoval pouze jednoduché rozhraní a to metodami

  • public static int Random()
  • public static int Random(int lowerBound, int upperBound)
  • public static int Random(int lowerBound, int upperBound, int inicialization)
, které budou vracet náhodné číslo. Vím, není to úplně originální případ, doufám však, že pro demonstraci toto bude dostačovat. Obzvláště v případech, kdy budeme chtít zajistit výpočet náhodného čísla různými algoritmy.
Každá tato metoda volá příslušné metody providera následujícím způsobem
public static int Random() {
  RandomService.Initialize();
	return RandomService.Provider.Random();
}

Máme tedy definováno rozhraní v naší tříde RandomService, nyní vytvoříme druhou třídu, která bude předkem pro naše konkrétní implementace.

Publikováno pod: asp.net providers
5
XII

Přehled zdrojů pro asp.net providery

Tento příspěvek měl být prvním, ovšem jak už to tak bývá, ne vše se podaří jak má a tak se na první přehled zdrojů podívám až nyní.

Pro začátek jsem vybral zdroje, které pocházejí přímo od Microsoftu. Pojďme se na ně podívat. Asi prvním bohatým zdrojem, popisujícím veškeré dostupné Providery je ASP.NET 2.0 Provider Model: Introduction to the Provider Model. Stránka, kde doporučuji se zastavit a přečíst při svém prvním seznamování se. (Teda pokud jako první nenavštívíte tyto stránky :-).) Když už jsem se v prvním příspěvku zmínil o SiteMap provideru, určitě Vás bude zajímat i jeho implementace v podání Jeff Prosise. Ano vzal jsem si inspiraci a upravil několik věcí, které se mi na tomto provideru nelíbili.

Dále určitě stojí za pozornost dva články od Rob Howard Provider Model Design Pattern and Specification, Part 1 a Provider Design Pattern, Part 2, jež jsou poněkud staršího data, přesto stále aktuální, a já v nich měl inspiraci již pro projekty postavené na .NET 1.1.

Ale vrátím se od pouhého čtení k něčemu, co některým (snad skutečně jen výjimkám) udělá radost. Jsou to Sample Access Providers Starter Kit implementace pro Membership, Role Manager, Profile a Web Parts personalization s využitím Microsoft Access databáze. Dle mého názoru je toto pouze okrajové a nouzové řešení, neboť bych raději použil SQL Server 2005 Express Edition.

A když už jsem u toho kódu, který se dá použít, i když ne tak úplně souvisí s provider patterny v ASP.NET 2.0, nedá mi to abych je nezmínil. Jistě si někteří z Vás oblíbili Enterprise Library. Tato knihovna se již blíží do finálního release i pro .NET Framework 2.0 a usnadní nám práci díky těmto aplikačním blokům:

  • Caching Application Block
  • Cryptography Application Block
  • Logging & Instrumentation Application Block
  • Exception Handling Application Block
  • Security Application Block
  • Data Access Application Block
  • Configuration Application Block

Toť pro dnešek vše, další informace budou v průběhu zítřejšího dne ... vzhledem k pracovnímu vytížení, spíše večera.

Publikováno pod: asp.net providers
4
XII

MsSqlSiteMapProvider

Součástí instalace ASP.NET 2.0 je několik providerů. Tyto se dělí do několika oblastí, pro které zprostředkovávají rozhraní. Mezi ně patří i rozhraní pro mapu webu, neboli SiteMap Provider. Ovšem, když se podíváte důkladněji po tomto provideru, zjistíte, že co nabízí ve své základní instalaci, je pouze XmlSiteMapProvider.

XmlSiteMapProvider je vhodný v okamžiku, kdy hodláte vytvořit mapu webu pomocí xml souboru. Ovšem jsou situace, kdy toto není plně vhodné. Já osobně dávám přednost raději SQL databázi, ve které je definována struktura stránek. A tak nezbývá než napsat nového providera, a tohoto začlenit do svého projektu.

Začínáme vytvářet vlastní provider - analýza

Celý princip provider patternu je důkladně popsán na těchto stránkách. A důkladněji se mu budu věnovat v dalším příspěvku. Důležité je vědět, že pro náš SiteMap provider můžeme vycházet ze dvou abstraktních výchozích tříd. První z nich SiteMapProvider je skutečnou výchozí třídou, ze které můžeme odvozovat vlastní providery. Ovšem, pokud nechceme psát příliš mnoho kódu, a který vývojář by tomu tak chtěl, můžeme použít druhou abstraktní třídu StaticSiteMapProvider. Tato, také abstraktní, třída implementuje několik metod, které bychom museli stejně napsat a usnadňuje nám tedy množství práce. Zároveň z této třídy vychází také náš MsSqlSiteMapProvider.

Dostáváme se k vlastnímu provideru

Vlastní provider je pak už jenom implementováním několika abstraktních metod. A navržením datové struktury tabulky, ve které budou obsaženy informace o struktuře webu.

Pro návrh databázové tabulky si vezmeme inspiraci z atributů, které můžeme zapsat do xml souboru a rozšíříme je o několik nutných položek. Tabulka se tak bude sestávat z těchto sloupců:

  • SMID
  • - primární klíč tabulky, zároveň slouží jako atribut key objektu SiteMapNode
  • SMParentID
  • - je odkazem na nadřazenou úroveň, např. v rámci tohoto webu je na nulté úrovni název Providers na první úrovni pak seznam všech výchozích providerů.
  • NodeOrder
  • - je pořadí příslušného nodu v dané úrovni. Tento atribut slouží pouze pro seřazení struktury na výstup.
  • Title
  • - je titulek, který se zobrazí uživateli a je mapován na stejně znějící atribut.
  • Url
  • - představuje odkaz na stránku v rámci webu.
  • Description
  • - jak už název napovídá, slouží pro popis odkazu. Pokud je tento popisek vyplněn, zobrazí se jako vyskakovací nápověda po najetí na odkaz.
  • Roles
  • - tento atribut je použit v případě nastavení property atributu SecurityTrimmingEnabled na hodnotu true. A umožňuje řízení oprávnění přístupu k webu.
  • ResourceKey
  • - nebyl by to pořádný web, který by nesloužil pouze pro jednu zemi. Takže toto je možnost, jak i menu lokalizovat.
  • Obsolete
  • - a samozřejmě můj oblíbený sloupec, který používám snad ve všech tabulkách. Nikdy totiž nevíte, jestli nebudete chtít příslušný záznam "schovat" před ostatními a přitom jej ponechat v databázi.

Takže strukturu databáze máme, přejdeme k napsání vlastního provideru. Jelikož jsem se rozhodl použít za výchozí třídu StaticSiteMapProvider, mám již spoustu kódu napsánu a tak mi zbývá implementovat jen několik málo metod.

Hned první je metoda Initialize(string name, NameValueCollection config). Zde doplníme kód pro získání připojovacího řetězce pro připojení k databázi, ve které se nachází výše zmíněná tabulka, pojmenovaná [SiteMap]. Další metodou, jejíž implementaci je nutné dopsat je SiteMapNode BuildSiteMap(), vracející kořenový nod našeho webu, většinou tedy default.aspx. Tato metoda načte strukturu webu z tabulky databáze a vytvoří příslušný strom, tak jak bude zobrazen na straně klienta. A to je vlastně téměř vše co musíme napsat, abychom získali vlastní SiteMapProvider.

Používáme vlastní SiteMapProvider

Napsali jsme vlastní provider, ale jak jej použít? Je to celkem jednoduché, chvilku se budeme zabývat souborem web.config. V jeho sekci přidáme definici pro náš vlastní provider. Ta může vypadat následovně

	
		
			
		
V připadě, že jsme předtím používali například XmlSiteMapProvider na svých stránkách, máme hotovo a struktura webu se nám rázem, samozřejmě po uložení souboru, bude načítat z nového úložiště. Jestliže začínáme psát nový web, pak musíme pro zobrazení nového menu použít příslušné ovládací prvky. Ale to si nechám zase na příště.
Publikováno pod: asp.net providers