MIX10 – paskutinės valandos Lietuvoje

Parašė Sergejus | 2010-03-12 14:12

Kaip ir rašiau anksčiau, šiais metais aš pirmą kartą dalyvausiu MIX konferencijoje Las Vegase. Tradiciškai susiklostė, kad Microsoft anonsuoja daugiausiai naujų produktų per dvi konferencijas: MIX ir PDC. Šiais metais pagrindinis akcentas bus Windows Phone 7 Series, bet taip pat didelis dėmesys bus skirtas Silverlight 4, Internet Explorer 9 ir Windows Azure. Pirmadienį ir antradienį vyks pagrindinės sesijos (keynotes), iš kurių aš bandysiu gyvai rašyti į twitterį (@sergejusb), o vėliau išpublikuosiu apibendrintą dienos straipsnį. Raginu visus sekti MIX naujienas čia!

Kelios mintys dėl Windows Phone 7 Series

Parašė Sergejus | 2010-03-09 01:02

Aš esu vienas iš tų žmonių, kurie daugiau nei metus stebėjo ir rinko gandus apie Windows Phone 7. Tai tikriausiai pirmasis Microsoft produktas, pagamintas be jokių informacijos nutekėjimų. Tam kad geriau įsivaizduotume ant kiek tai buvo slaptas produktas – nei Microsoft darbuotojai, nei Windows Mobile MVP nežinojo kas vyksta Windows Phone 7 grupės viduje.

Vasario 15 dieną, Mobile World Congress konferencijos metu, Steve Ballmer pirmą kartą per 18 mėnesių nuo kūrimo pradžios, parodė gyvai Windows Phone 7. Tuo pačiu metu buvo išpublikuotas ir detalesnis video Channel 9 svetainėje. Microsoft pribloškė visus (ko nebuvo jau pakankamai senokai) savo novatoriška vartotojo sąsaja (vadinama Metro) ir operacinės sistemos galimybėmis. Per sekančias kelias valandas tai tapo naujiena #1 IT pasaulyje. Apie Windows Phone 7 rašė IT portalai, tinklaraščiai, twitter ir kiti media šaltiniai. Tuo pačiu metu startavo ir oficialus puslapis – windowsphone7series.com bei tinklaraštis.

wp7-1

Trumpai priminsiu svarbiausius dalykus apie Windows Phone 7 telefonus. Iki šiol Microsoft buvo liberali Windows Mobile įrenginių gamintojams. Jie neturėjo jokių apribojimų ekrano dydžiui bei rezoliucijai, atminties kiekiui, procesoriaus dažniui ir kitoms charakteristikoms. Nuo šiol kiekvienas įrenginys turės tenkinti žemiau išvardintus techninius reikalavimus:

  • Didelis WVGA ekranas su fiksuotu aukščio/pločio santykiu (angl. aspect ratio)
  • Talpinis jutimui jautrus ekranas (angl. capacitive multitouch)
  • 5 aparatiniai mygtukai: Start, atgal, paieška, įjungimas/išjungimas ir kamera. Lygiai 5 – nei daugiau, nei mažiau
  • Telefonas turi tenkinti tam tikrus minimalius CPU ir GPU reikalavimus
  • WiFi palaikymas
  • AGPS palaikymas
  • Akselerometras
  • FM radijas
  • Ne mažesnė nei 5 Mega pikselių kamera

Kaip matote, šie apribojimai skirti išlaikyti vienodą naudojimosi Windows Phone 7 patyrimą nepriklausomai nuo konkretaus gamintojo modelio.

Windows Phone 7 tai visiškai nauja mobilių įrenginių operacinė sistema. Ji didžiąja dalimi paremta Zune HD OS, todėl naudoja tą pačią Metro vartotojo sąsaja. Dar daugiau, Microsoft pristatė naują koncepciją – Hubs. Tai centrinė vieta, iš kurios galima atlikti tam tikras tipines užduotis bei patogiau naviguoti tarp susijusios informacijos ir meniu punktų. Šiuo metu paskelbtos 6 sritys:

  • People hub
    wp7-2
  • Picture hub
    wp7-3
  • Games hub
    wp7-4
  • Music + Video hub
    wp7-5
  • Marketplace hub
    wp7-7
  • Office hub
    wp7-6

Marketplace sritis apima ir visas telefono aplikacijas, kadangi nuo šiol tai vienintelė vieta iš kurios galima instaliuoti naujas aplikacijas. Apskritai, be 3G ar WiFi prisijungimo vargu aš Windows Phone 7 telefonas galės pilnaverčiai dirbti. Internetas naudojamas kontaktų sinchronizacijai su Facebook ir XBox Live, jūsų pasiekimai žaidimuose bei patys žaidimai irgi sinchronizuojasi su XBox Live, informacija apie grojamą MP3 dainą gali būti imama tiesiogiai iš interneto, Office (tame tarpe ir SharePoint) moka sinchronizuotis su debesimi (angl. cloud) ir t.t.

Norėdami detaliau pasiskaityti apie Windows Phone 7 galimybes rekomenduoju perskaityti šį Engadget straipsnį bei pasižiūrėti jų šou (nuo 30 minutės).

OK, aukščiau pateikta informacija nėra naujiena ir yra praktiškai mėnesio senumo. Kodėl šį straipsnį aš nusprendžiau parašyti tik dabar? Barselonoje buvo pristatyta tik viena naujovių pusė – naujovės skirtos galutiniams naudotojams. Visos naujienos skirtos programuotojoms turėjo būti paskelbtos kitą savaitę vykstančioje MIX konferencijoje (iš kurios aš aktyviai dalinsiuos įspūdžiais twitteryje). Bet prieš kelias dienas dalis informacijos pirma buvo atskleista viename iš oficialių tinklaraščių, o vėliau atsirado vaizdo įrašasTechEd Middle East konferencijos, kuriame tas pats žaidimas veikė tiek XBox, tiek Windows Phone platformose.

Pirma blogos naujienos – pasitvirtino informacija, kad egzistuojančios Windows Mobile aplikacijos naujoje operacinėje sistemoje nebeveiks. Neišreikštinai tai pat buvo pasakyta, kad .NET Compact Framework irgi nebeveiks Windows Phone 7. Programuotojams bus skirti du pagrindiniai įrankiai – Silverlight aplikacijų kūrimui bei XNA žaidimų kūrimui. Asmeniškai aš nepergyvenu dėl to, kad senos aplikacijos nebeveiks – pats laikas viską pergalvoti iš esmės. Iš kitos pusės aš be galo patenkintas, kad pasirinktos egzistuojančios brandžios technologijos: XNA iki šiol buvo naudojamas kurti žaidimus personaliam kompiuteriui, XBox 360 ir Zune HD; Silverlight jau kurį laiką kuo puikiausiai veikia tiek naršyklėse, tiek už jų ribų (out of browser support).

Vienintelis dalykas kuris mane gąsdina – tai Marketplace sritis. Nuo pat Zune pasirodymo dėl juridinių priežasčių jis buvo prieinamas tik JAV ir Kanadoje. Ar tai reiškia, kad su Windows Phone 7 mes galėsime pirkti muziką ir filmus tik iš JAV – kol kas nežinau, bet tikiuosi gauti atsakymą į šį klausimą MIXe.

Apibendrinant, turiu pripažinti kad šį kartą Microsoft pavyko padaryti „WOW“. Kas ypač malonu, su naujos operacinės pasirodymu iš karto taps pasiekiamas ir visas įrankių arsenalas programuotojams. Šiuo metu turiu svajonę – kuo greičiau nusipirkti Windows Phone 7, o tai turėtų tapti įmanoma dar šiais metais…

O ką jus manote apie Windows Phone 7?

Steve Ballmer apie Microsoft debesų kompiuterijos strategiją

Parašė Sergejus | 2010-03-04 22:53

Ką tik pasibaigė online video transliacija iš Steve Ballmer pristatymo apie Microsoft debesų kompiuterijos strategiją. Rekomenduoju pasižiūrėti žemiau esantį video (1,5 valandos). Pristatymo metu didžiausias dėmėsis buvo skirtas šitiems Microsoft produktams:

  • Windows Azure
  • SQL Azure
  • Exchange Online
  • Sharepoint Online
  • Office Web Apps
  • Office Communications Online
  • Dynamics CRM Online

Windows Azure – 7 dalis

Parašė Sergejus | 2010-03-01 00:50
Ankstesni straipsniai

Įvadas į Windows Azure – 1 dalis (Pagrindinės sąvokos)

Įvadas į Windows Azure – 2 dalis (Windows Azure Hello World ASP.NET puslapio kūrimas)

Įvadas į Windows Azure – 3 dalis (lokalios objektinės Windows Azure saugyklos konfigūravimas)

Įvadas į Windows Azure – 4 dalis (lokalios BLOB saugyklos panaudojimas)

Įvadas į Windows Azure – 5 dalis (lokalios BLOB saugyklos perkėlimas į Windows Azure)

Įvadas į Windows Azure – 6 dalis (esybių lentelių saugyklos panaudojimas)

 

PASTABA: šis straipsnis yra identiškas 6 dalyje aprašytam puslapiui, bet vietoje BLOB saugyklos naudojamas virtualus diskas.

Vasarį mėnesį atsinaujinus Windows Azure Tools for Microsoft Visual Studio 1.1 (February 2010), tapo prieinamas ir naujas objektinės saugyklos tipas – X-Drive (debesų diskas). Šioje dalyje aš pateiksiu ASP.NET puslapį, kuriame galima pridėti naują failą į diską, atvaizduoti esamus failus, juos parsisiųsti bei ištrinti. Kaip ir 6 dalyje, visos operacijos su Windows Azure yra apvilktos į repozitorijaus (angl. repository) projektavimo šabloną.

X-Drive pagrindai

X-Drive (arba tiesiog debesų diskas (angl. cloud disk)) – tai naujas Windows Azure objektinių saugyklų tipas (šalia eilių, esybių lentelių ir BLOBų). Pagrindinis debesų disko privalumas – jis leidžia dirbti tu BLOB saugyklomis naudojant standartinį .NET System.IO API. Iš techninės pusės jis realizuotas kaip virtualus diskas, patalpintas nurodytoje objektinėje BLOB saugykloje ir susietas su tam tikra Windows Azure disko raide (pav., X:). Naujasis CloudDrive API leidžia ne tik kurti tokius virtualius diskus, bet ir atlikti jiems standartines operacijas Mount (prijungti diską) ir Unmount (atjungti diską).

Kaip žinia, objektinės saugyklos yra globalios, t.y. nepriklauso nuo konkrečios Windows Azure virtualios mašinos. Tai reiškia, kad standartinės operacijos su objektinėmis saugyklomis nėra ypač greitos. Vienintelis paspartinimo būdas – lokalios saugyklos panaudojimas (lokali saugykla yra individuali kiekvienai Windows Azure virtualiai mašinai). CloudDrive moka pasinaudoti lokalia saugykla kaip įrašymo/skaitymo operacijų buferiu (tarpine atmintimi).

Vienas didžiausių X-Drive privalumu – nuo šiol įmanoma pakankamai nesunkiai paimti egzistuojantį virtualų diską (VHD formatu) ir tiesiog jį su visais duomenimis perkelti į debesis.

Paruošiamieji darbai

Prieš pradedant, aš primygtinai rekomenduoju perskaityti ankstesnius straipsnius, tam kad mokėti sukurti Windows Azure ASP.NET puslapį, sukonfigūruoti lokalią objektinę Windows Azure saugyklą bei dirbti su objektine BLOB saugykla.

Už pagrindą aš pasiėmiau 2 dalyje aprašytą „Hello World“ Windows Azure ASP.NET aplikaciją. Kadangi darbui su X-Drive reikalinga BLOB objektinė saugykla, mums reikia nurodyti Windows Azure prisijungimo duomenis. HelloWorldCloud projekte reikia nueiti į nustatymus ir pridėti naują prisijungimo eilutę, kurią aš pavadinau StorageConnectionString:

azure14

Atkreipkite dėmesį, kad laikinai mes naudojame ne realius Windows Azure prisijungimo duomenis, bet lokalią saugyklą. Nors tarpinės atminties panaudojimas su debesų diskais nėra būtinas, išsamumo dėlei šiame pavyzdyje aš parodysiu kaip ja pasinaudoti. Tam reikia nueiti į kortelę Local Storage ir pridėti naują lokalią saugyklą (pavadinau DiskCacheLocalStorage):

azure17

Kitas svarbus momentas – Web rolės klasės aprašymas. Kadangi Windows Azure BLOB saugykla nepriklauso nuo .NET vykdymo aplinkos (skaitykit nuo Microsoft.WindowsAzure.ServiceRuntime), reikia HelloWorldWeb projekte sukurti Web rolės klasę ir joje nusakyti kaip reaguoti į konfigūracijos failo pakeitimus. WebRole klasė nesiskiria nuo pateiktos 6 dalyje.

Puslapio sukūrimas

Kadangi mes operuojame standartine System.IO vardų sritimi, jokių papildomų klasių apibrėžti nereikia ir galima pereiti prie repozitorijaus interfeiso aprašo su visomis mums reikalingomis operacijomis:

public interface IXDriveFileRepository
{
    IEnumerable<FileInfo> List();
    byte[] Get(string fileName);
    void Insert(string fileName, byte[] file);
    void Delete(string fileName);
}

Aptarkime kiekvieno metodo paskirtį:

  • metodas List skirtas pateikti diske saugomų failų metaduomenų sąrašą (System.IO.FileInfo)
  • metodas Get gauna nurodytą failą
  • metodas Insert įrašo failą į diską
  • metodas Delete ištrina nurodytą failą iš disko

Nesigilinant į IXDriveFileRepository realizaciją, pateiksiu Web puslapio kodą:

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="XDrive.aspx.cs" Inherits="HelloWorldWeb.XDrive" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Failų sąrašas</title>
</head>
<body>
    <form id="form" runat="server">
    <h1>Failai</h1>
    Pridėti naują
    <asp:FileUpload ID="FileUpload" runat="server" />
    <asp:Button runat="server" Text="Pridėti" OnClick="UploadFile" />
    <asp:ListView ID="Files" runat="server">
        <LayoutTemplate>
            <ul>
                <li id="itemPlaceHolder" runat="server" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <li>
                <asp:LinkButton runat="server" Text='<%# Eval("Name") %>'
                    OnCommand="DownloadFile" CommandArgument='<%# Eval("Name") %>' />
                <asp:LinkButton ID="Name" runat="server" Text="[x]"
                    OnCommand="DeleteFile" CommandArgument='<%# Eval("Name") %>' />
            </li>
        </ItemTemplate>
    </asp:ListView>
    </form>
</body>
</html>

Kaip matote, puslapyje tėra failo pridėjimo elementas bei sąrašas jau pridėtų failų su galimybe ištrinti. Failų pavadinimas yra atvaizduojamas kaip nuoroda, kad galima būtų jį parsisiųsti paprastu paspaudimu. C# pusė atrodo taip:

public partial class XDrive : Page
{
    private readonly IXDriveFileRepository repository =
        new XDriveFileRepository(
            "drives",
            100,
            "test.vhd",
            "DiskCacheLocalStorage",
            "StorageConnectionString");

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ListFiles();
        }
    }

    protected void UploadFile(object sender, EventArgs e)
    {
        if (FileUpload.HasFile)
        {
            var fileName = FileUpload.PostedFile.FileName;
            var file = FileUpload.FileBytes;

            repository.Insert(fileName, file);

            ListFiles();
        }
    }

    protected void DownloadFile(object sender, CommandEventArgs e)
    {
        var fileName = e.CommandArgument.ToString();
        var file = repository.Get(fileName);

        Response.AppendHeader("content-disposition", "attachment; filename=" + fileName);
        Response.BinaryWrite(file);
        Response.End();
    }

    protected void DeleteFile(object sender, CommandEventArgs e)
    {
        var fileName = e.CommandArgument.ToString();
        repository.Delete(fileName);

        ListFiles();
    }

    private void ListFiles()
    {
        Files.DataSource = repository.List();
        Files.DataBind();
    }
}

Repozitorijaus dėka, šis ASP.NET puslapis neturi jokio supratimo apie Windows Azure panaudojimą. XDriveFileRepository konstruktorius bus aprašytas vėliau.

XDriveFileRepository įgyvendinimas

Žemiau pateikta XDriveFileRepository realizacija reikalauja nuorodų į tokias bibliotekas:

  • Microsoft.WindowsAzure.CloudDrive
  • Microsoft.WindowsAzure.ServiceRuntime
  • Microsoft.WindowsAzure.StorageClient
  • System.Data.Services.Client

Atskirai norėtųsi paminėti XDriveFileRepository konstruktorių: jis priima net penkis argumentus:

  • drives – BLOB konteinerio pavadinimas kuriame bus saugoma virtualaus disko informacija
  • 100 – debesų disko dydis megabaitais
  • test.vhd – virtualaus disko failo pavadinimas
  • DiskCacheLocalStorage – lokalios saugyklos, naudojamos kaip disko tarpinė atmintis, pavadinimas iš mūsų konfigūracijos failo
  • StorageConnectionString – prisijungimo prie Windows Azure saugyklos eilutės pavadinimas iš mūsų konfigūracijos failo

Kitus paaiškinimus parašiau kaip komentarus:

public class XDriveFileRepository : IXDriveFileRepository, IDisposable
{
    private readonly CloudDrive drive;
    private readonly string driveLetter;

    public XDriveFileRepository(string container,
                                int diskSize,
                                string diskFileName,
                                string diskCacheStorageName,
                                string connectionString)
    {
        // inicializuojame disko tarpinę atmintį spartesnei prieigai prie duomenų
        var localDiskCache = RoleEnvironment.GetLocalResource(diskCacheStorageName);
        CloudDrive.InitializeCache(localDiskCache.RootPath, localDiskCache.MaximumSizeInMegabytes);

        // aprašome mūsų BLOB klientą
        var storageAccount = CloudStorageAccount.FromConfigurationSetting(connectionString);
        var blobClient = storageAccount.CreateCloudBlobClient();

        // pagal nurodytą vardą gauname egzistuojantį konteinerį arba sukuriame naują
        var blobContainer = blobClient.GetContainerReference(container);
        blobContainer.CreateIfNotExist();

        // sukuriame naują diską
        var driveUri = blobClient.GetPageBlobReference(diskFileName).Uri.ToString();
        drive = storageAccount.CreateCloudDrive(driveUri);
        try
        {
            drive.Create(diskSize);
        }
        catch (CloudDriveException e)
        {
            // klaida įvyksta net kai viskas gerai, bet diskas jau egzistuoja
        }

        driveLetter = drive.Mount(localDiskCache.MaximumSizeInMegabytes, DriveMountOptions.None);
    }

    public void Dispose()
    {
        drive.Unmount();
    }

    public IEnumerable<FileInfo> List()
    {
        var dirInfo = new DirectoryInfo(driveLetter);
        return dirInfo.GetFiles();
    }

    public byte[] Get(string fileName)
    {
        var path = GetFullPath(fileName);
        return File.ReadAllBytes(path);
    }

    public void Insert(string fileName, byte[] file)
    {
        var path = GetFullPath(fileName);
        File.WriteAllBytes(path, file);
    }

    public void Delete(string fileName)
    {
        var path = GetFullPath(fileName);
        File.Delete(path);
    }

    private string GetFullPath(string fileName)
    {
        return Path.Combine(driveLetter, fileName);
    }
}

BLOB saugyklos sukūrimas

Iki šiol BLOB saugyklos testavimui mes naudojome taip vadinamą „Development Storage“. Norėdami išpublikuoti mūsų Windows Azure aplikaciją į debesis, pirma reikia sukurti saugyklą Windows Azure portale, tai detaliai aprašyta 5 dalyje.

Kitoje dalyje…

Nors aš žadėjau, kad jau šioje dalyje mes išnagrinėsime eiles (angl. queues), nusprendžiau pirma aprašyti X-Drive naujovę, nes ji glaudžiai susijusi su BLOB objektine saugykla. Eiles aptarsime kitoje dalyje…

MVP Summit 2010

Parašė Sergejus | 2010-02-14 17:49

Jau už kelių valandų pradedu savo paros kelionę į Seattle, į MVP Summit 2010. Kaip ir kiekvienais metais, Microsoft organizuoja viso pasaulio MVP skirtą keturių dienų susitikimą, kurio metu suteikiama nepakartojama proga gyvai pabendrauti su produktų grupėmis, aptarti ateities produktų versijas, išsakyti savo nuomonę apie produktus bei pasiūlyti būdus kaip juos pagerinti. Microsoft iš savo pusės pasakos apie savo artimiausių metų planus, strategiją bei produktus.

Kadangi aš esu C# MVP, tai daugiausiai dalyvausiu susitikimuose su C# ir Visual Studio komandomis. Taip pat dalyvausiu keliuose susitikimuose su ASP.NET (MVC), Entity Framework, Silverlight bei Windows Azure ir SQL Azure komandomis.

MVP Summit 2010 tai yra uždara konferencija (kiekvienas iš MVP esame pasirašę su Microsoft informacijos neatskleidimo susitarimą), todėl įspūdžiai iš kelionės bus bendrojo pobūdžio. Kaip sakoma, laukite naujienų bei sekite mane twitteryje @sergejusb.

Visual Studio 2010 RC – jau prieinamas

Parašė Sergejus | 2010-02-09 19:41

VS2010

Štai ir įvyko – Visual Studio 2010 RC šiandien tapo prieinamas MSDN prenumeratoriams. Kiekvienas norintysis galės parsisiųsti ją jau vasario 10 vakare.

Po Beta2 pasirodymo, nemažai MVP ir kitų entuziastų pateikė pastabas dėl Visual Studio greitaveikos. Kaip žinia, pradinis planas buvo išleisti Visual Studio 2010 jau kovą. Po aštrių diskusijų su MVP ir stambiausiais klientais, Microsoft priėmė teisingą sprendimą ir atidėjo išleidimo datą mėnesiu, o visus resursus tam laikotarpiui permetė greitaveikos gerinimui. Pagrindiniai optimizavimo aspektai:

  • Integruotos kūrimo aplinkos greitaveika
  • IntelliSense greitaveika
  • WPF greitaveika virtualioje aplinkoje ir per nuotolinį prisijungimą
  • Naudojamos atminties ir kitų resursų optimizavimas
  • Surinkimo (build) proceso pagreitinimas
  • Darbo su dideliu projektų skaičiumi pagerinimas

Nesvarbu ar jus naudojatės Beta2, ar dar apskritai nesate bandę 2010 versijos, aš primygtinai rekomenduoju jums susidiegti Visual Studio 2010 Release Candidate.

Daugiau informacijos apie naują Visual Studio 2010 RC galite rasti Jason Zander tinklaraštyje.

PAPILDYTA

Norėdami išinstaliuoti Visual Studio 2010 Beta2 svarbu prisilaikyti tokios tvarkos:

  • Web Deployment Tool
  • Silverlight 3 SDK
  • Visual Studio 2010 Tools for SQL Server Compact 3.5 SP2
  • SQL Server Compact 3.5 SP2
  • SQL Server 2008
  • SQL Server 2008 Native Client
  • SQL Server 2008 R2 Management Objects
  • SQL Server System CLR Types
  • The .NET Framework version 4 Language Pack
  • The .NET Framework version 4 Extended
  • The .NET Framework version 4 Client

PAPILDYTA

Visual Studio 2010 RC jau prieinama ir viešai!

Artimiausi mano renginiai/pristatymai/konferencijos

Parašė Sergejus | 2010-02-07 21:32

Vasario 11 – skaitau pristatymą iš Visual Studio 2010, Microsof Lietuva klientų konferencija

Vasario 15–21 – skrendu į Seattle, MVP Summit 2010

Vasario pabaiga – kovo pradžia (datos bus patikslintos) – Lietuvos .NET vartotojų grupės susitikimas (viskas apie Silverlight)

Kovo 13-19 – skrendu į Las Vegasą, MIX 10

Balandis (datos bus patikslintos) – oficialus Visual Studio 2010 paleidimas Lietuvoje

 

O dabar kelios geros naujienos. Jeigu turite kokių pageidavimų dėl naujų C# ir Visual Studio galimybių, galite parašyti komentaruose ir aš perduosiu jūsų pageidavimus MVP Summit metu atitinkamoms Microsoft grupėms. Taip pat MIX konferencijos metu (panašiai kaip buvo ir TechEd metu), aš žadu rašyti dienos apžvalgas. MIX pagrindinės sesijos metu (kurioje žadama bus anonsuotas Silverlight 4, parodytas Internet Explorer 9 bei Windows Mobile 7) aš aktyviai „twitinsiu“, tad sekite mane @sergejusb.

Windows Azure – 6 dalis

Parašė Sergejus | 2010-02-01 00:11

PASTABA: šis straipsnis nagrinėja identišką puslapį aprašytą ketvirtoje ir penktoje dalyse, bet vietoje BLOB saugyklos naudojama esybių lentelių saugykla.

Šioje dalyje mes panaudosime prieš tai sukonfigūruotą lokalią esybių lentelių saugyklą, o vėliau pereisime ir prie realios. Kaip pavyzdį aš pateiksiu ASP.NET puslapį, kuriame galima pridėti naują failą į objektinę esybių lentelių saugyklą, atvaizduoti esamus failus, juos parsisiųsti bei ištrinti. Kaip ir 4 dalyje, visos operacijos su Windows Azure yra apvilktos į repozitorijaus (angl. repository) projektavimo šabloną.

Esybių lentelės pagrindai

Esybių lentelės (angl. tables) – tai viena iš Windows Azure objektinių saugyklų, kuri yra skirta esybių saugojimui. Lentelių saugykla yra sudaryta iš lentelių (esybių), kur kiekviena eilutė atitinka konkrečią esybę. Kiekviena esybė mažiausiai yra sudaryta iš trijų savybių: PartitionKey, RowKey ir Timestamp.Timestamp nusako esybės versiją (panašiai kaip SQL Server duomenų bazėje), PartitionKey ir RowKey kartu sudaro unikalų esybės raktą.

Jeigu turėjote reikalų su SQL serverio greitaveikos gerinimu – tikriausiai žinoti sąvoką Partitioning. Pagrindinė jos esmė – automatiškai paskirstyti duomenis tarp visų prieinamų SQL serverių, taip pagerinant bendrą duomenų bazės greitaveiką. Windows Azure esybių lentelėse įgyvendinta labai panaši technologija: PartitionKey nusako kurioje particijoje reikia ieškoti duomenų, o RowKey apibrėžia unikalų įrašo ID toje particijoje.

Taip pat norėtųsi pridėti, kad visos esybės taip pat yra pasiekiamos ADO.NET Data Services pagalba.

„Hello World“ projekto pakeitimai

Už pagrindą aš pasiėmiau 2 dalyje aprašytą „Hello World“ Windows Azure ASP.NET aplikaciją. Kadangi darbui su objektinėmis saugyklomis mums reikės nurodyti Windows Azure prisijungimo duomenis, tam HelloWorldCloud projekte reikia nueiti į nustatymus ir pridėti naują prisijungimo eilutę, kurią aš pavadinau StorageConnectionString:

azure14

Atkreipkite dėmesį, kad laikinai mes naudojame ne realius Windows Azure prisijungimo duomenis, bet lokalią saugyklą. Kitas svarbus momentas – Web rolės klasės aprašymas. Kadangi Windows Azure esybių lentelių saugykla nepriklauso nuo .NET vykdymo aplinkos (skaitykit nuo Microsoft.WindowsAzure.ServiceRuntime), reikia HelloWorldWeb projekte sukurti Web rolės klasę ir joje nusakyti kaip reaguoti į konfigūracijos failo pakeitimus. Žemiau pateiktas kodas yra nukopijuotas iš Windows Azure SDK, tikiuosi ateityje Microsoft sugalvos patogesnį sprendimą:

public class WebRole : RoleEntryPoint
{
    public override bool OnStart()
    {
        DiagnosticMonitor.Start("DiagnosticsConnectionString");

        // This code sets up a handler to update CloudStorageAccount instances when their corresponding
        // configuration settings change in the service configuration file.
        CloudStorageAccount.SetConfigurationSettingPublisher((settingName, configSetter) =>
        {
            // Provide the configSetter with the initial value
            configSetter(RoleEnvironment.GetConfigurationSettingValue(settingName));

            RoleEnvironment.Changed += (sender, arg) =>
            {
                if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                    .Any(change => (change.ConfigurationSettingName == settingName)))
                {
                    // The corresponding configuration setting has changed, propagate the value
                    if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(settingName)))
                    {
                        // In this case, the change to the storage account credentials in the
                        // service configuration is significant enough that the role needs to be
                        // recycled in order to use the latest settings. (for example, the 
                        // endpoint has changed)
                        RoleEnvironment.RequestRecycle();
                    }
                }
            };
        });

        // For information on handling configuration changes
        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
        RoleEnvironment.Changing += (sender, arg) =>
        {
            // If a configuration setting is changing
            if (arg.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
            {
                // Set e.Cancel to true to restart this role instance
                arg.Cancel = true;
            }
        };

        return base.OnStart();
    }
}

Puslapio sukūrimas

Kadangi puslapyje mes operuosime failais, apibrėškime klasę FileEntity, kurioje saugosime failo pavadinimą, turinio tipą bei patį failo turinį. Taip pat reikia apibrėžti anksčiau minėtas savybes PartitionKey, RowKey ir Timestamp arba tiesiog paveldėti iš TableServiceEntity (iš vardų srities Microsoft.WindowsAzure.StorageClient):

public class FileEntity : TableServiceEntity
{
    public FileEntity(string partitionKey, string rowKey)
        : base(partitionKey, rowKey)
    {
    }

    public FileEntity()
        : this(Guid.NewGuid().ToString(), String.Empty)
    {
    }

    public string FileName { get; set; }
    public string ContentType { get; set; }
    public byte[] Data { get; set; }
}

Dabar apibrėšime repozitorijaus interfeisą su mums reikalingomis operacijomis:

public interface IFileRepository
{
    IEnumerable<FileEntity> List();
    FileEntity Get(Guid id);
    void Insert(FileEntity file);
    void Delete(FileEntity file);
    void Delete(Guid id);
}

Aptarkime kiekvieno metodo paskirtį:

  • metodas List skirtas pateikti esybių lentelių saugykloje saugomų failų sąrašą
  • metodas Get gauna nurodytą failą
  • metodas Insert įterpia į esybių lentelių saugyklą failą
  • metodas Delete ištrina nurodytą failą iš esybių lentelių saugyklos

Nesigilinant į IFileRepository realizaciją, pateiksiu Web puslapio kodą:

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="Table.aspx.cs" Inherits="HelloWorldWeb.Table" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Failų sąrašas</title>
</head>
<body>
    <form id="form" runat="server">
    <h1>Failai</h1>
    Pridėti naują
    <asp:FileUpload ID="FileUpload" runat="server" />
    <asp:Button runat="server" Text="Pridėti" OnClick="UploadFile" />
    <asp:ListView ID="Files" runat="server">
        <LayoutTemplate>
            <ul>
                <li id="itemPlaceHolder" runat="server" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <li>
                <asp:LinkButton runat="server" Text='<%# Eval("FileName") %>'
                    OnCommand="DownloadFile" CommandArgument='<%# Eval("PartitionKey") %>' />
                <asp:LinkButton runat="server" Text="[x]"
                    OnCommand="DeleteFile" CommandArgument='<%# Eval("PartitionKey") %>' />
            </li>
        </ItemTemplate>
    </asp:ListView>
    </form>
</body>
</html>

Kaip matote, puslapyje tėra failo pridėjimo elementas bei sąrašas jau pridėtų failų su galimybe ištrinti. Failų pavadinimas yra atvaizduojamas kaip nuoroda, kad galima būtų jį parsisiųsti paprastu paspaudimu. C# pusė atrodo taip:

public partial class Table : Page
{
    private readonly IFileRepository repository =
        new FileRepository("StorageConnectionString");

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ListFiles();
        }
    }

    protected void UploadFile(object sender, EventArgs e)
    {
        if (FileUpload.HasFile)
        {
            var file = new FileEntity
            {
                FileName = FileUpload.PostedFile.FileName,
                ContentType = FileUpload.PostedFile.ContentType,
                Data = FileUpload.FileBytes
            };

            repository.Insert(file);

            ListFiles();
        }
    }

    protected void DownloadFile(object sender, CommandEventArgs e)
    {
        var file = repository.Get(new Guid(e.CommandArgument.ToString()));

        Response.AppendHeader("content-disposition", "attachment; filename=" + file.FileName);
        Response.ContentType = file.ContentType;
        Response.BinaryWrite(file.Data);
        Response.End();
    }

    protected void DeleteFile(object sender, CommandEventArgs e)
    {
        repository.Delete(new Guid(e.CommandArgument.ToString()));

        ListFiles();
    }

    private void ListFiles()
    {
        Files.DataSource = repository.List();
        Files.DataBind();
    }
}

Repozitorijaus dėka, šis ASP.NET puslapis neturi jokio supratimo apie Windows Azure panaudojimą.

FileRepository įgyvendinimas

Žemiau pateikta FileRepository realizacija reikalauja nuorodų į tokias bibliotekas:

  • Microsoft.WindowsAzure.ServiceRuntime.dll
  • Microsoft.WindowsAzure.StorageClient.dll
  • System.Data.Services.Client.dll

Atskirai norėtųsi paminėti FileRepository konstruktorių: jis priima vieną argumentą – prisijungimo prie Windows Azure saugyklos eilutės pavadinimą iš mūsų konfigūracijos failo. Kitus paaiškinimus parašiau kaip komentarus:

public class FileRepository : IFileRepository
{
    private readonly TableServiceContext context;
    private const string TableName = "Files";

    public FileRepository(string connectionString)
    {
        // aprašome mūsų lentelės klientą
        var storageAccount = CloudStorageAccount.FromConfigurationSetting(connectionString);

        // jeigu lentelė dar neegzistuoja - sukuriame naują
        storageAccount.CreateCloudTableClient().CreateTableIfNotExist(TableName);

        // sukuriame lentelės kontekstą (ADO.NET data services kontekstą)
        context = new TableServiceContext(storageAccount.TableEndpoint.ToString(),
                                          storageAccount.Credentials);
    }

    public IEnumerable<FileEntity> List()
    {
        return (from f in context.CreateQuery<FileEntity>(TableName)
                select f).ToList();
    }

    public FileEntity Get(Guid id)
    {
        return (from f in context.CreateQuery<FileEntity>(TableName)
                where f.PartitionKey == id.ToString()
                select f).SingleOrDefault();
    }

    public void Insert(FileEntity file)
    {
        context.AddObject(TableName, file);
        context.SaveChanges();
    }

    public void Delete(FileEntity file)
    {
        context.AttachTo(TableName, file);
        context.DeleteObject(file);
        context.SaveChanges();
    }

    public void Delete(Guid id)
    {
        var file = Get(id);
        if (file != null)
        {
            context.DeleteObject(file);
            context.SaveChanges();
        }
    }
}

Esybių lentelių saugyklos sukūrimas

Iki šiol esybių lentelių saugyklos testavimui mes naudojome taip vadinamą „Development Storage“. Norėdami išpublikuoti mūsų Windows Azure aplikaciją į debesis, pirma reikia sukurti saugyklą Windows Azure portale. Įvedus norimą saugyklos pavadinimą bei adresą, jus pamatysite panašų vaizdą:

azure15

Iš paveiksliuko matyti, kad mano saugyklos pavadinimas yra Files, o nuoroda – http://sergejus.table.core.windows.net. Taip pat žemiau pateikiami kodai, kurių pagalba galima prisijungti ir dirbti su saugykla iš aplikacijos.

Pakeitimai konfigūracijos faile

Turėdami egzistuojančią Windows Azure esybių lentelių saugyklą, belieka nueiti į WindowsCloudWeb projekto konfigūracijos failą ir jame pakeisti prisijungimo eilutės StorageConnectionString reikšmę į prieš tai sukurtos saugyklos duomenis. Account name laukelyje reikia įvesti jūsų esybių lentelių saugyklos nuorodos pradžią (viskas kas iki table.core.windows.net, mano atveju – sergejus). Account key laukelyje įveskite Primary Access Key kodą:

azure16

Svarbu pažymėti, kad naujus esybių lentelių saugyklos duomenis reikia nurodyti ne tik StorageConnectionString prisijungimo eilutėje, bet ir standartinėje DiagnosticsConnectionString prisijungimo eilutėje.

Tam kad patikrinti, ar saugykla veikia, užtenka paleisti aplikaciją derinimui. Įsitikinus, kad viskas veikia kaip numatyta, galite išpublikuoti aplikaciją į Windows Azure kaip buvo aprašyta antroje dalyje.

Veikiantį programos pavyzdį galite rasti adresu http://hellocloud.cloudapp.net/Table.aspx.

Kitoje dalyje…

Mes pratęsime nagrinėti Windows Azure saugyklas ir iš arčiau pasižiūrėsime į eiles (angl. queues).

Windows Azure – 5 dalis

Parašė Sergejus | 2010-01-24 22:29

Praeitoje dalyje aš parodžiau, kaip pasinaudoti Windows Azure binarine BLOB saugykla failų talpinimui ir saugojimui. Šį kartą mes perkelsime prieš tai sukurtą aplikaciją į debesis.

BLOB saugyklos sukūrimas

Iki šiol BLOB saugyklos testavimui mes naudojome taip vadinamą „Development Storage“. Norėdami išpublikuoti mūsų Windows Azure aplikaciją į debesis, pirma reikia sukurti saugyklą Windows Azure portale. Įvedus norimą saugyklos pavadinimą bei adresą, jus pamatysite panašų vaizdą:

azure15

Iš paveiksliuko matyti, kad mano saugyklos pavadinimas yra Files, o nuoroda – http://sergejus.blob.core.windows.net. Taip pat žemiau pateikiami kodai, kurių pagalba galima prisijungti ir dirbti su saugykla iš aplikacijos.

Pakeitimai konfigūracijos faile

Turėdami egzistuojančią Windows Azure BLOB saugyklą, belieka nueiti į WindowsCloudWeb projekto konfigūracijos failą ir jame pakeisti prisijungimo eilutės StorageConnectionString reikšmę į prieš tai sukurtos saugyklos duomenis. Account name laukelyje reikia įvesti jūsų BLOB saugyklos nuorodos pradžią (viskas kas iki blob.core.windows.net, mano atveju – sergejus). Account key laukelyje įveskite Primary Access Key kodą:

azure16

Svarbu pažymėti, kad naujus BLOB saugyklos duomenis reikia nurodyti ne tik StorageConnectionString prisijungimo eilutėje, bet ir standartinėje DiagnosticsConnectionString prisijungimo eilutėje.

Tam kad patikrinti ar saugykla veikia, užtenka paleisti aplikaciją derinimui. Įsitikinus, kad viskas veikia kaip numatyta, galite išpublikuoti aplikaciją į Windows Azure kaip buvo aprašyta antroje dalyje.

Veikiantį programos pavyzdį galite rasti adresu http://hellocloud.cloudapp.net/Blob.aspx.

Kitoje dalyje…

Parodysiu kaip tą patį funkcionalumą galima pasiekti naudojant esybių lenteles (Tables) vietoje binarinės saugyklos (BLOB).

Windows Azure – 4 dalis

Parašė Sergejus | 2010-01-20 00:19

Šioje dalyje mes panaudosime prieš tai sukonfigūruotą lokalią BLOB saugyklą. Kaip pavyzdį aš pateiksiu ASP.NET puslapį, kuriame galima pridėti naują failą į objektinę BLOB saugyklą, atvaizduoti esamus failus, juos parsisiųsti bei ištrinti. Po ilgų svarstymų, aš nusprendžiau apvilkti visas operacijas su Windows Azure į repozitorijaus (angl. repository) projektavimo šabloną.

BLOB pagrindai

BLOB saugykla – tai viena iš Windows Azure objektinių saugyklų, kuri yra skirta binarinių duomenų saugojimui. BLOB saugykla yra sudaryta iš konteinerių – katalogų analogo failų sistemoje. Būtent konteineriuose mes saugome BLOBus (duomenis). BLOBuose fiziškai saugomi ne tik duomenys, bet ir metaduomenys bei atitinkama unikali HTTP nuoroda (ID analogas).

BLOBus galima pasiekti dviem būdais: naudojant pastarąją nuorodą ir REST HTTP operacijas, arba specialų .NET API (jis toliau ir bus nagrinėjamas). Abiems atvejais vietoje ID naudojama nuoroda (Uri formatu).

„Hello World“ projekto pakeitimai

Už pagrindą aš pasiėmiau 2 dalyje aprašytą „Hello World“ Windows Azure ASP.NET aplikaciją. Kadangi darbui su objektinėmis saugyklomis mums reikės nurodyti Windows Azure prisijungimo duomenis, tam HelloWorldCloud projekte reikia nueiti į nustatymus ir pridėti naują prisijungimo eilutę, kurią aš pavadinau StorageConnectionString:

azure14

Atkreipkite dėmesį, kad laikinai mes naudojame ne realius Windows Azure prisijungimo duomenis, bet lokalią saugyklą. Kitas svarbus momentas – Web rolės klasės aprašymas. Kadangi Windows Azure BLOB saugykla nepriklauso nuo.NET vykdymo aplinkos (skaitykit nuo Microsoft.WindowsAzure.ServiceRuntime), reikia HelloWorldWeb projekte sukurti Web rolės klasę ir joje nusakyti kaip reaguoti į konfigūracijos failo pakeitimus. Žemiau pateiktas kodas yra nukopijuotas iš Windows Azure SDK, tikiuosi ateityje Microsoft sugalvos patogesnį sprendimą:

public class WebRole : RoleEntryPoint
{
    public override bool OnStart()
    {
        DiagnosticMonitor.Start("DiagnosticsConnectionString");

        // This code sets up a handler to update CloudStorageAccount instances when their corresponding
        // configuration settings change in the service configuration file.
        CloudStorageAccount.SetConfigurationSettingPublisher((settingName, configSetter) =>
        {
            // Provide the configSetter with the initial value
            configSetter(RoleEnvironment.GetConfigurationSettingValue(settingName));

            RoleEnvironment.Changed += (sender, arg) =>
            {
                if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                    .Any(change => (change.ConfigurationSettingName == settingName)))
                {
                    // The corresponding configuration setting has changed, propagate the value
                    if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(settingName)))
                    {
                        // In this case, the change to the storage account credentials in the
                        // service configuration is significant enough that the role needs to be
                        // recycled in order to use the latest settings. (for example, the 
                        // endpoint has changed)
                        RoleEnvironment.RequestRecycle();
                    }
                }
            };
        });

        // For information on handling configuration changes
        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
        RoleEnvironment.Changing += (sender, arg) =>
        {
            // If a configuration setting is changing
            if (arg.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
            {
                // Set e.Cancel to true to restart this role instance
                arg.Cancel = true;
            }
        };

        return base.OnStart();
    }
}

Puslapio sukūrimas

Kadangi puslapyje mes operuosime failais, apibrėžkime pagalbinę klasę FileMetaData, kurioje saugosime failo pavadinimą, turinio tipą bei failo nuorodą BLOBo saugykloje (turi būti unikali):

public class FileMetaData
{
    public Uri Uri { get; set; }
    public string FileName { get; set; }
    public string ContentType { get; set; }
}

Dabar apibrėšime repozitorijaus interfeisą su mums reikalingomis operacijomis:

public interface IFileRepository
{
    IEnumerable<FileMetaData> List();
    byte[] Get(Uri uri);
    void Insert(FileMetaData metaData, byte[] file);
    void Delete(Uri uri);
}

Aptarkime kiekvieno metodo paskirtį:

  • metodas List skirtas pateikti BLOB saugykloje saugomų failų sąrašą (be tų failų duomenų)
  • metodas Get gauna nurodyto failo duomenis
  • metodas Insert įterpia į BLOB saugyklą failą kartu su jo metaduomenimis
  • metodas Delete ištrina nurodytą failą iš BLOB saugyklos

Nesigilinant į IFileRepository realizaciją, pateiksiu Web puslapio kodą:

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="HelloWorldWeb._Default" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Failų sąrašas</title>
</head>
<body>
    <form id="form" runat="server">
    <h1>Failai</h1>
    Pridėti naują
    <asp:FileUpload ID="FileUpload" runat="server" />
    <asp:Button runat="server" Text="Pridėti" OnClick="UploadFile" />
    <asp:ListView ID="Files" runat="server">
        <LayoutTemplate>
            <ul>
                <li id="itemPlaceHolder" runat="server" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <li>
                <a href='<%# Eval("Uri") %>'> <%# Eval("FileName") %> </a>
                <asp:LinkButton runat="server" Text="[x]" OnCommand="DeleteFile"
                    CommandArgument='<%# Eval("Uri") %>' />
            </li>
        </ItemTemplate>
    </asp:ListView>
    </form>
</body>
</html>

Kaip matote, puslapyje tėra failo pridėjimo elementas bei sąrašas jau pridėtų failų su galimybe ištrinti. Failų pavadinimas yra atvaizduojamas kaip nuoroda, kad galima būtų jį parsisiųsti paprastu paspaudimu. C# pusė atrodo taip:

public partial class _Default : Page
{
    private readonly IFileRepository repository =
        new FileRepository("files", "StorageConnectionString");

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ListFiles();
        }
    }

    protected void UploadFile(object sender, EventArgs e)
    {
        if (FileUpload.HasFile)
        {
            var file = FileUpload.FileBytes;
            var metaData = new FileMetaData
                               {
                                   FileName = FileUpload.PostedFile.FileName,
                                   ContentType = FileUpload.PostedFile.ContentType
                               };

            repository.Insert(metaData, file);

            ListFiles();
        }
    }

    protected void DeleteFile(object sender, CommandEventArgs e)
    {
        repository.Delete(new Uri(e.CommandArgument.ToString()));

        ListFiles();
    }

    private void ListFiles()
    {
        Files.DataSource = repository.List();
        Files.DataBind();
    }
}

Repozitorijaus dėka, šis ASP.NET puslapis neturi jokio supratimo apie Windows Azure panaudojimą.

FileRepository įgyvendinimas

Žemiau pateiktą FileRepository realizaciją aš pabandžiau maksimaliai paaiškinti komentarų pagalba. Atskirai norėtųsi tik paminėti FileRepository konstruktorių: jis priima du argumentus – BLOB konteinerio pavadinimą (leistinos tik mažosios raidės bei skaičiai) ir prisijungimo prie BLOB saugyklos eilutės pavadinimą iš mūsų konfigūracijos failo.

public class FileRepository : IFileRepository
{
    private readonly CloudBlobContainer blobContainer;

    public FileRepository(string container, string connectionString)
    {
        // aprašome mūsų BLOB klientą
        var storageAccount = CloudStorageAccount.FromConfigurationSetting(connectionString);
        var blobClient = storageAccount.CreateCloudBlobClient();

        // nustatome viešą prieigą prie duomenų
        var permissions = new BlobContainerPermissions();
        permissions.PublicAccess = BlobContainerPublicAccessType.Container;

        // pagal nurodytą vardą gauname egzistuojantį konteinerį arba sukuriame naują
        blobContainer = blobClient.GetContainerReference(container);
        blobContainer.CreateIfNotExist();
        blobContainer.SetPermissions(permissions);
    }

    public IEnumerable<FileMetaData> List()
    {
        // gauname informaciją apie prieinamus BLOBus
        var blobItems = blobContainer.ListBlobs();
        var metaData = new List<FileMetaData>();

        foreach (var blobItem in blobItems)
        {
            // gauname nuorodą į BLOBą...
            var blob = blobContainer.GetBlobReference(blobItem.Uri.ToString());
            // ... ir jo meta duomenis
            blob.FetchAttributes();

            // sukuriame objektą atvaizdavimui
            metaData.Add(new FileMetaData
                             {
                                 Uri = blob.Uri,
                                 FileName = blob.Metadata["FileName"],
                                 ContentType = blob.Properties.ContentType
                             });
        }

        return metaData;
    }

    public byte[] Get(Uri uri)
    {
        // parsisiunčiame duomenis
        return blobContainer.GetBlockBlobReference(uri.ToString()).DownloadByteArray();
    }

    public void Insert(FileMetaData metaData, byte[] file)
    {
        // sukuriame naują BLOBą
        var blob = blobContainer.GetBlobReference(Guid.NewGuid().ToString());
        // siunčiame failo duomenis...
        blob.UploadByteArray(file);
        // ... bei nurodome meta duomenis
        blob.Metadata["FileName"] = metaData.FileName;
        blob.SetMetadata();
        blob.Properties.ContentType = metaData.ContentType;
        blob.SetProperties();
    }

    public void Delete(Uri uri)
    {
        // gauname nuorodą į BLOBą...
        var blob = blobContainer.GetBlobReference(uri.ToString());
        // ir bandome jį ištrinti
        blob.DeleteIfExists();
    }
}

Kitoje dalyje…

Parodysiu kaip panaudoti realią Windows Azure BLOB saugyklą.