{"id":24358486,"url":"https://github.com/thomasgalliker/crossplatformlibrary","last_synced_at":"2025-04-10T05:41:03.465Z","repository":{"id":1636965,"uuid":"42665244","full_name":"thomasgalliker/CrossPlatformLibrary","owner":"thomasgalliker","description":"An extensible cross-platform toolkit which provides a basic set of functionality used in most mobile apps.","archived":false,"fork":false,"pushed_at":"2024-03-16T10:23:44.000Z","size":17407,"stargazers_count":9,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-04-06T22:41:10.563Z","etag":null,"topics":["boilerplate","bootstrapping","cross-platform","library","user-controls","xamarin"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasgalliker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"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},"funding":{"patreon":"user?u=21232884"}},"created_at":"2015-09-17T15:42:17.000Z","updated_at":"2024-03-19T13:07:13.000Z","dependencies_parsed_at":"2024-06-18T20:11:42.762Z","dependency_job_id":null,"html_url":"https://github.com/thomasgalliker/CrossPlatformLibrary","commit_stats":{"total_commits":606,"total_committers":3,"mean_commits":202.0,"dds":0.008250825082508295,"last_synced_commit":"c88d848bdd2f30a894b00a46a28f51ab952f8920"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgalliker%2FCrossPlatformLibrary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgalliker%2FCrossPlatformLibrary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgalliker%2FCrossPlatformLibrary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasgalliker%2FCrossPlatformLibrary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasgalliker","download_url":"https://codeload.github.com/thomasgalliker/CrossPlatformLibrary/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248166184,"owners_count":21058475,"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","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":["boilerplate","bootstrapping","cross-platform","library","user-controls","xamarin"],"created_at":"2025-01-18T20:11:28.802Z","updated_at":"2025-04-10T05:41:03.440Z","avatar_url":"https://github.com/thomasgalliker.png","language":"C#","funding_links":["https://patreon.com/user?u=21232884"],"categories":[],"sub_categories":[],"readme":"# CrossPlatformLibrary\n[![Version](https://img.shields.io/nuget/v/CrossPlatformLibrary.svg)](https://www.nuget.org/packages/CrossPlatformLibrary)  [![Downloads](https://img.shields.io/nuget/dt/CrossPlatformLibrary.svg)](https://www.nuget.org/packages/CrossPlatformLibrary)\n\n\u003cimg src=\"https://raw.githubusercontent.com/thomasgalliker/CrossPlatformLibrary/master/Images/cpl_short.png\" alt=\"CrossPlatformLibrary\" align=\"right\" height=\"100\"\u003e\nCrossPlatformLibrary is an extensible toolkit which addresses cross-cutting concern. It is a lightweight library which provides a collection of functionality used in most mobile and desktop applications such as bootstrapping, exception handling, tracing and UI dispatching.\n\n### Supported Platforms\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003ctd\u003e.Net 4.5 / WPF\u003c/td\u003e\n    \u003ctd\u003e.Net Standard 2.0\u003c/td\u003e\n    \u003ctd\u003eXamarin.Android\u003c/td\u003e\n    \u003ctd\u003eXamarin.iOS\u003c/td\u003e\n    \u003ctd\u003eUWP\u003c/td\u003e\n\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eCrossPlatformLibrary\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eCrossPlatformLibrary.Forms\u003c/td\u003e\n    \u003ctd\u003eno\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n    \u003ctd\u003eyes\u003c/td\u003e\n    \u003ctd\u003enot yet\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Download and Install CrossPlatformLibrary\n\nThis library is available on [NuGet](https://www.nuget.org/packages/CrossPlatformLibrary). Use the following command to install CrossPlatformLibrary using NuGet package manager console:\n\n```PM\u003e Install-Package CrossPlatformLibrary```\n\nThe Xamarin.Forms specific library can be installed using following command:\n\n```PM\u003e Install-Package CrossPlatformLibrary.Forms```\n\n### Usage\n\n#### User Controls\nThe library contains a rich set of customized user controls which extend basic implementations of existing controls. Following screenshots of the SampleApp demonstrate the usege of some of the delivered controls. The coloring is pretty random and mainly used for debugging/development purposes. Since every control uses dynamic styles, you're free to override the default styles.\n\u003cp float=\"left\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/thomasgalliker/CrossPlatformLibrary/develop/Images/Screenshot_SampleApp_Android.jpg\" alt=\"SampleApp Android\" height=\"500\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/thomasgalliker/CrossPlatformLibrary/develop/Images/Screenshot_SampleApp_iOS.png\" alt=\"SampleApp iOS\" height=\"500\"\u003e\n\u003c/p\u003e\n\n##### Getting Started\nIn order to use the user controls of CrossPlatformLibrary, the styles used in these controls need to be initialized properly. For this reason, add following line of code just after the line `this.InitializeComponent();` in `App.xaml.cs`:\n\n`\nCrossPlatformLibrary.Forms.CrossPlatformLibrary.Init(this, \"SampleApp.Theme\");\n`\n\n\n```TODO: to be documented```\n\n##### Known Problems\n- `System.Collections.Generic.KeyNotFoundException: The resource 'Theme.Color.TextColor' is not present in the dictionary.` This error eventually appears if user controls of CrossPlatformLibrary are used without calling the `CrossPlatformLibrary.Forms.Init(..)` method.\n\n#### Input Validation\nThe base viewmodel ```BaseViewModel``` implements a pretty sophisiticated and praxisproven user input validation system which allows to run client- and server-based property validation side-by-side.\nThere are a few steps to follow to get input validation to work:\n\n- Inherit your viewmodels from ```BaseViewModel``` or implement a similar logic which exposes a ```BaseViewModel.Validation``` property.\n- Override the protected method ```SetupValidation```. This enables your viewmodel to use input validation. The most simple setup just returns an empty  ```ViewModelValidation```.\n- Setup validation rules inside ```SetupValidation```. There are basically two different approaches: Either you validate viewmodel properties locally (validation logic provided by the viewmodel) or you call a backend service which validates a given object (DTO) against some central validation logic.\n- Configure the according view to react on validation errors. This is done in XAML by binding a dependency property to the string list of validation errors for a certain property. The following example binds to validation errors for property 'UserName': ```ValidationErrors=\"{Binding Validation.Errors[UserName]}\"```\n- In order to run the validation, just call ```Validation.IsValidAsync()```. Depending on the result (true/false) we proceed with further actions (e.g. saving the object).\n```\n  var isValid = await this.Validation.IsValidAsync();\n  if (isValid)\n  {\n      // TODO Save...\n  }\n```\n\nFollowing snippet is an extract of a unit test. It demonstrates some setup variations.\n```\nprotected override ViewModelValidation SetupValidation()\n{\n    var viewModelValidation = new ViewModelValidation();\n\n    // Validation function with parameter-less custom error message\n    viewModelValidation.AddValidationFor(nameof(this.UserName))\n        .When(() =\u003e string.IsNullOrEmpty(this.UserName))\n        .Show(() =\u003e \"Username must not be empty\");\n\n    // Validation rule with parameter and custom error message\n    viewModelValidation.AddValidationFor(nameof(this.Email))\n        .When(new IsNotNullOrEmptyRule())\n        .Show(p =\u003e $\"Email address '{p}' must not be empty.\");\n\n    // Validation delegated to async service\n    viewModelValidation.AddDelegateValidation(nameof(this.UserName), nameof(this.Email))\n        .Validate(async () =\u003e (await this.validationService.ValidatePersonAsync(this.CreatePerson())).Errors);\n\n    return viewModelValidation;\n}\n```\n\n#### Bootstrapping\n\nThe bootstrapping mechanism is used to startup and shutdown an application in a controlled way. The boostrapper is called at the entry point of an application and it cares about the basic initialisation tasks. The entry point of the application can differ from application type to application type.\n\n\nCrossPlatformLibrary provides you with a base implementation of a bootstrapper. You may want to inherit the Bootstrapper class in order to influence the startup procedure and/or bootstrap parts of your own application. Following things can be done with a custom Bootstrapper:\n\n* Register project-dependant dependencies in the IoC container\n\n* Define your own IExceptionHandler to be used for unhandled exceptions\n\n* Handle exceptions that happen during Bootstrapping (BootstrappingException)\n\n```TODO: to be documented```\n\n#### Exception Handling\n\nUnhandled exceptions may occur in every application. Better we are prepared for such exceptions. IExceptionHandler instance is used to handle any System.Exception that is not handled by the application.\n\n#### Tracing\n\nThe tracing functionality provided by CrossPlatformLibrary can be used to write application debug traces. The purpose of trace messages is to assist developers and 3rd level support locating and fixing bugs or other program flow related problems.\n\n\u003cdocument abstraction, design desicion\u003e\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eTracer Name\u003c/td\u003e\n    \u003ctd\u003eDescription\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eEmptyTracer\u003c/td\u003e\n    \u003ctd\u003eEmptyTracer doesn’t trace anything. Each call to the Write method will not execute anything.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eDebugTracer\u003c/td\u003e\n    \u003ctd\u003eDebugTracer uses System.Diagnostics.Debug.WriteLine to write traces.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eActionTracer\u003c/td\u003e\n    \u003ctd\u003eActionTracer allows you to define an Action/Delegate to which traces are written to.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eYour own ITracer implementation\u003c/td\u003e\n    \u003ctd\u003eWrite your own tracer by implementing ITracer or abstract TracerBase.\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nYou can implement your own tracer by either implementing the ITracer and ITracerFactory interface on you own or extend the provided base implementation of the TracerBase and TracerFactoryBase.\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eTrace Category\u003c/td\u003e\n    \u003ctd\u003eDescription\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eDebug\u003c/td\u003e\n    \u003ctd\u003eInformation traced for debugging purposes. Usually only active in test or pre-production releases.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eInformation\u003c/td\u003e\n    \u003ctd\u003eImportant trace information which is usually also traced by production software.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eWarning\u003c/td\u003e\n    \u003ctd\u003eSome warnings which are not critical but need care.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eError\u003c/td\u003e\n    \u003ctd\u003eTypically handled exceptions which have to be traced in order to be analyzed and avoided.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eFatal\u003c/td\u003e\n    \u003ctd\u003eSoftware crashes, unhandled exceptions.\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\n#### Modularity\n\nCrossPlatformLibrary was designed in a way which promotes modular design. Modules are loosely coupled and self-contained units which serve a concrete purpose. This approach supports the separation of concerns in your application. You can easily test modules in isolation and integrate them later into your application(s) without having them too tighly coupled. \n\n```TODO: to be documented```\n\n#### UI Dispatching\n\n```TODO: to be documented```\n\n#### Dependency Management\n\nDependency injection containers are used to manage dependencies between components. This typically involes registration and instanciation and resolution of dependencies. CrossPlatformLibrary uses its own implementation of a dependency injection container, CrossPlatformLibrary.Ioc.SimpleIoc.\n\n```TODO: to be documented```\n\n### Contribution\n\nWant to contribute to this project? Feel free to start a discussion in the issues area to see if your idea could fit in.\n\n### License\n\nCrossPlatformLibrary is Copyright \u0026copy; 2019 [Thomas Galliker](https://ch.linkedin.com/in/thomasgalliker). Free for non-commercial use. For commercial use please contact the author.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasgalliker%2Fcrossplatformlibrary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasgalliker%2Fcrossplatformlibrary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasgalliker%2Fcrossplatformlibrary/lists"}