.NET MAUI (Multi-platform App UI) on tehokas työkalu mobiilisovellusten kehittämiseen, ja se tarjoaa mahdollisuuden luoda monialustaisia sovelluksia, jotka toimivat niin Androidilla, iOS:llä kuin Windowsilla. Tässä osassa käymme läpi, kuinka luoda yksinkertainen asiakastietosovellus, joka tukee asiakastietojen lisäämistä, muokkaamista ja puhelun soittamista suoraan asiakaskortista. Tämän lisäksi pohdimme, kuinka testaamme sovelluksen toimivuutta Android-emulaattorilla ja kuinka käsittelemme web-palveluja, joiden avulla voimme saada asiakastiedot pilvestä.

Asiakastietosovelluksen rakenne

Kun luodaan käyttöliittymää .NET MAUI:ssa, joka sisältää Grid-rakenteen, on tärkeää ymmärtää, että kontrollerit, jotka kuuluvat Grid-elementtiin, saavat oletusarvoisesti Grid.Row ja Grid.Column -arvot 0. Tämä tarkoittaa sitä, että asiakastunnuksen tai muiden vastaavien elementtien kohdalla nämä arvot eivät tarvitse olla erikseen määriteltyjä. Tämä yksinkertaistaa käyttöliittymän määrittelyä ja vähentää tarpeettoman koodin kirjoittamista.

Asiakastietosivun toiminta on suunniteltu niin, että käyttäjä voi lisätä, muokata ja poistaa asiakkaita. Tämä tapahtuu ViewModel-rakenteen avulla, joka sitoo käyttöliittymän logiikan ja esityksen toisiinsa. CustomerDetailPage.xaml.cs-tiedostoon luodaan kaksi eri konstruktoria: yksi uuden asiakkaan lisäämistä varten ja toinen olemassa olevan asiakkaan muokkaamista varten. Uuden asiakkaan lisäämisen yhteydessä BindingContext asetetaan uusiksi asiakastiedoiksi, ja näkymä vaihtuu "Add Customer" -otsikkoon. Muokkaustilassa taas Insert-nappi piilotetaan, koska muokkaus tapahtuu olemassa olevan asiakastiedon pohjalta ja kaikki muutokset päivittyvät suoraan näkymään.

Puhelun soittaminen asiakastiedostuksesta

.NET MAUI -sovelluksessa voidaan myös hyödyntää laitteiston puhelutoimintoja, jolloin käyttäjä voi soittaa puheluja suoraan asiakaskortilta. Tämä edellyttää kuitenkin, että sovellus saa luvan käyttää puhelinsoittoja. Android-alustalla tämä tapahtuu AndroidManifest.xml-tiedoston muokkaamisella, jossa määritellään tarvittavat oikeudet puhelutoimintojen käyttämiseksi. Sen jälkeen asiakastiedon tarkastelusivulla käyttäjä voi valita asiakkaan, napsauttaa "Phone"-painiketta ja käynnistää puhelinsoiton. Tämä on erityisen hyödyllinen toiminto, joka yhdistää asiakaspalvelun ja mobiililaitteet saumattomasti.

Testausvaiheessa voidaan käyttää Android-emulaattoria, jossa käyttäjä voi testata puhelutoimintojen ja muiden käyttöliittymäelementtien toimivuutta. Emulaattorissa testaus tapahtuu valitsemalla oikea kohdekehys, joka tässä tapauksessa on net7.0-android, ja käynnistämällä sovellus Debug-tilassa. Tällöin saamme näkyviin käyttöliittymän toiminnot ja voimme varmistaa, että kaikki komponentit, kuten asiakastiedot ja puhelunsoittopainikkeet, toimivat odotetusti.

Web-palvelun kuluttaminen

Sovelluksen laajentaminen web-palveluilla on tärkeä osa mobiilisovelluksen kehitystä. Esimerkiksi asiakastietojen hakeminen ja päivitys voidaan tehdä suoraan pilvipalvelusta käsin. Apple:n App Transport Security (ATS) ja Androidin vastaava politiikka varmistavat, että kaikki sovellukset, jotka käyttävät internetyhteyksiä, tekevät sen turvallisesti. Tässä esimerkissä käsitellään tilannetta, jossa käytämme itse allekirjoitettua sertifikaattia, joka vaatii erillistä konfigurointia. Vaikka tämä asettaa haasteita, voimme yksinkertaistaa prosessia sallimalla epävarmat yhteydet ja poistamalla turvallisuustarkastuksia sovelluksesta.

Yksinkertaisen asiakastietopalvelun luomiseksi on luotava Web API -palvelu, joka toimii asiakastietokannan kanssa. Tämä mahdollistaa asiakastietojen hakemisen ja tallentamisen web-sovellukseen, joka puolestaan päivittää mobiilisovelluksen asiakastiedot. Kun mobiilisovellus ja web-palvelu on yhdistetty, saamme dynaamiset asiakastiedot, jotka päivittyvät sovelluksessa ilman tarvetta päivittää sovellusta itse.

Tärkeitä huomioita

Asiakastietosovelluksen kehittäminen ei ole pelkästään käyttöliittymän ja logiikan yhdistämistä, vaan myös monien taustateknologioiden hallintaa, kuten puhelinsoittotoimintojen, web-palveluiden ja turvallisuuden. On tärkeää ymmärtää, että vaikka sovellus voi näyttää yksinkertaiselta, sen toiminnallisuus perustuu monimutkaisempaan taustatyöhön ja teknologian ymmärtämiseen. Esimerkiksi web-palveluiden integrointi ja turvallisuusasetusten hallinta ovat ratkaisevia tekijöitä mobiilisovellusten luotettavuuden ja suorituskyvyn kannalta.

Miten System.Index ja System.Range muuttavat ohjelmointia C#:ssa?

C#:ssa taulukkojen ja merkkijonojen käsittely perustuu indekseihin ja leikkauksiin, jotka mahdollistavat tehokkaan ja selkeän tavan käsitellä tietoja. Tämä konsepti laajenee entisestään uusilla ominaisuuksilla, kuten System.Index ja System.Range, jotka tuotiin C#-kieleen versiossa 8. Näiden avulla voidaan viitata tiettyihin elementteihin ja osiin taulukosta tai merkkijonosta tavalla, joka on joustavampi ja intuitiivisempi kuin perinteiset lähestymistavat.

Indeksi määrittelee paikan taulukossa tai merkkijonossa. Esimerkiksi yksinkertaisessa taulukossa voit käyttää kokonaislukua, kuten seuraavassa esimerkissä:

csharp
int index = 3;
Person p = people[index]; // Taulukon neljäs henkilö char letter = name[index]; // Nimen neljäs kirjain

Tässä index on kokonaisluku, joka osoittaa tietyn paikan taulukossa. Kuitenkin System.Index tarjoaa entistä tarkempaa hallintaa, sillä se tukee myös laskemista taulukon lopusta päin. Tämän avulla voidaan määritellä paikkoja joustavasti riippumatta taulukon koosta.

System.Index voidaan määritellä seuraavasti:

csharp
Index i1 = new Index(value: 3); // Lasketaan alusta
Index i2 = 3; // Implicit int muunnos Index i3 = new Index(value: 5, fromEnd: true); // Lasketaan lopusta Index i4 = ^5; // Käytetään caret-operaattoria

Näissä esimerkeissä i3 ja i4 molemmat viittaavat taulukon viidenteen elementtiin, mutta i3 käyttää tarkasti määriteltyä arvoa ja laskentaa lopusta, kun taas i4 käyttää lyhyempää syntaksia, jossa caret-operaattori (^) kertoo, että indeksi lasketaan taulukon loppupäästä.

System.Range puolestaan mahdollistaa usean peräkkäisen arvon määrittämisen yhdellä kertaa. Se käyttää kahta System.Index-arvoa, jotka määrittävät alueen alku- ja loppupään:

csharp
Range r1 = new Range(start: new Index(3), end: new Index(7));
Range r2 = new Range(start: 3, end: 7); // Implicit int muunnos
Range r3 =
3..7; // Käytetään C# 8.0 syntaksia Range r4 = Range.StartAt(3); // Kolmannesta indeksistä viimeiseen Range r5 = 3..; // Kolmannesta indeksistä viimeiseen Range r6 = Range.EndAt(3); // Alusta kolmanteen indeksiin Range r7 = ..3; // Alusta kolmanteen indeksiin

Tämä mahdollistaa erittäin tiiviin syntaksin, jolla voi helposti viitata osiin taulukosta tai merkkijonosta ilman monimutkaisia silmukoita tai ehtoja.

Näiden uudenlaisten tietotyypien tuominen C#:iin tarjoaa ohjelmoijille suurempaa joustavuutta ja selkeyttä koodin kirjoittamiseen ja lukemiseen. Ne tekevät koodista vähemmän virhealtista ja helpottavat koodin ylläpitoa, koska ne selkeyttävät sitä, kuinka dataa käsitellään.

C# 9:ssä ja .NET 5:ssä esiteltiin myös merkittäviä parannuksia, kuten record-tyypit ja init-setterit, jotka mahdollistavat muuttujien määrittämisen vain luomisvaiheessa, ja target-typed new -syntaksi, joka yksinkertaistaa objektien luomista:

csharp
XmlDocument xmlDoc = new(); // Ei tarvitse toistaa tyyppiä

Tällaiset ominaisuudet tekevät koodista entistä tiiviimpää ja helpommin hallittavaa, erityisesti suurissa projekteissa, joissa tyypin määrittäminen voi olla toistuva ja turhauttava toimenpide.

Kun tarkastellaan C# 10:ää ja .NET 6:ta, projektimallien oletusasetukset on muutettu, ja ne mahdollistavat ns. globaalit using-lausunnot, jolloin yhteiset nimikkomerkit kuten System ja System.Linq voidaan määrittää vain yhdessä tiedostossa. Tämä helpottaa projektin hallintaa ja vähentää toisteisuutta:

csharp
global using System;
global using System.Linq;

Tämä ominaisuus yksinkertaistaa koodin rakennetta, erityisesti suurissa projekteissa, joissa on useita tiedostoja, jotka tarvitsevat samoja nimikkeitä.

Tällaiset uudet C#:n ja .NET:n ominaisuudet eivät vain paranna ohjelmoinnin sujuvuutta, vaan myös koodin ylläpidettävyyttä ja laajennettavuutta. Ne mahdollistavat entistä tehokkaamman ja selkeämmän tavan käsitellä dataa, luoda olioita ja organisoida koodia suurissa sovelluksissa.

On tärkeää ymmärtää, että nämä muutokset eivät ole vain syntaksin parannuksia, vaan ne myös vaikuttavat ohjelmistojen arkkitehtuuriin ja kehityskäytäntöihin. Erityisesti Index ja Range tarjoavat koodin kirjoittajalle parempaa kontrollia ja yksinkertaistavat monimutkaisia tehtäviä, kuten tietyn alueen hakemista listasta tai taulukosta. Näiden työkalujen hyödyntäminen oikein voi merkittävästi parantaa ohjelmointiprosessin selkeyttä ja vähentää virheiden mahdollisuuksia.

Miksi C# 11 ja .NET 7 ovat tärkeitä kehittäjille ja kuinka ne vaikuttavat koodauksen käytäntöihin?

C#-ohjelmointikielen ja .NET-alustan kehittyminen tuo mukanaan merkittäviä muutoksia, jotka vaikuttavat niin yksittäisiin kehittäjiin kuin koko ohjelmointi- ja sovelluskehitysprosessiin. C# 11 ja .NET 7 esittelevät uusia ominaisuuksia, jotka tekevät koodin kirjoittamisesta helpompaa ja tehokkaampaa. Erityisesti ne tuovat uusia tapoja käsitellä null-arvoja, parantavat koodin luettavuutta ja tarjoavat tukea kehittyneille laskentaoperaatioille.

Yksi merkittävä parannus C# 11:ssa on null-arvojen tarkistuksen helpottaminen. Aiemmin oli yleistä kirjoittaa pitkiä if-lauseita tarkistamaan metodien parametrit ja heittämään ArgumentNullException, jos parametri oli null. Tämä prosessi vie paljon tilaa ja voi helposti johtaa virheiden tekemiseen. C# 11 tarjoaa yksinkertaisemman tavan tehdä tämä: ArgumentNullException.ThrowIfNull(parametri). Tämä yksinkertaistaa koodia ja parantaa sen luettavuutta, samalla vähentäen virheiden mahdollisuutta.

C# 11:n tuomaa uusinta syntaksia voidaan pitää myös mielenkiintoisena, vaikka se oli alun perin kontroversiaali. Kyseessä on !!-operaattori, joka mahdollistaa null-arvojen tarkistamisen ilman erillisiä if-lauseita. Vaikka tämä syntaksi oli aluksi saatavilla esikatseluversiona, se poistettiin myöhemmin, koska kehittäjien palautteet eivät olleet yksimielisiä sen käytön suhteen. Tämän seurauksena Microsoft päätti poistaa sen, mutta silti on mahdollista, että jotkin kehittäjät kokeilevat tätä ominaisuutta omissa projekteissaan.

Uusi "raw string literals" -ominaisuus tekee tekstin käsittelystä entistä joustavampaa. Tämä on erityisen hyödyllistä silloin, kun käsitellään monimutkaisempia tekstimuotoja, kuten XML:ää, HTML:ää tai JSON:ia. Tällöin ei tarvitse huolehtia erikoismerkkien pakottamisesta, ja koodi säilyy siistinä ja luettavana. Erityisesti tämä parantaa koodin ylläpidettävyyttä ja helpottaa sen käsittelyä pitkissä ja monimutkaisissa teksteissä.

C# 11 tuo myös tukea generisille laskentatehtäville, kuten mahdollisuuden määritellä omia numeerisia tyyppejä. Vaikka tämä ei ole tavalliselle kehittäjälle jokapäiväistä käyttöä, se mahdollistaa erikoistuneempien ja räätälöityjen datatyyppien luomisen, mikä on tärkeää tietyissä korkean suorituskyvyn sovelluksissa. Tämä on tärkeä askel kohti kehittyneempää ja monipuolisempaa ohjelmointia.

Erityisen mielenkiintoista on myös C# 11:n tarjoama "required" muokkaaja, jonka avulla kenttien ja ominaisuuksien arvot voidaan asettaa pakollisiksi olion luomisen yhteydessä. Tämä lisää koodin luotettavuutta ja auttaa estämään virheitä, joita voi syntyä silloin, kun tarvittavat arvot jäävät asettamatta. Tämä ominaisuus tuo mukanaan selkeyttä ja varmuutta olioiden käytössä.

On tärkeää ymmärtää, että nämä uudet ominaisuudet eivät ole pelkästään syntaktisia muutoksia. Ne heijastavat syvempää muutosta ohjelmointikulttuurissa, jossa kehittäjien täytyy jatkuvasti löytää tasapaino tehokkuuden, luettavuuden ja virheiden ehkäisyn välillä. Uudet työkalut, kuten GitHubin käyttö koodin hallintaan, antavat kehittäjille mahdollisuuden työskennellä tehokkaammin tiimeissä ja jakaa tietoa ja korjauksia avoimesti. Tämä tuo esiin tärkeän piirteen nykyaikaisessa ohjelmistokehityksessä: yhteistyön merkitys.

C# 11:n ja .NET 7:n uudet ominaisuudet auttavat kehittäjiä kirjoittamaan puhtaampaa, turvallisempaa ja tehokkaampaa koodia. On kuitenkin tärkeää, että kehittäjät ymmärtävät myös näiden uusien työkalujen käyttöönoton vaatimukset. Koodin kirjoittaminen ei ole vain tekninen tehtävä, vaan se on osa suurempaa ajatteluprosessia, jossa tulee ottaa huomioon koodin ylläpidettävyys, virheiden ehkäisy ja tehokkuus. Nämä työkalut tarjoavat mahdollisuuksia, mutta ne vaativat myös huolellista harkintaa ja järkevää soveltamista.

Kuinka työstää kuvia ja kirjata lokitiedostoihin käytettäessä ImageSharpia ja Serilogia

Kuvien käsittely ja lokitietojen hallinta ovat keskeisiä osa-alueita monissa ohjelmistokehityksessä. Tässä käsitellään kahta tärkeää työkalua: SixLabors.ImageSharp, joka on monipuolinen kirjasto kuvankäsittelyyn, ja Serilog, joka tuo lisäarvoa lokitietojen käsittelyyn. Molemmat työkalut ovat suosittuja, ja ne tarjoavat laajat mahdollisuudet tehokkaan koodin kirjoittamiseen.

Ensimmäiseksi tarkastellaan kuvia, jotka käsitellään SixLabors.ImageSharp -kirjaston avulla. Oletetaan, että sinulla on kansio, joka sisältää useita kuvia, ja tavoitteena on muuntaa kaikki kuvat harmaasävyisiksi pikkukuviksi, joiden koko on kymmenen prosenttia alkuperäisestä. Tämä prosessi on erityisen hyödyllinen esimerkiksi verkkosivustojen kuvia optimoitaessa tai pienempien versioiden luomisessa, joita voidaan käyttää eri yhteyksissä, kuten esikatseluissa tai mobiiliversioissa.

Ensimmäinen askel on varmistaa, että kuvat ovat oikeassa kansiossa. Kuvakansio voi olla esimerkiksi ohjelman juurihakemistossa. Sen jälkeen sinun täytyy asentaa SixLabors.ImageSharp ja lisätä se projektin riippuvuuksiksi. Kun tämä on tehty, voit kirjoittaa koodin, joka käy läpi kaikki kuvat ja muuntaa ne harmaasävyisiksi pikkukuviksi. Esimerkiksi seuraavassa koodinpätkässä tehdään kuvan käsittely:

csharp
string imagesFolder = Path.Combine(Environment.CurrentDirectory, "images");
WriteLine($"I will look for images in the following folder:\n{imagesFolder}"); WriteLine(); if (!Directory.Exists(imagesFolder)) { WriteLine("Folder does not exist!"); return; } IEnumerable<string> images = Directory.EnumerateFiles(imagesFolder); foreach (string imagePath in images) { if (Path.GetFileNameWithoutExtension(imagePath).EndsWith("-thumbnail")) { WriteLine($"Skipping:\n {imagePath}"); continue; // This file has already been converted } string thumbnailPath = Path.Combine(Environment.CurrentDirectory, "images", Path.GetFileNameWithoutExtension(imagePath) + "-thumbnail" + Path.GetExtension(imagePath)); using (Image image = Image.Load(imagePath)) { WriteLine($"Converting:\n {imagePath}"); WriteLine($"To:\n {thumbnailPath}"); image.Mutate(x => x.Resize(image.Width / 10, image.Height / 10)); image.Mutate(x => x.Grayscale()); image.Save(thumbnailPath); } } WriteLine("Image processing complete. View the images folder.");

Tässä koodissa tarkistetaan ensin, että määritelty kansio on olemassa. Tämän jälkeen jokainen kuvatiedosto käsitellään: kuvaa pienennetään ja muutetaan harmaasävyiseksi, minkä jälkeen se tallennetaan uuteen tiedostoon, jonka nimeen lisätään "-thumbnail".

Kun kuvat on käsitelty, ne näkyvät nyt pienempinä ja harmaasävyisinä versioina alkuperäisistä kuvista. Tämä voi olla erityisen hyödyllistä tilanteissa, joissa kuvia tarvitsee käsitellä suuremmassa mittakaavassa.

Toinen tärkeä osa on Serilogin käyttö lokitietojen käsittelyyn. Serilog tarjoaa erinomaisen tavan kerätä ja tallentaa lokitietoja, erityisesti silloin, kun on tarpeen kirjata monimutkaisempaa tietoa. Serilog mahdollistaa strukturoitujen lokitietojen keräämisen, mikä parantaa hakemisen ja lajittelun mahdollisuuksia.

Serilogin avulla voidaan määrittää, mihin logitiedot tallennetaan. Yksi yleisimmistä tavoista on käyttää Serilogin "sink" -järjestelmää, joka määrittää, mihin tietoja kirjataan (esimerkiksi tiedostoon tai konsoliin). Esimerkiksi, jos haluat kirjoittaa lokitiedot sekä konsoliin että tiedostoon, käytät seuraavaa koodia:

csharp
using Serilog;
Log.Logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); Log.Information("This is an informational message."); Log.Warning("This is a warning message."); Log.Error("This is an error message.");

Tässä koodissa määritellään loggeri, joka kirjoittaa lokitiedot sekä konsoliin että tiedostoon, joka luodaan päivittäin. Tämä helpottaa lokitiedon hallintaa ja mahdollistaa paremman seurannan ja virheiden jäljittämisen ohjelman käytön aikana.

Serilogin käytön etuna on se, että se tukee strukturoitujen tietojen lisäämistä lokitietoihin. Tämä mahdollistaa esimerkiksi sen, että voidaan lokittaa monimutkaisempia objekteja, kuten tuoteobjekteja, käyttäen seuraavaa esimerkkiä:

csharp
var lineitem = new { ProductId = 11, UnitPrice = 25.49, Quantity = 3 }; Log.Information("Added {@LineItem} to shopping cart.", lineitem);

Tässä esimerkissä logimerkinnässä käytetään strukturoitua tietoa, joka sisältää tuotteen tiedot. Tämä mahdollistaa tiedon myöhemmän hakemisen ja analysoinnin, mikä on erityisen hyödyllistä suurissa järjestelmissä, joissa on monia eri tapahtumia.

Käytettäessä Serilogia, on myös tärkeää valita oikeat "sink" -paketit. Näitä voi lisätä projektin NuGet-pakettihallinnan kautta, ja esimerkiksi seuraavat paketit ovat yleisesti käytettyjä:

  • serilog.sinks.console

  • serilog.sinks.file

  • serilog.sinks.debug

  • serilog.sinks.mssqlserver

Kun lokitiedot tallennetaan useisiin eri paikkoihin, niiden käsittely ja analysointi on huomattavasti helpompaa. Tämä on erityisen tärkeää suurissa ja monimutkaisissa järjestelmissä, joissa on jatkuvasti kerättävää tietoa.

Yhteenvetona voidaan todeta, että sekä SixLabors.ImageSharp että Serilog tarjoavat tehokkaita ja joustavia työkaluja ohjelmoinnin eri osa-alueilla. Kuvankäsittely mahdollistaa esimerkiksi kuvien koon pienentämisen ja muuntamisen harmaasävyiksi, mikä on olennaista erityisesti verkkosivustoilla. Lokitietojen hallinta Serilogilla taas tuo lisää läpinäkyvyyttä ja tarkkuutta järjestelmän toiminnan seurantaan ja virheiden jäljittämiseen.

Miten kansainvälistämisen ja lokalisoinnin työkalut toimivat ohjelmoinnissa?

Kun työskentelemme ohjelmistojen käännöksien ja kansainvälistämisen parissa, on tärkeää ymmärtää, että pelkkä käännös ei riitä. Käännöksen lisäksi ohjelman on pystyttävä mukautumaan erilaisiin kulttuurisiin ja alueellisiin tarpeisiin, kuten päivämäärämuotoihin, valuutoihin ja kielikohtaisiin erityispiirteisiin. Tämä on erityisen tärkeää globaalissa maailmassa, jossa ohjelmistoja käytetään monilla eri markkinoilla ja kielillä.

Erityisesti .NET-ympäristössä on käytössä tehokkaita työkaluja, joiden avulla voidaan hallita lokalisointia ja kansainvälistämistä. Lokalisointi (localization) tarkoittaa kielen, kulttuuristen normien ja teknisten erityispiirteiden huomioimista ohjelmointia tehtäessä, kun taas kansainvälistäminen (internationalization) on suunnitteluprosessi, jossa ohjelmisto rakennetaan siten, että se tukee eri kieliä ja kulttuureja ilman suuria muutoksia koodiin.

Pohditaanpa esimerkiksi käytettävää tekstiä ohjelmissa. Oletetaan, että ohjelma kysyy käyttäjältä tietoja, kuten nimeä, syntymäaikaa ja palkkaa. Tällöin ohjelma voi esittää nämä kysymykset eri kielillä, ja lisäksi se voi mukauttaa vastaukset paikallisiin käytäntöihin, kuten päivämäärämuotoon ja valuuttaan. Esimerkiksi, kun käyttäjä syöttää syntymäaikansa, ohjelma voi kertoa hänen ikänsä minuuteissa, mutta tätäkin tietoa on muokattava kunkin alueen vaatimusten mukaiseksi.

Tässä vaiheessa otetaan esimerkki siitä, miten kansainvälistäminen toimii käytännössä. Oletetaan, että ohjelma tukee useita kieliä, kuten ranskaa (Ranska ja Kanada), puolaa ja persiaa. Tässä koodissa käyttäjä saa ohjelmasta kysymyksiä kunkin alueen kielellä. Kun ohjelma pyytää käyttäjältä esimerkiksi syntymäpäivää, kysymys voi olla ranskaksi "Entrez votre date de naissance", puolaksi "Wpisz swoją datę urodzenia" tai persiaksi "دینک دراو ار دوخ دلوت خیرات". Ohjelma voi myös näyttää, kuinka monta minuuttia käyttäjä on elänyt ja kuinka paljon hän ansaitsee paikallisessa valuutassa.

Tällainen muokkaus mahdollistaa sen, että ohjelma voi kommunikoida eri kielillä, mutta myös ottaa huomioon kulttuuriset ja tekniset erot. Esimerkiksi, kun kysytään syntymäpäivää, se voi käyttää päivämääräformaatteja, jotka ovat erilaisia eri maissa. Yhdysvalloissa käytetään kuukausi/päivä/vuosi-muotoa, kun taas Euroopassa käytetään päivä/kuukausi/vuosi-muotoa.

Yksi esimerkki ongelmasta, johon voidaan törmätä, on väärin nimetty resurssitiedosto, joka voi aiheuttaa virheilmoituksia ohjelman käytön aikana. Jos esimerkiksi käännöstiedosto, jossa kysytään käyttäjän nimeä, on nimetty väärin, ohjelma ei pysty löytämään tarvittavaa tekstiä ja palauttaa virheilmoituksen. Tässä vaiheessa ohjelma voi käyttää oletusresurssitiedostoa tai näyttää virheilmoituksen, joka kertoo käyttäjälle, ettei tarvittavaa tietoa löytynyt.

Erityisesti satelliittikokoelmat (satellite assemblies) ovat hyödyllisiä monikielisten ohjelmien kehittämisessä. Satelliittikokoelmat mahdollistavat käännösten tallentamisen erillisiin tiedostoihin, jotka voidaan ladata ohjelman ajon aikana, ilman että alkuperäistä ohjelmaa tarvitsee kääntää uudelleen. Tällöin ohjelma voi tukea useita kieliä ja kulttuureja ilman suuria koodimuutoksia.

Yksi tärkeä käytäntö kansainvälistämisessä on miettiä, tarvitseeko ohjelma tukea monia kieliä, ja suunnitella ohjelma sen mukaan. Tämä ei koske vain tekstejä ja kielikäännöksiä, vaan myös aikamuotoja, numeroiden esitystapaa ja lajittelukäytäntöjä. On tärkeää laatia lista kaikista tekstielementeistä, jotka tulevat olemaan osa ohjelman käyttöliittymää, ja miettiä, miten ne tulee kääntää ja lokalisoida eri kielille.

Lokalisoinnin ja kansainvälistämisen työkalut, kuten Microsoftin ResX Resource Manager, voivat auttaa luomaan monia käännöstiedostoja (.resx) ja yhdistämään ne satelliittikokoelmiin, jotka voidaan sitten jakaa käyttäjille ilman ohjelman uudelleenkäännöstä. Tällöin myös käännösten hallinta helpottuu, sillä voit helposti lisätä ja poistaa käännöksiä ohjelman eri versioissa.

Lopuksi on tärkeää muistaa, että vaikka ohjelma voisi tukea useita kieliä, kaikki alueelliset ja kulttuuriset tekijät on otettava huomioon. Esimerkiksi Kanadassa, jossa virallisia kieliä ovat sekä ranska että englanti, ohjelman tulee tukea molempia kieliä. Tällöin ohjelman käyttöliittymä voi vaihtaa kieliä riippuen siitä, mikä kieli on valittu, mutta myös sen tulee noudattaa paikallisia sääntöjä, kuten valuuttamuotoja ja päivämääräformaatteja.