Tuesday, 21 September 2004
Malá programátorská hádanka
Máte následující kód:
class
Test : BaseTest
{
private
string
m_rene;
public
Test() :
base
()
{
m_rene = "Rene";
}
public
override
void
WriteName()
{
Console.WriteLine(m_rene);
Console.Read();
}
}
Metoda WriteName vypíše za určitých podmínek jen prázdný řetězec - víte kdy? ;)
Update: A víte, jak se bude chovat stejný kód po přepsání do C++?
Tuesday, 21 September 2004 15:32:00 (Central Europe Standard Time, UTC+01:00)
Programátorské hádanky
Monday, 20 September 2004
Česká .Net Developer Group nabírá dech
Jak už psal Michal, dneska se uskutečnilo první setkání české .Net Developer Group. K jeho postřehům bych jen dodal, že mě jakožto skeptika, co se týče úspěšnosti pořádání kolektivních akcí pod egidou velkých společností jako je Microsoft, příjemně překvapil počet účastníků, a hlavně to, že většina z nich nebyla všemu pasivně přitakávající zasmušilou většinou, která vévodí většině oficiálních seminářů a přednášek, ale že se se (skoro) všichni podíleli na vytváření programu dalších setkání.
Jestliže tedy nechcete potkávat své kolegy jen ve virtuálním prostoru internetu a nejste naprostí asociálové opevňující se s hysterickými vzlyky ve svém domě i při zmínce o návštěvě blízkého příbuzného, tak přijďte na další setkání, které se bude konat přibližně za měsíc a jehož tématem je bezpečnost v .Net Frameworku. O bezpečnosti bude přednášet Honza Šeda.
Honzovi Šedovi také patří pořádný dík za to, že si .Net Developer Group vymyslel, prosadil a celé první setkání v Microsoftu zorganizoval.
Monday, 20 September 2004 21:52:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework | Ostatní
ADSL versus CDMA
Uvažuji, že své pomalé GPRS připojení vyměním za něco lepšího, protože mám konečně v dosahu ADSL i CDMA.
Po srovnání obou technologií a hlavně jejich perspektivy se mi víc zamlouvá ADSL, ale ta má jednu velkou nevýhodu - je poskytována Českým Telecomem, jehož rozhodnutí o rozvoji broadband internetu mají jedinou logiku - logiku maximalizace zisku za každou cenu v co nejkratším časovém období a na úkor rozvoje celé služby. Kvůli laxnosti Telecomu při instalaci DSlamů, kdy jsem byl neustále krmen jen velkohubými PR zprávami o lepšící se infratruktuře Telecomu, jsem v únoru už dlouho předtím nepoužívanou pevnou linku odhlásil. A teď bych si jí měl zase zřídit, jak já nesnáším monopol :(
Vím, že s Eurotelem Telecomu neuteču, ale ke kompletnímu manažerskému ovládnutí Eurotelu Telecomem a k telekomunizaci celé cenové politiky a firemní strategie Eurotelu snad zatím nedojde a po prodeji Telecomu se, alespoň doufám, obě společnosti opět rozdělí. (spekulace vychází z modelového scénáře, že Eurotel koupí Orange, který se chce Telecomu ihned zbavit).
Takže bych vás chtěl poprosit, abyste mi v komentářích napsali své zkušenosti s oběma technologiemi i vaším doporučením, abych měl rozhodování lehčí. Díky ;)
Monday, 20 September 2004 08:03:00 (Central Europe Standard Time, UTC+01:00)
Ostatní
Sunday, 19 September 2004
Rychlá instalace všech aplikací na MDA II (XDA II) po tvrdém restartu
Nevím jak vy, ale já na svém Pocket PC nesnáším stav po tvrdém resetu, kdy musím znovu a znovu instalovat desítky programů, které používám. Windows Mobile 2003 jsou sice navzdory pochybovačným křiklounům stabilní a kvalitní operační systém a kvaziargumenty křiklounů jen je samotné usvědčují z toho, že za perfektní PDA považují jakoukoli programovatelnou kalkulačku, hlavně když je bez démonického systému Microsoftu, a do extatického křepčení kolem zlatého telete je dostane pouze fakt, že jde navíc o kalkulačku osedlanou Linuxem, ale experimentování s málo zdokumentovaným RIL protokolem dokáže i moje MDA II spolehlivě složit. U MDA II naštěstí nemusíte s otráveným obličejem instalovat všechny programy, ani nemusíte dbát na pravidelné a zdlouhavé zálohování celého zařízení, protože instalaci programů lze po tvrdém resetu spustit z Extended ROM.
Extended ROM je neveřejná část vestavěné flash paměti, která je vyhrazena pro mobilní operátory. Mobilní operátoři do této paměti umisťují programy (u TMO jde například o GPRS monitor), českou lokalizaci nebo témata na Today obrazovku se svým logem. Extended ROM je uzamčena pro zápis a v seznamu složek na PDA není vidět. Druhou část flash paměti, kterou asi používáte, je takzvaná Storage. Storage je volně přístupná uživateli a je určena k zálohování dat, o něž nechceme přijít po tvrdém resetu. Do Storage i do Extended ROM můžeme také nakopírovat CAB soubory, které budou nainstalovány po tvrdém restartu zařízení. Aby byly programy nainstalovány, neobejdeme se bez zásahu do Extended ROM a hlavně do "magického" souboru config.txt.
Upozornění: I když jde o zcela nesmyslné opatření servisu, zásahem do Extended ROM přicházíte o záruku. Proto si nejdříve obsah originální Extended ROM zazálohujte na počítači a před zanesením zařízení do servisu obnovte zálohu, zamkněte a skryjte Extended ROM - v servisu pak žádné provedené úpravy nepoznají a vaše oprava bude provedena v rámci záruky. Úpravu Extended ROM provádíte na vlastní odpovědnost a já neodpovídám za žádná případná poškození zařízení. (ale to jste určitě ode mě ani nečekali;) )
1) Stáhnete si a nainstalujte na MDA II Extended ROM Unlocker. Extended ROM Unlocker je nástroj, který zpřístupní a odmkne Extended ROM. Po instalaci najdete zástupce programu s výmluvnými názvy Hide, Unhide, Lock, Unlock v menu Programy pod složkou Extended ROM Tools. Zveřejněte (Unhide) a odemkněte (Unlock) Extended ROM. Resetujte (měkký reset) zařízení, abyste viděli složku Extended ROM.
2) V Extended ROM jsou hlavně CAB soubory operátorů, ale nás bude zajímat soubor config.txt. Config.txt je obyčejný textový soubor, který obsahuje příkazy vykonávané jednoduchým interpreterem autorun.exe po tvrdém resetu MDA II. Modifikací souboru config.txt můžeme instalovat další programy, které jsou umístěny v Extended ROM, ve Storage nebo na paměťové SD kartě (Storage Card) a odstraněním instrukcí operátora nebo výrobce se zase zbavíme automatické instalace programů, které stejně ihned po restartu odebíráme.
Instalaci CAB souboru si vynutíme zadáním prefixu CAB:, za který doplníme cestu k CAB souboru.
Instalace CABu umístěného v Extended ROM:
CAB: \EXTENDED_ROM\tcmdpocket.exe
Instalace CABu umístěného v Storage
CAB: \STORAGE\tcmdpocket.exe
Kromě instalace CAB souborů, můžete potvrdém restartu automaticky kopírovat soubory. Takže je snadné přidat třeba nového zástupce do Startup složky.
Za prefixem CPY1: zadáme cestu ke kopírovanému (zdrojovému souvoru)
Za prefixem CPY2: zadáme cestu k cílovému souboru
CPY1:\STORAGE\totalcmd.lnk
CPY2:\Windows\StartUp\totalcmd.lnk
Příkazem RST: Reset v config.txt si vynutíme měkký reset.
Nyní můžete bez obav provést tvrdý reset zařízení a všechny programy (bez dat!) budete mít za chvíli nainstalovány.
Tip na závěr: Z config.txt odstraňte volání nepovedených programů TPEnable.exe a TPDisable.exe. Jejich úkolem je po dobu instalace programů nepovolit vstupy uživateli - bohužel tyto prográmky jsou občas příčinou "zamrznutí" zařízení a také se nehodí, když CAB soubor vyžaduje potvrzení některých instalačních kroků.
Sunday, 19 September 2004 16:38:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Thursday, 16 September 2004
Vytvářejte se mnou aureolu dobrého weblogu
Můj blog rozmnožuje informační entropii již několik měsíců, a protože souhlasím s Radkem Hulánem, že dobrý weblog je navštěvovaný weblog, chci dát v tomto spotu prostor vám, čtenářům, abyste mi pomohli dotvářet jeho podobu, která bude více zajímavá pro vás i pro mě.
Za těch pár měsíců, co se spolu potkáváme na weblogu, jste mohli už částečně poznat, co mě zajímá, z čeho jsem nadšený i jaké animozity v sobě živím. Weblog jako žánr vyžaduje, aby v něm autor nabídl svoje osobité vidění problematiky, a to i problematiky odborné, a ne aby byl vzdálenou dvouřádkovou ozvěnou novinek právě rezonujících všemi informačními kanály na internetu nebo ochraptělou a omezenou hlásnou troubou jedné minoritní komunity. Od počátku se snažím i podtitulkem naznačit, že weblog je pro mě hlavně střet - nejen veřejný verbální střet mezi mnoha soupeřícími podobami mého ega (myšleno psychologicky, ne pejorativně ;) ) ve spotech , ale také střet mezi mými a vašimi názory, střet s jinými bloggery nebo autory. Nechci být jedním z mnoha bloggerů na doméně Vyvojar.cz, ale chci a snažím se, abyste po otevření směsice spotů na blog.vyvojar.cz poznali, který příspěvek jsem napsal já. Je to neskromné? Asi ano, ale kdybych o to neusiloval, tak nemusím psát weblog - nezaměnitelná aureola dobrého weblogu je podle mě konstituována jen a pouze originálními příspěvky jeho autora.
Proto bych chtěl slyšet váš názor na můj blog.
Zajímalo by mě, proč právě vy chodíte na můj weblog a jaké rysy vás na něm přitahují, co vás nudí nebo dokonce odpuzuje a co by vás nejvíce z témat, o nichž víte, že mě baví, zajímalo. Vaše reakce mi usnadní rozhodnutí, co by se s blogem mělo dít dál. V poslední době čím dál častějí přemýšlím o přesunu svych aktivit na vlastní doménu, i když by těsná spolupráce s Vývojářem v jiné podobě trvala určitě dále.
Co mě k rozhodnutí založit si vlastní doménu vede?
- Můj blog se netýká jen .NETu a i když Michalovi tématicky odlišné příspěvky nevadí, tak si nejsem jist, zda neodrazují jiné návštěvníky serveru Vyvojar.
- Na blogovacím systému .Text se mi nelíbí, že do RSS exportuje celé spoty.
- Na vývojáři není funkční stránka pro zasílání emailu přes odkaz Contact.
- Nové příspěvky pod spoty nejsou zasílány emailem. Nejen kvůli těmto nevýhodám uvažuji, že jako blogovací systém nepoužiji .Text v jeho "čisté" podobě.
- Na blogu nemám jednoduše dostupné úložiště pro obrázky a zdrojové kódy. Michal na požádání sice ochotně všechny artefakty na server umístí, ale přeci jen vlastní a vždy dostupné úložiště by bylo lepší.
- Na mých stránkách nechci mít jen blog, ale také stránky s regulérními články, poradnu pro zajímavé dotazy a když bude z vaší strany zájem, tak i třeba komerční sekci s e-booky na aktuální vývojářská témata.
Takže neváhejte a pořádně me zkritizujte, abych věděl, co musím se svým blogem udělat ;)
Thursday, 16 September 2004 21:15:00 (Central Europe Standard Time, UTC+01:00)
Ostatní
Wednesday, 15 September 2004
Živě učí staré psy staré kousky
Živě zahájilo s obrozeneckým nadšením seriál o VB.NET. Nadšení serveru pro nové jazyky a polopatické vzdělávání svých čtenářů se ale ve své aktuální podobě stávají pro seriál sudičkami se smrtícími kletbami ve své bezzubé hubě.
Autor seriálu Milan Petřík se rozhodl, že postaví na hlavu všechna didaktická pravidla, která říkají, že vysvětlování nového tématu s odlišným viděním problému by nemělo být budováno na předchozích zastaralých znalostech, a raději nám předkládá svoji vizi "jednoduchého" VB jako chameleona proplouvajícího napříč technologiemi již léta skoro beze změny. To, že VB.NET je jen marketingový název Microsoftu pro jazyk budovaný na zcela jiných principech nez VB6 a nižší verze, který se svými zastaralými předchůdci sdílí některé méně významné syntaktické konstrukce, a že jen pro nepoučitelné nostalgiky je vytvořen jmenný prostor Microsoft.VisualBasic, s jehož pomocí je způsob kódování ve VB.NET degradován na hybridní VB6/.NET styl, nemusím návštěvníkům mého blogu asi připomínat.
Autor veškeré připomínky ke svému seriálu odmítá alibistickým poukazem na to, že prvních 10 dílů seriálu je určeno úplným začátečníkům, a proto nevysvětluje hned některé pokročilé, ale zásadní koncepty (třeba třídy, jmenné prostory), které přesahují ohraničený svět VB.NET. Alibistické je to proto, že se sice dle svých slov vyhýbá teoretickému vysvětlování některých pojmů, ale to mu nebrání, aby nás hned ve druhém dílu seriálu nepoučil o o logickém členění programu do modulů (Proč Microsoft před programátory skrývá své sladké tajemství, že modul ve VB.NET je jen třída se statickými metodami a syntaxe modulu je rozvinuta do třídy teprve kompilátorem?) a procedur a v zatím posledním díle se zase rozhodne, že jeho čtenáři jsou již dostatečně vyspělí, aby pochopili konstrukci Try - Catch (a to vše ještě před řídícími konstrukcemi jazyka!), ale aby jejich chápavé obvody v mozku nepřetížil, tak jim taktně zamlčí existenci klíčového slova Finally.
Dalšími lapsy jsou neustálé vypisování celé hierarchie jmenných prostorů nebo utvrzování začátečníka, že používání "magických" čísel místo konstant je v pořádku. Seriál je rozvleklý, těžkopádný a skáče bez jakékoli logické souvislosti z tématu na téma.
Shrnu-li to. Za seriálem není znát žádná myšlenková osnova a působí na mě dojmem, že si někdo v Živě řekl "No ten .Net už je docela rozšířenej, jeden děsnej seriál pro začátečníky o PHP už máme, a protože jsme server pro masového čtenáře, tak vytvoříme i podobný seriál ve VB.NET (jako bumerang se zde Microsoftu vrací, že VB má pověst lidového jazyka :), pozn. aut. ) a seženeme někoho, kdo dokáže žoviálně podat, jakej je ten VB.NET pohodovej jazyk fakt pro každou lamu".
Komu je seriál určen, opravdu netuším. Napadli mě jen ortodoxní příznivci programování v Basicu na nezastarávajícím stroji Didaktik Gamma, kteří se pod tlakem doby rozhodli migrovat na na PC a .NET. Ale že by tvořili tak početnou skupinu, aby se pro ně vyplatilo vytvářet seriál? :)
Wednesday, 15 September 2004 07:55:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework | Ostatní
Monday, 13 September 2004
Http modul pro změnu URL adresy ve WSDL webové služby
Webové služby v ASP.NET generují dynamické WSDL, ve kterém je adresa služby (obsah elementu soap:address) dynamicky určena podle url původního požadavku. Například při použití reverzní proxy by se hodilo určit adresu ve wsdl dokumentu staticky a přitom stále ponechat na ASP.NET generování většiny elementů ve wsdl dokumentu.
K tomuto účelu jsem napsal http modul pro změnu adresy. V kódu se předpokládá, že nové url webové služby je zadáno ve web.config v sekci appSettings pod klíčem newUrl a že k službě je přistupováno pouze přes protokol SOAP.
using System;
using System.Web;
using System.IO;
using System.Xml;
using System.Diagnostics;
namespace RSTEIN.HttpModules
{
///
/// Modul pro změnu
///
public class ChangeUrlModule : IHttpModule
{
#region private constants
private const string WSDL_REQUEST = "wsdl";
private const string SOAP_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/soap/";
private const string SOAP_PREFIX = "soap";
private const string LOCATION_NAME = "location";
private const string ADDRESS_NAME = "address";
#endregion private constants
#region private variables
private readonly string m_newServiceUrl;
#endregion private variables
#region Constructors
///
/// Konstruktor
///
public ChangeUrlModule()
{
m_newServiceUrl = System.Configuration.ConfigurationSettings.AppSettings["newUrl"];
}
#endregion Constructors
#region IHttpModule Members
///
/// Inicializace modulu - Součást rozhraní
///
///
public void Init(HttpApplication context)
{
if (m_newServiceUrl != String.Empty)
{
context.BeginRequest +=new EventHandler(context_BeginRequest);
context.EndRequest +=new EventHandler(context_EndRequest);
}
}
///
/// Součást rozhraní
///
public void Dispose()
{
}
#endregion
#region private methods
//Zapsání jiného URL
private void context_EndRequest(object sender, EventArgs e)
{
string path = HttpContext.Current.Request.RawUrl.ToLower();
if (isWSDLRequest())
changeUrl();
}
//Změna Url www služby
private void changeUrl()
{
HttpResponse response = HttpContext.Current.Response;
XmlDocument doc = new XmlDocument();
MemoryStream originalStream = ((FilterStream)response.Filter).InnerStream;
originalStream .Position = 0;
try
{
XmlTextReader reader = new XmlTextReader(originalStream);
doc.Load(reader);
}
catch (Exception e)
{
Trace.WriteLine("Invalid response");
return;
}
XmlNamespaceManager namManager = new XmlNamespaceManager(doc.NameTable);
namManager.AddNamespace(SOAP_PREFIX, SOAP_NAMESPACE);
XmlNode locationNode = getLocationAttribute(doc);
locationNode.Value = m_newServiceUrl;
response.Clear();
doc.Save(response.Output);
}
//Vyhledání atributu location elementu soap:address
private XmlNode getLocationAttribute(XmlDocument doc)
{
XmlNode addressNode = doc.GetElementsByTagName(ADDRESS_NAME, SOAP_NAMESPACE)[0];
return addressNode.Attributes["location"];
}
#endregion private methods
//přiřazení filtru na objekt Response
private void context_BeginRequest(object sender, EventArgs e)
{
if (isWSDLRequest())
HttpContext.Current.Response.Filter = new FilterStream(HttpContext.Current.Response.Filter);
}
//Kontrola, zda se jedná o WSDL požadavek
private bool isWSDLRequest()
{
string path = HttpContext.Current.Request.RawUrl.ToLower();
if (path.EndsWith(WSDL_REQUEST))
return true;
return false;
}
}
}
O významu http modulů a jejich registraci ve web.config se více dočtete v mém starším článku na Interval.cz.
Monday, 13 September 2004 15:12:00 (Central Europe Standard Time, UTC+01:00)
Web Services
Sunday, 12 September 2004
Několik zkušenosti s merge replikací na MSSQL proti SQL serveru CE (PDA)
Merge replikace na MSSQL proti SQL Serveru CE má svůj půvab, který ale odhalíte až po projití minového pole nástrah, o nichž v dokumentací naleznete jen pár sporadických zmínek. Spot jsem napsal proto, abych vás před nástrahami kapriciozních tvůrců CE replikací varoval a v některých případech nabídl i dočasné řešení.
1. Jestliže máte nainstalován na MSSQL Service Pack 3, nainstalujte podporu pro CE replikace na serveru z instalačního balíčku, který si můžete stáhnout zde.
2. Pro CE klienty je podporována jen "merge" replikace. Vytvoření publikace s podporou pro CE klienty je snadné - v průvodci "Create publication wizard" na formuláři "Specify subscriber types" zaškrtněte "Devices running SQL Server CE". Při manuálním vytváření publikace proceduru sp_addMergePublication nastavte argument @sync_mode na N'character' a povolte vytváření "subscription" anonymním klientům (@allow_anonymous = N'true').
3. Jestliže používáte dynamické filtry (to znamená, že filtrujete replikovaná data například podle Id uživatele), tak musí být v replikaci povolena optimalizace přenášených dat na klienta. V průvodci na formuláři "Optimize synchronization" zvolte "Yes, enable data optimization” . Alternativně v proceduře sp_addMergePublication nastavte argument @keep_partition_changes na true.
4. CE klienti NEPODPORUJÍ komprimované snapshoty, proto tuto volbu nikdy nezapínejte.
5. Po instalaci SQL Server CE 2.0 na serveru spustťe MMC konzoli SQL Server Connectivity Managament a vytvořte nový virtuální adresář. Na záložce Http Content Folder vyberte adresář, ve kterém je knihovna sscesa20.dll, která zpracovává požadavky na replikaci od PDA klientů. Virtuální adresář musí mit nastaveno právo Execute, takže MMC konzole vám toto právo nedovolí upravovat. Na záložce Http authentication si můžete vybrat vyžadovaný typ autentizace přistupujících klientů - jestliže se rozhodnete pro anonymní přístup, můžete kliknutím na tlačítko Edit... vybrat účet, pod kterým bude knihovna sscesa20.dll přistupovat ke zdrojům počítače. Na záložce NTFS permissions můžete upravit práva, která jsou přidělena účtu, pod kterým běží IIS - většinou ale není nutné s právy manipulovat, protože průvodce si sám nastaví potřebná práva a nedovolí je přes konzoli změnit. Jen pro upřesnění – IIS replikační agent nemusí být nainstalován na serveru, na němž běží MSSQL s publikací.
6. Dostupnost IIS aplikace si ověříte zadáním adresy souboru sscesa20.dll (například http://RSTEIN2/sqlserverce/sscesa20.dll). Jestliže je soubor správně nainstalován, zobrazí se text "SQL Server CE Server Agent". Když se vám zobrazí chybové hlášení nebo dokonce prohlížec nabídne stažení knihovny, přeregistrujte dll zadáním regsvr32 /i sscesa20.dll.
7. Do databáze s publikací musí mít uživatel povolen přístup a současně musí být uživatel přidán do PAL (Publication Access List) ve vlastnostech publikace. O jakého uživatele se ale jedná?
a) Jestliže používáte v IIS aplikaci anonymní autentizaci a pro přístup k MSSQL Windows autentizaci, přístup do databáze a umístění do PAL se týká uživatele, pod nímž běží IIS replikační agent (IUSR_NazevPocitace nebo účet vybraný v bodě 5).
b) Při "Basic" nebo "Integrated Windows" autentizaci uživatele v IIS aplikaci a Windows autentizaci do MSSQL, musí být povolen přístup do databáze a sočasně přidán záznam do PAL pro všechny uživatele, kteří replikaci provádějí.
c) Při SQL autentizaci do MSSQL je do PAL přidán příslušný SQL účet, kterému je také povolen přístup do databáze.
8. Snapshot publikace by měl být generován do vlastní složky, která je sdílena po síti a má nastavena minimální potřebná práva. Výchozí složka pro snapshoty je po síti totiž dostupná jen přes "administrátorské sdílení" (jméno disku se znakem dolaru na konci).
Složku se snapshotem určíte ve vlastnostech publikace na záložce Snapshot loation. Zaškrtněte volbu "Generate snapshots in this location" a do textového pole Folder zadejte název složky (například \\RSTEIN2\PDAREPLIKACE\PDA_FULL). Při zakládání publikace metodou sp_addMergePublication určete alternativní umístění snapshotu argumentem @alt_snapshot_folder. (@alt_snapshot_folder = '\\RSTEIN2\PDAREPLIKACE\PDA_FULL' ).
Na složce, do které je generován snapshot, musejí být nastavena tato práva.
a. Účty, pod kterými běží služby SQL Server a SQL Server Agent, musejí mít nastaveno plné řízení (Full control).
b. Jestliže používáte v IIS aplikaci anonymní autentizaci, musí mít anonymní účet právo "Read".
c. Jestliže používáte v IIS aplikaci "Basic" nebo "Integrated Windows" autentizaci, musejí mít všechny přistupující účty právo "Read".
9. Ke správě a řízení zařízení na PDA je možné vytvořit odlehčenou verzí replikačního manažera, kterého jsem popisoval v jiném spotu. CE replikační manažer má své zvláštnosti, protože například dotaz na dostupnost MSSQL je nesmyslný, poněvadž CE replikace komunikují jen s replikačním agentem v IIS. Namísto dotazu na MSSQL tedy vytvoříme GET požadavek na soubor sscesa20.dll a zkontrolujeme, jestli se nám vrátil řetězec "SQL Server CE Server Agent".
10. Nepříjemným omezením (chybou) v SQL serveru CE 2.0 je podpora pouze maximálně jedné "subscription" v jedné databázi. Přesněji řečeno - před začátkem práce na projektu jsem si ověřoval, jestli mi SQL CE server bude podporovat dvě "subscription", protože jsem chtěl vytvořit dvě publikace v jednoé databázi. Jedna z nich by byla filtrovaná, druhá nefiltrovaná, což je v souladu s doporučeními v MSDN, jež se zabývají optimalizacemi replikací. Vytvořil jsem tedy dvě zkušební "subscription" v jedné CE databázi a vše proběhlo bez problémů. Problém se vyskytl až při pokusu o první replikaci. První "subscription" byla úspěšně synchronizována se serverem a byl doručen snapshot, při synchronizaci druhé "subscription" byla vrácena chyba "Invalid subscription", která je ale natolik obecná, že jsem nejdříve několikrát generoval znovu snapshot na serveru a zkoušel zakládat nové "subscription". Jako poslední zoufalcovo gesto jsem prohodil pořadí synchronizace obou subscription - synchronizace druhé (původně první) "subscription" selhala. Takže i když se CE server „tváří“, že podporuje paralelně více subscription, nevěřte tomu a adekvátně upravte svůj návrh publikace.
11. API pro replikaci v compact .NET Frameworku představuje rozhraní třídy SqlCeReplication,
Příklad práce s objektem SqlCeReplication:
Vytvoříme pomocnou metodu, abychom měli v replikačním manažeru na jednom místě inicializaci vlastností instance třídy SqlCeReplication.
private SqlCeReplication getDefaultReplicationClass()
{
SqlCeReplication replication = new SqlCeReplication();
//Připojovací řetězec k CE databázi
replication.SubscriberConnectionString = m_connectionString;
//URL IIS agenta (souboru sscesa20.dll)
replication.InternetUrl= m_internetURL;
//Libovolný řetězec, který bude na serveru použit k filtrování tabulek (článků) - v MSSQL hodnotu vlastnosti vrátí funkce HOST_NAME.
replication.HostName = m_hostNameValue;
//Libovolný unikátní identifikátor jednoho PDA klienta
replication.Subscriber = m_subscriberValue;
//Když není prázdné heslo, tak je zvolena "basic" nebo "anonymní" autentizace V IISreplikačním agentovi
if ((m_internetUserPassword != String.Empty) &&
(m_internetUserPassword != null))
{
//Přihlašovací jméno uživatele (IIS replikační agent)
replication.InternetLogin = m_internetUserName;
//Heslo uživatele (IIS replikační agent)
replication.InternetPassword = m_internetUserPassword;
}
//Název databázoveho serveru s publikací
replication.Publisher = m_remoteServerName;
//Název databázoveho serveru s publikací
replication.PublisherDatabase = m_remoteDatabase;
//Název publikace
replication.Publication = m_publicationName;
//Typ autentizace k MSSQL (NT nebo SQL)
replication.PublisherSecurityMode = this.m_serverSecurityMode;
//Jestliže je zvolena SQL autentizace k MSSQL, doplníme jméno a heslo
if (m_serverSecurityMode == SecurityType.DBAuthentication)
{
//Přihlašovací jmeno k SQL serveru (SQL účet)
replication.PublisherLogin = m_serverLoginName;
//Heslo k SQL serveru (SQL účet)
replication.PublisherPassword = m_serverLoginPassword;
}
//Vrácení inicializovaného objektu SqlCeReplication
return replication;
}
Metoda pro spuštění replikace.
public bool RunReplication(bool reinitialise)
{
//Resetování členské proměnné,která nese informaci o počtu provedených změn při poslední replikaci
m_totalChanges = 0;
//Získání inicializovaného objektu SqlCeReplication SqlCeReplication ceReplication = getDefaultReplicationClass();
//Podmíněná reinicializace "subscription" (=vynucení si opětovného dodání snapshotu)
if (reinitialise)
{
ceReplication.ReinitializeSubscription(true);
}
try
{
//Metodou Synchronize spustíme replikaci dat. Předtím můžete ještě voláním ceReplication.CreateSubscription založit „subscription“ před první synchronizací. V replikačním manažeru spravují „subscriptions“ speciální metody.
ceReplication.Synchronize();
//Celkový počet změn je součtem změn provedených na klientovi a serveru
m_totalChanges += (ceReplication.PublisherChanges + ceReplication.SubscriberChanges);
return true;
}
catch (Exception e)
{
//Jestliže došlo k chybě, naplníme členskou proměnnou m_lastReplicationError s popisem chyby pro prostého uživateli
m_lastReplicationError = STATIC_REPLICATION_ERROR_MESSAGE + Environment.NewLine + e.Message;
return false;
}
finally
{
//Objekt SqlCeReplication používá neřízené prostředky, proto zavoláme jeho metodu Dispose.
if (ceReplication!= null)
{
ceReplication.Dispose();
}
}
}
Tento kód předpokládá, že MSSQL server s rolí „publisher“ je současně i „distributor“ publikace.
12. Jestliže chcete zjistit, jaké chyby při replikaci nastaly, tak po zachycení výjimky SqlCeException projděte její kolekci Errors, která obsahuje objekty SqlCeError, a zkontrolujte jejich vlastnosti Hresult, Message, NativeError a Source.
13. Na serveru můžete logovat činnost IIS replikačního agenta přidáním nového klíče do registrů pod větev HKLM\Software\Microsoft\MSSQLSERVERCE\Transport. Klíč musí být typu DWORD a jeho názvem musí být fyzická (!ne virtuální) cesta k adresáři, v němž je umístěn soubor sscesa20.dll, doplněná řetězcem LOGGING_LEVEL. Hodnota klíče musí být v intervalu od 0 do 3 (0 – logování vypnuto, 1 – logování chyb, 2 – logování chyb a varování, 3 – logování chyb, varování a všech informativních hlášení). Po zapnutí nebo změně úrovně logování musíte restartovat IIS. Soubor s logem je vytvořen v adresáři IIS replikačního agenta a jmenuje se Sscerepl.log. (klíč c:\Inetpub\Sqlce20Agent\ LOGGING_LEVEL s hodnotou 1 zapne po restartu IIS logování chyb do souboru c:\Inetpub\Sqlce20Agent\ Sscerepl.log).
14. V books online pro SQL CE 2.0 si pozorně prostudujte článek o mapování mezi datovými typy MSSQL a SQL CE 2.0 (MSSQL ), abyste již při návrhu databáze počítali se všemi omezeními SQL CE klienta. Článek má název Supported Data Types and Data Type Mappings.
Sunday, 12 September 2004 18:35:00 (Central Europe Standard Time, UTC+01:00)
(MS)SQL tipy a triky
Thursday, 09 September 2004
Interval - článek Návrh aplikací v jazyce UML - textová specifikace případů užití
Další článek o UML mi dnes vyšel na serveru Interval.cz. I když pojem UML je dnes v názvu článku použit spíše jen ze setrvačnosti a také respektu k celému názvu seriálu, protože se zabývám návrhem struktury šablony dokumentu, ve které je umístěn podrobný popis případů užití.
Tímto článkem jsem opustil problematiku případů užití a příště již přijde na řadu (IMHO) nejzajímavější diagram v UML - diagram tříd.
Thursday, 09 September 2004 08:35:00 (Central Europe Standard Time, UTC+01:00)
UML
Friday, 27 August 2004
Podílejte se na rychlém konci éry bastlířů softwaru. Objektovými principy a návrhovými vzory řízený design a vývoj kvalitních aplikací.
Ve spotu z minulého týdne jsem sliboval překvapení pro příznivce OOP, UML a návrhových vzorů a hlavně pro ty, kdo mi psali, že by ode mě chtěli konzultaci nebo školení v designu aplikací. I když někteří z vás nabízeli opravdu zajímavé podmínky, musel jsem vždy odepsat, že žádné školení ani konzultaci neposkytuji. Důvody byly stále stejné. Mám dostatek vlastní práce a k courání po externích firmách nemám důvod. Žádostí ale bylo čím dál tím více, takže jsem se rozhodl s naším školícím střediskem připravit cyklus přednášek o OOP, UML a návrhových vzorech doprovázený podrobnými praktickými příklady kódovanými v jazyce C#.
Orientační program kurzu:
1. den
- Přivítání účastníků kurzu.
- Úvodní informace o zaměření a organizaci kurzu.
- Základní pojmy OOP a UML..
- Mýty o OOP a UML.
- Vysvětlení rozdílů mezi business analýzou, systémovým designem a implementací aplikace na konkrétní platformě.
- Světlo v temnotách – Model Driven Architecture (MDA)
- Základní architektura a rozvrstvení aplikace.
- Statický pohled na systém – vytváříme základní diagram tříd a ověřujeme, že jsou v něm zaneseny všechny informace, jež jsou nám známy z případů užití.
- Zvolení složitosti diagramu tříd. Potřebujeme vždy flexibilní doménový model?
- Zapouzdření objektů, polymorfismus, návrh metod.
i. Důležitost principů kovariance a kontravariance.
ii. Různé typy soudržnosti metod.
iii. Rozhodnutí o typu viditelnosti u každého člena třídy.
iv. Jaké konstruktory by měl nabízet každý objekt z problémové domény? Jak určit vlastnosti pouze pro čtení.
v. Ověření bezpečného chování třídy vůči potenciálním klientům.
- Precizní definice vztahů mezi třídami. Asociace, kompozice, agregace, závislost, realizace, generalizace.
- Vysvětlení rozdílů mezi abstraktní třídou a rozhraním (interface).
i. Vztah mezi typem a podtypem.
ii. Rozpoznání primárního účelu (hlavního smyslu) třídy i jejich sekundárních odpovědností vynucených vztahy s objekty z různých vrstev.
- Praktický příklad - ukázka implementace vzorových vztahů mezi objekty, perzistence objektů z problémové domény a zobrazování dat. (jazyk C#)
- Separace kódu pro ukládání a obnovení objektů z perzistentního úložiště v samostatné vrstvě.
- Jak zajistíme, že v paměti počítače existuje nanejvýš jedna instance objektu se stejnou identitou.
- Ukázky různých způsobů mapování agregace, kompozice, generalizace a asociace do databáze.
- Zajištění existence maximálně jedné instance objektu v systému.
- Efektivní ukládání a nahrávání kolekcí.
- Jak se slučuje objektový přístup a přímé použití DataSetu (recordsetu) v uživatelském rozhraní?
- Odpovědi na dotazy frekventantů kurzu.
2. den
- Vysvětlení pojmu návrhový vzor.
- Kdy byste měli používat návrhové vzory?
- Základní vzory (GoF vzory)
- Vzory pro řízení vzniku objektů.
- Strukturální vzory.
- Vzory pro chování objektů.
- Začlenění návrhového vzoru do designu aplikace. Kreativní aplikace vzorů.
- Kompozice vzorů do vyšších sémantických celků.
- Příklady odvozených návrhových vzorů často používaných při designu informačního systému.
- Kdy byste neměli používat návrhové vzory?
- Příklad - ukázky implementace složitějších vzorů. (jazyk C#).
- Odpovědi na dotazy frekventantů kurzu.
3. den
- Typické problémy při modelování informačního systému a jejich řešení.
- Modelování složitých organizačních struktur.
- Výhody vytváření fasád (Facade) pro aplikace s více než jedním typem uživatelského rozhraní (lehký klient, těžký klient).
- Evidence kompletní historie objektu.
- Aplikační role a práva uživatelů.
- Modelování toku peněz (zboží) v systému.
- Vytvoření flexibilního systému, jehož chování je změněno bez rekompilace aplikace.
- Příklad – ukázky řešení problémů při modelování informačního systému. (jazyk C#).
- Odpovědi na dotazy frekventantů kurzu.
- Ukončení kurzu.
Kurz se koná 3.11 - 5.11 2004 a jeho lektorem je samozřejmě moje maličkost. Jestliže vás program kurz zaujal, podívejte se prosím na jeho oficiální stránku, na které se můžete přihlásit. A pokud si stejně jako já myslíte, že zlatokopeckou dobu vývoje softwaru, kdy neznalý zákazník byl ochoten platit za zpatlanou aplikaci jakémukoli bastlíři, který za svoje excelentní know how považuje znalost syntaxe nějakého triviálního programovacího jazyka, halí opar blížícího se "fin de siecle” a že v nové éře musí kódování předcházet kvalitní návrh, jemuž rozumí všichni vývojáři, tak je kurz určen právě vám. Máte-li nějaké dotazy, napište je prosím do diskuze.
Aktualizace: Kurz je již obsazen (takový zájem mě opravdu těší), ale právě dohadujeme další termíny, aby se dostalo na všechny zájemce ;)
Friday, 27 August 2004 16:08:00 (Central Europe Standard Time, UTC+01:00)
Kurzy UML a OOP | UML