{"id":20504484,"url":"https://github.com/tiknil/xamarin-style-guide","last_synced_at":"2026-02-15T20:03:10.573Z","repository":{"id":113422292,"uuid":"92072487","full_name":"tiknil/xamarin-style-guide","owner":"tiknil","description":"Tiknil's style guide \u0026 coding conventions for Xamarin Forms projects http://www.tiknil.com","archived":false,"fork":false,"pushed_at":"2021-02-10T15:57:24.000Z","size":9,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-05T20:55:27.761Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tiknil.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-22T16:01:10.000Z","updated_at":"2021-02-10T15:57:27.000Z","dependencies_parsed_at":"2023-04-24T18:44:40.089Z","dependency_job_id":null,"html_url":"https://github.com/tiknil/xamarin-style-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tiknil/xamarin-style-guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiknil%2Fxamarin-style-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiknil%2Fxamarin-style-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiknil%2Fxamarin-style-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiknil%2Fxamarin-style-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tiknil","download_url":"https://codeload.github.com/tiknil/xamarin-style-guide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiknil%2Fxamarin-style-guide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001047,"owners_count":26082991,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T19:38:22.795Z","updated_at":"2025-10-09T08:42:28.166Z","avatar_url":"https://github.com/tiknil.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Xamarin-style-guide\nGuida di riferimento per i progetti Xamarin Forms di Tiknil.\u003cbr\u003e\nOgni consiglio o critica è ben accetta se contribuisce a migliorare la qualità del codice 👍\n\n## SOMMARIO\n1. [Pattern di sviluppo](#pattern-di-sviluppo)\n\t* [Inversion of Control e Dependency Injection](#inversion-of-control-e-dependency-injection)\n\t* [MVVM](#mvvm-model---view---viewmodel)\n2. [XAML o C#?](#xaml-o-c)\n3. [Naming conventions](#naming-conventions)\n4. [Struttura e organizzazione della soluzione](#struttura-e-organizzazione-della-soluzione)\n\t* [Cartelle e contenuti](#cartelle-e-contenuti)\n\t* [Classi utili secondo Tiknil](#classi-utili-secondo-tiknil)\n\t* [Gestione assets](#gestione-assets)\n5. [Tool e pacchetti NuGet usati e testati](#tool-e-pacchetti-nuget-usati-e-testati)\n\n### Pattern di sviluppo\nIn questa sezione analizziamo un paio di pattern che abbiamo deciso di utilizzare nelle nostre applicazioni Xamarin Forms con l'obiettivo di migliorare **riusabilità** e **manutenibilità** del codice con conseguente agevolazione al lavoro in team.\n\n#### Inversion of Control e Dependency Injection\nL'*Inversion of Control* (**IoC**) è un *software design pattern* secondo il quale ogni componente dell'applicazione deve ricevere il **controllo** da un componente appartenente ad una **libreria riusabile**.\u003cbr\u003e\nL'obiettivo è quello di rendere ogni componente il più indipendente possibile dagli altri in modo che ognuno sia modificabile singolarmente con conseguente maggior riusabilità e manutenibilità.\n\nLa *Dependency Injection* (**DI**) è una forma di *IoC* dove l'implementazione del pattern avviene stabilendo le dipendenze tra un componente e l'altro tramite delle *interfacce* (chiamate **interface contracts**).\u003cbr\u003e\nA tali interfacce viene associata un'implementazione in fase di istanziazione del componente (nel *costruttore*) oppure in un secondo momento tramite *setter*.\u003cbr\u003e\nIn ogni caso è generalmente presente un oggetto **container** che si occupa di creare le istanze di ogni *interfaccia*; la configurazione di tale *container* può così influenzare le dipendenze tra i vari componenti.\u003cbr\u003e\nL'utilizzo della *DI* è molto utile per la realizzazione di test automatici, infatti modificando il *container* è possibile *mockare* le dipendenze che non si desidera testare.\n\nReferences:\n\n* [Semplice video che chiarisce il concetto di DI](https://www.youtube.com/watch?v=IKD2-MAkXyQ)\n* [Esempio di applicazione della DI in Xamarin](https://xamarinhelp.com/xamarin-forms-dependency-injection/)\n* [Unity: tool per DI by Microsoft in Xamarin](https://www.youtube.com/watch?v=B-L6OE3AKXQ)\n\n#### MVVM (Model - View - ViewModel)\nL'*MVVM* è un *pattern architetturale* che facilita la separazione tra interfaccia grafica (**GUI**) e la **business logic** tramite l'utilizzo di **bindings** tra *view* e *viewmodel*.\u003cbr\u003e\n\n* **Model:** implementazione del *domain model* che include modelli di dati, logiche di business e validazione.\n* **View:** struttura, layout e aspetto di ciò che l'utente vede su schermo.\n* **ViewModel:** il *viewmodel* è un'astrazione di ciò che visualizza la *view* relativa ed espone *properties* e *commands* che vengono collegati alla *view* tramite **binding**.\n![MVVM Pattern](https://upload.wikimedia.org/wikipedia/commons/8/87/MVVMPattern.png)\n\n[Qui](https://www.youtube.com/watch?v=sbZRtrKj3Ds) c'è un esempio di applicazione del pattern *MVVM* utilizzando solo l'sdk di Xamarin.Forms. Il ragazzo non è bravissimo a presentare, ma l'esempio è utile per capire il concetto.\n\n#### Considerazioni su frameworks MVVM\nIn seguito ad un'analisi dei vari framework MVVM disponibili per Xamarin abbiamo individuato **FreshMVVM** come il più adatto al nostro tipo di utilizzo.\u003cbr\u003e\nDi seguito riportiamo una lista di pro e contro per ogni framework aggiornata ad Aprile 2017:\n\n---\n#### [FreshMVVM](https://github.com/rid00z/FreshMvvm)\n**PRO**\n\n* Lightweight: leggero e poco invasivo. Si è più liberi di applicarlo o meno dove si desidera\n* Navigazione VM-VM buona\n* Specifico per Xamarin.Forms\n* [Video esplicativi esaurienti](https://github.com/rid00z/FreshMvvm#related-videosquick-start-guides)\n* Pattern testabile con UnitTest\n\n**CONTRO**\n\n* Per ora è necessario adattarsi alle sue naming conventions\n\t* *View =\u003e Page*\n\t* *ViewModel =\u003e PageModel*\n\n---\n#### [Prism](https://github.com/PrismLibrary/Prism)\n**PRO**\n\n* Interessante il sistema di navigazione VM-VM tramite url/path\n* Possibilità di scegliere il proprio framework di Dependency Injection\n\n**CONTRO**\n\n* Codice un po’ troppo “invadente”; è necessario che molti elementi siano sottoclassi di quelle fornite dal framework\n* I template forniti sulla creazione dei file si basano tutti su XAML\n* Documentazione non troppo esauriente\n\n**Materiale**\u003cbr\u003e\n[Video](https://www.youtube.com/watch?v=DYRLcqG2BAY) di presentazione del framework tenuto dall’ideatore. Ne dimostra le potenzialità.\n\n---\n#### [MVVMCross](https://www.mvvmcross.com/) (non testato)\n**Pro**\n\n* Sembrerebbe ben documentato\n* Offre molti plugin con funzionalità varie accessorie\n\n**Contro**\n\n* Xamarin.Forms non sembra molto supportato\n\n---\n#### [MVVMLight](http://www.mvvmlight.net/) (non testato)\n**Pro**\n\n* Sembrerebbe parecchio utilizzato per sviluppo winzozz\n\n**Contro**\n\n* Documentazione assente\n\n---\n\n### XAML o C#?\nLe *views* in Xamarin.Forms si chiamano `Page` e rappresentano una singola schermata visualizzata dall'utente; si possono realizzare in due modi:\n\n1. C#: classe erede di `ContentPage`.\n2. XAML: file XML di concetto molto simile ai `layout` Android che viene trasformato in una classe C# (chiamata **code behind**) build time.\n\nIdealmente sarebbe meglio utilizzare XAML perché aiuta a mantenere un maggior decoupling tra *view* e *viewmodel* e perché l'IDE può fornire un'anteprima della visualizzazione, ma per ora preferiamo utilizzare solo C# per i seguenti motivi:\n\n1. Attualmente *Xamarin Studio* e *Visual Studio* su Mac hanno un sistema di completamento automatico (**IntelliSense**) carente soprattuto nei *binding*.\n2. XAML non è un linguaggio di programmazione, quindi impedisce di far ereditare una *page* da un'altra complicando il molto frequente utilizzo di una `BasePage` per l'implementazione di un'iterfaccia comune a tutta l'applicazione. Es: navigation bar customizzata.\n\n### Naming conventions\n* I nomi delle classi e dei campi `public` vanno espressi in [UpperCamelCase](https://en.wikipedia.org/wiki/Camel_case). Es: `AwesomeClass`, `AwesomePublicProperty`.\n* I campi `private` o `protected` iniziano con l'underscore `_` e vanno espressi in [lowerCamelCase](https://en.wikipedia.org/wiki/Camel_case). Es: `_awesomePrivateProperty`.\n* Le interfacce iniziano con la `I` maiuscola. Es: `IAwesomeInterface`.\n* Naming conventions ereditate da **FreshMVVM**:\n\t* Le *views* del pattern *MVVM* hanno suffisso `Page`. Es: `AwesomePage`.\n\t* I *viewmodels* del pattern *MVVM* hanno suffisso `PageModels`. Es: `AwesomePageModel`.\n\n### Struttura e organizzazione della soluzione\n\n#### Cartelle e contenuti\n* *Helpers*: qualsiasi classe o interfaccia che sia generalmente utile in ogni punto del progetto senza essere strettamente legata a nulla. Namespace: `NomeProgetto.Helpers`. Es: `IHudProvider`.\n* *Libraries*: librerie varie sviluppate ad-hoc e non integrate tramite NuGet. Namespace customizzati per liberia. Es: `Verscker`.\n* *Models*: *modelli* e business logic del pattern MVVM. Namespace: `NomeProgetto.Models`.\n* *PageModels*: *viewmodels* del pattern MVVM. Namespace: `NomeProgetto.PageModels`.\n* *Pages*: *views* del pattern MVVM basate sulle `Page` di Xamarin.Forms. Namespace: `NomeProgetto.Pages`.\u003cbr\u003eQuesta cartella può contenere le seguenti sottocartelle che mantengono lo stesso namespace:\n\t* *Cells*: classi eredi di `ViewCell` di Xamarin.Forms.\n* *Properties*: file di info degli *assembly* generato automaticamente da Xamarin.\n* *Renderers*: classi con customizzazione grafica per piattaforma tramite i *renderers* di Xamarin.Forms.\n* *Resources*: nella PCL eventuali assets di tipo *Embedded*, nelle piattaforme gli assets di tipo *Local*.\n* *Services*: interfacce e implementazioni dei servizi generalmente passati ai *viewmodels* nel costruttore tramite *DI*.\u003cbr\u003eSono generalmente sempre presenti le seguenti interfacce:\n\t* *IDataServices*: definisce i servizi di recupero dati dai modelli. Sarà compito dell'implementazione definire da dove recuperare i dati; ad esempio da *memoria* (singleton), *database* o altro.\n\t* *IRestServices*: definisce i servizi di recupero dati da webservices.\n\t* *ICacheServices*: definisce i servizi di storicizzazione di dati in cache. L'implementazione classica è il salvataggio di informazioni nella cache d'installazione dell'applicazione in una classe `Settings`.\n\n#### Classi utili secondo Tiknil\n* *UIConstants*: nella cartella *Pages* creiamo questa classe che conterrà proprietà statiche rappresentanti:\n\t* Colori\n\t* Misure (padding, ecc)\n\t* Stili (`Style` di Xamarin.Forms)\n* *Converters*: nella cartella *Pages* creiamo questo file che conterrà le varie classi che implementano `IValueConverter` di Xamarin.Forms utilizzate nelle varie *page* del progetto.\n* *BaseModel (opzionale)*: classe di base dei *models* con implementazioni comuni a tutti i *models*.\n* *BasePageModel*: classe di base dei *pagemodels* erede di `FreshBasePageModel` con implementazioni comuni a tutti i *pagemodels*. Es: costruttore con `IDataServices` per il recupero dei dati dai model.\n* *BasePage*: classe di base delle *pages* erede di `FreshBaseContentPage` con implementazioni comuni a tutte le *pages*. Es: navigation bar customizzata presente in ogni schermata con relativi metodi di controllo.\n\n#### Gestione assets\nLe risorse, in Xamarin.Form, si possono gestire in maniera [Local](https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/#Local_Images) o [Embedded](https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/#Embedded_Images).\u003cbr\u003e\nGli assets *Local* li posizioniamo nelle cartelle *Resources* dei progetti specifici di piattaforma, mentre le gli assets *Embedded* li posizioniamo nella cartella *Resources* della PCL.\n\nLa quasi totalità degli asset saranno ti tipo *Local* per riuscire a sfruttare i sistemi proprietari delle piattaforme di gestione delle risoluzioni.\n\nIn **iOS** inseriamo direttamente nella cartella *Resources* tutti i png con suffissi delle risoluzioni (`@2x`, `@3x`) in modo che da PCL possiamo scrivere semplicemente il nome del file per referenziare la correta risorsa. Es: mettiamo in *Resources* `awesome_image.png`, `awesome_image@2x.png`, `awesome_image@3x.png` e nella PCL possiamo usare semplicemente `awesome_image.png`; si occupa iOS di selezionare la corretta risoluzione per il device.\u003cbr\u003e\nNella cartella *Resources* ci sono anche:\n\n* `Assets.xcassets`: in cui gestiamo l'icona dell'app\n* `LaunchScreen.storyboard`: in cui possiamo customizzare la launch screen\n\nIn **Android** tutti gli assets li inseriamno nelle sottocartelle `drawable` della cartella *Resources*.\n\n### Tool e pacchetti NuGet usati e testati\n[Qui](https://github.com/MarcBruins/awesome-xamarin) è disponibile una lista generale di pacchetti utili.\n\n#### Pacchetti NuGet testati e utilizzati da Tiknil\n\n* Newtonsoft.Json =\u003e parsing json-oggetti\n* Microsoft.Net.Http =\u003e client per request HTTP\n* Plugin.Permissions =\u003e gestione delle richieste dei permessi\n\t* [https://blog.xamarin.com/new-ios-10-privacy-permission-settings/](https://blog.xamarin.com/new-ios-10-privacy-permission-settings/)\n* Xam.Plugins.Settings =\u003e caching di informazioni in stile StandardUserDefaults perché quello integrato di Xamarin non funziona\n* Xam.Plugin.Media =\u003e caricamento immagini da rullino o scatto da fotocamera\n* Xamarin.FFImageLoading =\u003e caricamento delle immagini dal web\n* Xam.Plugin.Geolocator =\u003e geolocalizzazione\n* Xamarin.Forms.Maps =\u003e ufficiale xamarin per la visualizzazione di mappe\n* Xam.Plugin.PushNotification =\u003e per la gestione delle notifiche push\n* Xam.Plugin.DeviceInfo =\u003e info sul dispositivo\n* PropertyChanged.Fody =\u003e implementazione automatica dell’INotifyPropertyChanged\u003cbr\u003e**NB:** l'ultima versione testata (*1.53.0*) da un errore in compilazione quindi per ora questo pacchetto non è stato utilizzato\n* HockeySDK.Xamarin =\u003e crash reporting e beta distribution tramite il servizio *HockeyApp*\n* ZXing.Net.Mobile.Forms =\u003e Scan di barcode e/o QR code\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiknil%2Fxamarin-style-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftiknil%2Fxamarin-style-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiknil%2Fxamarin-style-guide/lists"}