.NET MAUI (Multi-platform App UI) tuo monia mahdollisuuksia sovellusten kehittämiseen, erityisesti silloin, kun tavoitellaan eri käyttöjärjestelmiä, kuten Windowsia ja Androidia. Tässä käsitellään useita tärkeitä toiminnallisuuksia, jotka liittyvät tiedostojen valintaan, kuvien hallintaan ja laitteen tietojen saamiseen.

Ensimmäinen vaihe, joka liittyy tiedostojen valintaan, on varsin yksinkertainen. Sovelluksessa käyttäjä voi valita tekstin tiedoston, kuten esimerkissä sample.txt. Tiedoston polku ja sisältö näkyvät käyttöliittymässä selkeästi, ja tämä ominaisuus on tärkeä, koska se mahdollistaa tiedon tuomisen sovellukseen paikalliselta laitteelta. Käyttäjä voi valita tiedoston omasta laitteestaan, ja tiedoston polku ja sisältö tulevat näkyviin. Tämä vaihe on erityisen hyödyllinen tilanteissa, joissa sovellus tarvitsee käyttäjältä tietoja ulkoisista lähteistä tai halutaan käyttää paikallisesti tallennettuja tiedostoja.

Sovelluksen toinen keskeinen ominaisuus on kuvan valinta. Tällöin käyttäjä voi valita kuvan esimerkiksi verkosta ladattujen kuvien joukosta. Tämä prosessi on selkeä, ja kun kuva on ladattu, se näkyy heti sovelluksessa. Android-alustalla tämä näkyy erityisen hyvin, kun kuva lisätään valitsemalla "Pick Image" ja etsimällä viimeisimpien ladattujen kuvien joukosta.

Kolmas vaihe liittyy kameralaitteen käyttöön. .NET MAUI:ssa on mahdollista ottaa valokuva suoraan sovelluksesta, ja käyttäjä saa ilmoituksen, jos sovellus pyytää lupaa käyttää kameraa. Tämä lupapyyntö on tärkeä osa sovelluksen turvallisuutta ja yksityisyyttä, ja käyttäjällä on aina mahdollisuus kieltäytyä pyynnöstä.

Kun tarkastellaan laajempia toiminnallisuuksia, kuten ikkunoiden luomista, huomioimme, että .NET MAUI tukee uusien ikkunoiden luomista. Tämä on tärkeä erottava tekijä verrattuna vanhaan Xamarin.Forms-tekniikkaan, joka ei tukenut ikkunoiden luontia mobiililaitteilla. Windows-käyttöjärjestelmässä on mahdollista avata uusia ikkunoita, mikä lisää sovellusten monipuolisuutta. Jos käyttäjä painaa "New Window" -painiketta Windows-sovelluksessa, uusi ikkuna avautuu ja näyttää sovelluksen sisällön. Mobiililaitteilla tätä toimintoa ei tueta, mutta sen voi estää yksinkertaisella merkinnällä IsEnabled="{OnPlatform False, WinUI=True}", jolloin painike on näkyvissä vain Windows-alustalla.

Laiteinformaatioiden käsittely on toinen tärkeä osa sovellusten kehittämistä. Sovelluksessa voidaan kerätä tietoa laitteen akun tilasta, näytön koosta ja tiheydestä sekä laitteen mallista ja käyttöjärjestelmäversiosta. Android-laitteilla on erityisesti huomioitava se, että käyttöoikeudet, kuten akun ja muiden laiteominaisuuksien lukeminen, vaativat erillisen luvan. Tämä lisäturvatoimenpide varmistaa, että käyttäjä voi itse päättää, mitä tietoja sovellus voi kerätä ja käyttää.

Tietojen keräämiseksi on tärkeää luoda uusi DeviceInfoViewModel -luokka, joka sitoo kaikki tarvittavat tiedot käyttöliittymään. Tämä luokka tarjoaa yksinkertaisia ominaisuuksia, kuten näytön resoluution, laitteen mallin ja käyttöjärjestelmän version. Nämä tiedot voidaan sitoa suoraan näkymään OrdersPage.xaml-tiedostossa, jolloin ne näkyvät käyttäjälle reaaliaikaisesti.

Laiteinformaatioiden näyttämiseen voidaan käyttää erityyppisiä kehyksiä (Frame), jotka tarjoavat visuaalisesti selkeitä esitystapoja. Tämä on hyödyllistä, kun halutaan antaa käyttäjälle palautetta siitä, millä laitteella hän käyttää sovellusta, tai jos sovellus tarvitsee laitekohtaisia asetuksia, kuten näytön kirkkauden tai virkistystaajuuden säätämistä.

Yhteenvetona voidaan todeta, että .NET MAUI tuo monia tärkeitä ominaisuuksia, jotka parantavat sovelluksen käytettävyyttä ja monipuolisuutta. Tiedostojen valinta, kuvien käsittely, kameran käyttö ja laiteinformaatioiden kerääminen ovat kaikki keskeisiä toimintoja, jotka tekevät sovelluksista dynaamisempia ja käyttäjäystävällisempiä. On tärkeää ymmärtää, että vaikka nämä toiminnot voivat vaikuttaa yksinkertaisilta, niiden hallinta vaatii tarkkaa huomiota käyttöjärjestelmän erityispiirteisiin ja käyttöoikeuksiin.

Miten hallita relaatiotietoja SQL Serverillä .NET:ssä

Relaatiotietokantojen hallinta on keskeinen osa monien ohjelmistojen ja palveluiden rakentamista. SQL Server, joka on yksi maailman käytetyimmistä relaatiotietokannan hallintajärjestelmistä (RDBMS), tarjoaa tehokkaat työkalut tietojen tallentamiseen, hakemiseen ja käsittelemiseen. Tässä luvussa käsitellään SQL Serverin, Azure SQL Databasen ja Azure SQL Edgen käyttöä .NET:n kanssa sekä esimerkkejä käytännön sovelluksista, jotka liittyvät tietojen hallintaan.

Tietokantojen ymmärtäminen ja hallinta
Tämä luku keskittyy erityisesti SQL Serveriin, joka on Microsoftin kehittämä relaatiotietokannan hallintajärjestelmä. SQL Serverin avulla voidaan hallita suuria tietomääriä luotettavasti ja tehokkaasti, ja se on käytettävissä sekä Windowsilla että Linuxilla. Lisäksi cross-platform kehittäjille tarjotaan vaihtoehtoja kuten Azure SQL Database ja Azure SQL Edge, jotka tarjoavat pilvipohjaisia tai kontissa toimivia ratkaisuja.

SQL Server toimii sekä pienissä että suurissa projekteissa, mutta se vaatii hallitsemista ja oikeiden työkalujen käyttöä optimaalisen suorituskyvyn varmistamiseksi. Tietojen hallintaa voidaan lähestyä eri tasoilla: alhaisella tasolla, käyttäen ADO.NET-kirjastoja (Microsoft.Data.SqlClient), tai korkeammalla tasolla, hyödyntäen Entity Framework Corea (EF Core), joka tuo objektikuvauksen ja tietovarastojen välisen yhteyden helposti hallittavaan muotoon.

Tietojen hallinta Transact-SQL:llä ja ADO.NET:llä

Yksi ensimmäisistä askelista SQL Serverin kanssa on oppia käyttämään Transact-SQL:ää (T-SQL), joka on SQL Serverin laajennettu versio SQL-kielestä. Tämä kieli mahdollistaa perustoimintojen, kuten tietojen lisäämisen, hakemisen, päivittämisen ja poistamisen, toteuttamisen. T-SQL tarjoaa myös laajempia toimintoja, kuten virheenkäsittelyn ja transaktioiden hallinnan, jotka ovat elintärkeitä tuotantoympäristössä.

Toisaalta ADO.NET-kirjasto tarjoaa matalamman tason yhteyksiä SQL Serveriin. ADO.NET:n avulla voidaan suoraan hallita tietokannan yhteyksiä ja suorittaa SQL-komentoja ohjelmallisesti. Tämä on erityisen hyödyllistä, kun halutaan tarkempaa hallintaa tietokannan yhteyksistä ja suorituskyvystä, mutta se vaatii enemmän käsityötä ja koodia verrattuna korkeampitasoisiin työkaluihin, kuten EF Coreen.

EF Core ja perinnön hallinta

EF Core on moderni ORM (Object-Relational Mapper), joka yhdistää tietokannan ja ohjelmointikielen (esimerkiksi C#) objektit, helpottaen tietojen käsittelyä ja säästäen kehittäjän aikaa. EF Core mahdollistaa tietokannan objekti-mallin määrittämisen ja tietojen käsittelyn objektiorientaatiossa.

Erityisen tärkeää EF Core:ssa on sen kyky hallita perinnön hierarkioita. Tietokannan mallit voivat olla monimutkaisempia, ja perinnön käsittely on usein haasteellista. EF Core tarjoaa kolme eri strategiaa perinnön kartoitukseen, mikä mahdollistaa erilaisten perintö- ja sukupuu-rakenteiden käyttämisen tietokannan rakenteessa.

Esimerkkitietokannan käyttäminen
Esimerkkitietokanta on erinomainen tapa oppia relaatiotietokannan käsittelyä. Tässä luvussa käytämme Microsoftin Northwind-tietokantaa, joka on ollut käytössä vuodesta 1990-lopulta. Tämä tietokanta sisältää yhdeksän keskeistä taulua, ja sen rakenne on yksinkertainen, mutta silti riittävän monimutkainen harjoitteluun. Northwind tarjoaa todellisuuteen verrattavissa olevan esimerkin, joka auttaa ymmärtämään relaatiotietokannan hallinnan perusperiaatteet.

Northwind-tietokannan tärkeimpiin tauluihin kuuluvat muun muassa tuotekategoriat, tuotteet, asiakkaat, tilaukset ja työntekijät. Tietokannan rakenne on relaatioita täynnä: kunkin tuotteen kategoria yhdistetään omalla ainutlaatuisella tunnisteellaan, ja tuotteet taas yhdistetään toimittajiin ja tilauksiin, joilla on oma yhteys asiakkaille ja työntekijöille. Tämä esimerkki on ihanteellinen aloituspaikka SQL Serverin ja .NET:n yhteiskäytölle.

Yhteyden muodostaminen SQL Serveriin
SQL Serveriin yhdistäminen on yksinkertaista, mutta se vaatii muutamia keskeisiä tietoja, kuten palvelimen nimen ja tietokannan nimen. Yhteys merkitään yhteysmerkkijonolla, joka määrittää myös turvallisuusasetukset, kuten käyttäjätunnukset ja salasanat. Tärkeää on huomata, että jos käytetään Azure SQL -tietokantaa, Windows Authentication ei ole tuettu, joten sen sijaan täytyy käyttää SQL Serverin käyttäjätunnuksia ja salasanoja.

Hyvä käytäntö on käyttää pistettä (.) paikalliselle palvelimelle yhdistettäessä, mikä helpottaa koodin siirrettävyyttä ja käytettävyyttä eri ympäristöissä. Myös eri SQL Server -versiot voivat vaatia erityisiä konfiguraatioita, ja esimerkiksi Azure SQL Database tai Azure SQL Edge käyttävät hieman erilaisia yhteysasetuksia.

SQL Serverin asennus ja käyttöönotto
SQL Serverin asentaminen on melko suoraviivaista. Microsoft tarjoaa useita eri versioita, kuten SQL Server Developer Editionin, joka on ilmainen ja soveltuu erinomaisesti kehityskäyttöön. Voit myös käyttää SQL Server Expressiä tai SQL Server LocalDB:tä, jotka ovat kevyempiä vaihtoehtoja. Jos haluat käyttää cross-platform -ratkaisua, voit käyttää Azure SQL Databasea tai asentaa Azure SQL Edgen Docker-konttiin.

Jokaisessa tapauksessa on tärkeää luoda ja ladata oikea esimerkkitietokanta, kuten Northwind, joka auttaa sinua ymmärtämään ja testaamaan SQL Serverin ominaisuuksia käytännössä.

Tietoturva ja parhaat käytännöt

SQL Serverin kanssa työskentelevän kehittäjän on tärkeää kiinnittää huomiota tietoturvaan. Yhteyksien salaaminen SSL:llä, käyttäjätunnusten ja salasanojen hallinta sekä yhteyksien aikarajojen asettaminen ovat avainasemassa turvallisuuden varmistamisessa. Lisäksi on hyvä käytäntö poistaa salasana yhteysmerkkijonosta autentikoinnin jälkeen, jos se ei ole enää tarpeen.

Kuinka luoda ja laajentaa EF Core -pohjainen tietomallikirjasto SQL Server -ympäristössä

Kun tietokanta on jo olemassa ja sen taulut on määritelty, seuraava vaihe on luoda ohjelmallinen malli, joka vastaa näitä tauluja. Tämä tehdään dotnet ef dbcontext scaffold -komennolla, jossa annetaan yhteysmerkkijono, määritetään käytettävä tietokantamoottori sekä määritellään, mihin nimiavaruuteen luodut luokat sijoitetaan. Kun käytetään SQL Serveriä, komento voi näyttää seuraavalta:

vbnet
dotnet ef dbcontext scaffold "Data Source=.;Initial Catalog=Northwind;Integrated Security=true;TrustServerCertificate=True;" Microsoft.EntityFrameworkCore.SqlServer --namespace Packt.Shared --data-annotations

Tämä komento generoi 28 luokkaa, jotka kuvaavat tietokannan rakennetta. Esimerkiksi Customer.cs-tiedostossa CustomerId-kenttä tunnistetaan ensisijaiseksi avaimena, jonka maksimipituus on viisi merkkiä. Jos halutaan rajoittaa sallitut arvot vain isoihin länsimaisiin kirjaimiin, attribuuttia voidaan laajentaa seuraavasti:

csharp
[Key]
[StringLength(5)] [RegularExpression("[A-Z]{5}")] public string CustomerId { get; set; } = null!;

Kun entiteetit on luotu, seuraava askel on erottaa tietokantayhteyttä hallinnoiva konteksti omaan luokkalibraarioonsa. Tätä varten luodaan uusi Class Library -projekti, esimerkiksi nimellä Northwind.Common.DataContext.SqlServer. Projektiin lisätään viittaus entiteettimallien sisältävään projektiin ja tarvittava EF Core -paketti SQL Serverille.

NorthwindContext.cs-tiedosto siirretään uuteen projektiin. Samalla poistetaan oletusyhteysmerkkijonosta varoitusviesti, joka liittyy sen kovakoodaukseen. Kontekstiluokkaan voidaan lisätä myös laajennusmetodi, joka sallii sen injektoimisen riippuvuuksienhallintaan konfiguroitavalla yhteysmerkkijonolla:

csharp
public static IServiceCollection AddNorthwindContext(
this IServiceCollection services, string connectionString = "Data Source=.;Initial Catalog=Northwind;" + "Integrated Security=true;MultipleActiveResultsets=true;Encrypt=false") { services.AddDbContext<NorthwindContext>(options => { options.UseSqlServer(connectionString); options.LogTo(Console.WriteLine, new[] { Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.CommandExecuting }); }); return services; }

Tämä rakenne mahdollistaa sovelluksen tietomallin jakamisen loogisesti useaan projektiin. Se myös parantaa ylläpidettävyyttä ja testattavuutta, koska konteksti ja entiteetit voidaan käsitellä erillään.

EF Core 7 tuo uuden IMaterializationInterceptor-rajapinnan, jonka avulla voidaan puuttua entiteetin luonnin ja alustuksen vaiheisiin. Tämä tarjoaa mahdollisuuden lisätä automaattisesti lasketut ominaisuudet, kuten viimeisimmän päivitysajan. Tämän toteuttamiseksi vaaditaan neljä vaihetta:

  1. Määritellään rajapinta IHasLastRefreshed, joka sisältää LastRefreshed-ominaisuuden.

  2. Toteutetaan rajapinta ainakin yhdessä entiteetissä, esimerkiksi Employee-luokassa:

    csharp
    [NotMapped]
    public DateTimeOffset LastRefreshed { get; set; }
  3. Luodaan SetLastRefreshedInterceptor, joka asettaa LastRefreshed-arvon entiteetille alustuksen yhteydessä:

    csharp
    public object InitializedInstance(MaterializationInterceptionData data, object entity) { if (entity is IHasLastRefreshed tracked) { tracked.LastRefreshed = DateTimeOffset.UtcNow; } return entity; }
  4. Rekisteröidään interceptor NorthwindContext-luokan OnConfiguring-metodissa:

    csharp
    private static readonly SetLastRefreshedInterceptor interceptor = new();
    optionsBuilder.AddInterceptors(interceptor);

Tämä rakenne luo pohjan automaattiselle metatiedon hallinnalle ja parantaa sovelluksen kykyä käsitellä entiteettien tilatietoja dynaamisesti. Se myös mahdollistaa tulevaisuudessa hienostuneemman välimuistin hallinnan ja optimoinnin käyttämällä ajastettua uudelleenpäivitystä ilman ulkopuolista logiikkaa.

On tärkeää ymmärtää, että EF Core -mallien ja kontekstin rakenne ei ole vain tekninen yksityiskohta, vaan se määrittää koko sovelluksen tiedonhallinnan arkkitehtuurin. Luokkien välinen vastuunjako, tiedon validointi, tietoturva yhteysmerkkijonojen kautta, sekä laajennettavuus ovat kaikki rakenteellisia kysymyksiä, joilla on suora vaikutus ohjelmiston vakauteen ja tulevaisuuden kehityskelpoisuuteen. Tietokantainterseptoreiden, kuten IMaterializationInterceptor, käyttöönotto mahdollistaa sovelluksen käyttäytymisen hienosäädön ilman, että ydinlogiikkaa tarvitsee muuttaa – tämä tuo modulaarisuutta ja luo edellytykset ammattimaiselle ohjelmistoarkkitehtuurille.

Miten autentikointi ja valtuutus toimivat roolien ja väitteiden avulla?

Tietoturvan ja käyttäjänhallinnan tehokas hallinta on keskeinen osa nykyaikaisten sovellusten ja järjestelmien turvallisuutta. Yksi yleisimmistä tavoista hallita käyttäjien pääsyä järjestelmän resursseihin on käyttää rooleja ja väitteitä (claims). Tämä malli mahdollistaa sen, että käyttäjän rooli tai jäsenyys tietyssä ryhmässä voidaan määrittää eikä yksittäisten käyttöoikeuksien tarvitse muuttua aina, kun käyttäjän rooli tai jäsenyys muuttuu.

Esimerkiksi sen sijaan, että määritettäisiin käyttöoikeudet suoraan yksittäiselle käyttäjälle, kuten Buckinghamin palatsin käyttöoikeudet Charles Philip Arthur George Windsorille, voidaan käyttöoikeudet määrittää Yhdistyneen kuningaskunnan monarkille (rooli). Tässä tilanteessa Charles olisi vain yksi roolin jäsen. Tulevaisuudessa, kun seuraava henkilö valtaistuimelle nousee, ei tarvitsisi muuttaa mitään monarkin roolin käyttöoikeuksissa, vaan riittäisi, että Charles poistetaan roolista ja uusi perijä lisätään. Tämä mahdollistaa järjestelmän joustavuuden ja helpottaa pitkän aikavälin ylläpitoa ilman tarpeetonta työtä.

Käyttäjän tunnistaminen ja valtuuttaminen voidaan toteuttaa eri mekanismeilla, mutta kaikki niistä perustuvat kahta keskeistä rajapintaa: IIdentity ja IPrincipal. IIdentity vastaa käyttäjän tunnistamisesta ja sisältää esimerkiksi käyttäjän nimen ja sen, onko käyttäjä onnistuneesti autentikoitu. IPrincipal puolestaan yhdistää käyttäjän roolit ja jäsenyydet ryhmissä, mahdollistaen käyttäjän valtuutuksen määrittämisen.

Käyttäjän tunnistaminen toteutetaan usein väitteillä (claims), jotka voivat olla käyttäjän nimen, roolin, syntymäajan tai muiden ominaisuuksien mukaisia. Väitteet tallennetaan Claim-luokassa, joka sisältää tietoja esimerkiksi väitteen tyypistä, arvosta ja alkuperäisestä liittäjästä. Väitteet ovat keskeinen osa käyttäjän roolin ja pääsyn hallintaa, ja ne voivat olla yksinkertaisia, kuten roolin nimeä tai monimutkaisempia, kuten henkilötunnuksen tai muiden turvallisuusmerkintöjen käyttöä.

Autentikointi ja valtuutus voidaan toteuttaa useilla eri tavoilla. Yksi esimerkki on luoda mukautettu autentikointi- ja valtuutusmekanismi, joka käyttää väitteitä ja rooleja käyttäjän tietojen hallintaan. Tässä prosessissa käyttäjän rekisteröinti voi sisältää roolien määrittämisen, ja kirjautumisessa käytetään luotua identiteettiä ja pääsyoikeuksia, jotka liittyvät käyttäjän rooleihin.

Tämä lähestymistapa mahdollistaa sen, että käyttäjän pääsyoikeuksia ei tarvitse määrittää erikseen kaikissa paikoissa, vaan pääsynhallinta voidaan hoitaa roolien ja väitteiden avulla. Käyttäjän rekisteröinnin ja kirjautumisen jälkeen järjestelmä voi tarkistaa käyttäjän oikeudet ja pääsyn perustoimintoihin määrittelemällä ne roolien ja väitteiden perusteella.

Tämä lähestymistapa tuo etuja erityisesti suurille ja dynaamisille organisaatioille, joissa käyttäjien roolit voivat muuttua usein. Sen sijaan, että hallittaisiin yksittäisiä käyttöoikeuksia manuaalisesti, roolit ja väitteet mahdollistavat joustavan ja skaalautuvan järjestelmän, jossa muutokset voidaan tehdä helposti ilman, että tarvitsisi käsitellä kaikkia yksittäisiä käyttöoikeuksia.

Käyttäjien hallintamalli, joka perustuu rooleihin ja väitteisiin, tuo myös etuja organisaation turvallisuudelle. Koska käyttäjä voi kuulua useisiin rooleihin samanaikaisesti, voidaan hallita monimutkaisempia pääsynhallintakysymyksiä tehokkaammin. Esimerkiksi yrityksessä, jossa työntekijä on vastuussa sekä myynnistä että tiimijohtamisesta, voidaan antaa oikeudet kummassakin roolissa ilman, että täytyy luoda erillisiä käyttöoikeuksia jokaista tehtävää varten.

Autentikoinnin ja valtuutuksen toteutuksessa on tärkeää ymmärtää, että väitteet ja roolit eivät ole vain yksinkertaisia muuttujia. Ne ovat keskeisiä elementtejä, jotka määrittävät, kuinka käyttäjä voi vuorovaikuttaa järjestelmän kanssa ja millaisia resursseja hänellä on oikeus käyttää. Väitteet voivat olla yksilöllisiä ja ne voivat liittyä moneen eri turvallisuusmekanismiin, kuten monivaiheiseen tunnistautumiseen tai erityisiin käyttöoikeustarkastuksiin.

Lisäksi, vaikka roolit ja väitteet tekevät järjestelmästä joustavan ja tehokkaan, on tärkeää huolehtia myös niiden turvallisesta hallinnasta. Väitteiden väärinkäyttö tai roolien väärä määrittäminen voi johtaa vakaviin turvallisuusongelmiin. Esimerkiksi väärin määritelty rooli voi antaa käyttäjälle pääsyn tärkeisiin tietoihin, joita hän ei saisi nähdä. Siksi on tärkeää, että roolit ja väitteet ovat selkeästi määriteltyjä, ja niiden käyttö on rajoitettu vain niihin tilanteisiin, joissa ne ovat tarpeen.

Tietoturvan ja pääsynhallinnan hallinta ei ole vain tekninen haaste, vaan myös organisatorinen kysymys. Pääsynhallinta ja autentikointi eivät ole vain ohjelmointitehtäviä, vaan ne vaativat myös selkeän ymmärryksen siitä, miten organisaatio toimii ja mitkä sen tarpeet ovat. Tämä on erityisen tärkeää, kun järjestelmän käyttäjien määrä kasvaa ja roolit monimutkaistuvat. Tällöin on tärkeää, että roolit ja väitteet pysyvät hallittavina ja joustavina ilman, että niiden käyttö estää tai vaikeuttaa järjestelmän turvallisuutta.