🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
MDriven In Xamarin
This page was created by Alexandra on 2017-04-22. Last edited by Wikiadmin on 2026-07-29.

You can use MDriven Framework with a Xamarin Forms application to share a model-driven business layer across device projects while keeping platform-specific code, such as local storage, in the Android or iOS project.

This page describes the Xamarin Forms approach demonstrated with an Android client: create and activate an EcoSpace, use generated model classes and ViewModels, and persist a single user's data on the device. It is intended for developers building device clients that need offline data or later synchronization with a server system.

What this approach provides

MDriven Framework embeds MDriven Designer in Visual Studio and generates C# business-layer code from your model. In a Xamarin Forms client, you can place the model, EcoSpace, and shared application logic in a portable library, then keep device-specific operations in each platform project.

The demonstrated application replaces the Xamarin Forms template's manually maintained mock data with objects from an MDriven model. The result is:

  • Model classes generated from the MDriven model. For example, an Item class can inherit common properties such as ID, created date, updated date, text, and description from a base data-object class.
  • Generated ViewModels that Xamarin Forms views can bind to.
  • An active EcoSpace—the runtime object space that holds the model objects—for the application's data.
  • Local XML persistence implemented by the platform project, so objects remain available after an application restart.

Use this design when a user needs to work with data while disconnected. Examples include work in radio-shielded construction areas, tunnels, or other locations where connectivity cannot be assumed. For the wider choice between browser, Cordova, desktop, and offline-device clients, see Documentation:Getting MDriven benefits on devices.

Architecture

Keep shared model-driven code separate from device-specific code.

Area Responsibility Example
Portable/shared library Contains the model, EcoSpace, generated classes, and shared ViewModel logic. A generated Item class and the ViewModel that exposes a collection of items to a Xamarin Forms page.
Android project Starts the EcoSpace and implements Android-specific file access for persistence. In OnCreate, attach XML load/save handlers that read and write the file in Android external storage.
Other device projects Supply their own platform-specific startup and storage implementation. iOS must use its own storage approach; Android file-system code must not be reused as-is.

The platform projects should contain as little code as possible beyond platform concerns. Do not put the model or business rules in Android-specific code when those rules are shared by the application.

Build a model-driven Xamarin Forms client

The following sequence reflects the demonstrated Android setup.

  1. Create a Xamarin Forms project using the portable-library option.
  2. Add a portable class library for the MDriven model and shared code. Ensure that the target frameworks of projects that reference each other are compatible.
  3. Move or copy the EcoSpace and model files into the portable library. Remove the original model location when the portable library is the intended owner, so the solution has one model source.
  4. Add the MDriven runtime assemblies required by the portable library and device projects. In the demonstration, the EcoCore package was added through NuGet, including the runtime interfaces and LINQ extension support.
  5. Define the application data in the model. For example, create an Item class that inherits from a base data-object class and contains the text and description properties used by the Xamarin Forms template.
  6. Update the generated code. The model properties are then available as generated C# members, including inherited members.
  7. Replace the template's mock-data access with access to the active EcoSpace. For example, the ViewModel's item list should retrieve instances of the modeled Item class rather than create a separate mock-item type.
  8. In the Android startup code, create the EcoSpace, connect persistence callbacks, initialize the generated ViewModel definitions, activate the EcoSpace, and provide it to the application's data store.
  9. Bind Xamarin Forms pages to the generated ViewModels. Keep page bindings focused on the ViewModel; do not duplicate model rules in page code.
  10. Run the application, create an item, save it, restart the application, and verify that the item is loaded from local storage.

Example: start the EcoSpace on Android

The Android application initializes the EcoSpace before the ViewModels use it. The following example shows the pattern from the device walkthrough; replace the generated EcoSpace type with the type from your model.

private EcoProject1EcoSpace _es;

protected override void OnCreate(Bundle bundle)
{
  _es = new EcoProject1EcoSpace();
  _es.PMapperXml.OnLoadAsXML += Pm_OnLoadAsXML;
  _es.PMapperXml.OnSaveAsXML += Pm_OnSaveAsXML;

  ViewModelDefinitionsInApplication.Init(_es);

  _es.Active = true;
  BaseViewModel.DataStore.SetEcoSpace(_es);
}

Activation matters. Set _es.Active = true after the persistence handlers and ViewModel definitions have been connected. The active EcoSpace is the object space used when the application retrieves and updates modeled objects.

Example: persist XML through Android storage

The XML persistence mapper raises events for loading and saving. The mapper does not itself know the correct device file location, so Android code supplies that behavior.

private void Pm_OnSaveAsXML(object sender, Eco.Persistence.OnSaveAsXMLArgs e)
{
  var path = global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
  var filename = System.IO.Path.Combine(path.ToString(), e.FileName);
  e.XDocumentToSave.Save(filename);
  e.ContinueWithDefault = false;
}

private void Pm_OnLoadAsXML(object sender, Eco.Persistence.OnLoadAsXMLArgs e)
{
  var path = global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
  var filename = System.IO.Path.Combine(path.ToString(), e.FileName);
  if (System.IO.File.Exists(filename))
  {
    using (var fileStream = System.IO.File.OpenRead(filename))
    using (var streamReader = new System.IO.StreamReader(fileStream))
    {
      e.LoadedDataAsXml = streamReader.ReadToEnd();
      e.ContinueWithDefault = false;
    }
  }
}

The ContinueWithDefault = false setting tells the persistence operation that the application handled the read or write. This code is Android-specific because it uses Android external storage. Implement equivalent callbacks using the storage facilities of each target platform.

Model rules and ViewModels

Put business requirements in the MDriven model, including rules expressed in OCL where applicable, before writing device-specific C#. This lets you validate the modeled behavior independently of the phone UI and prevents the same rule from being reimplemented in multiple clients.

For example, if an item must have a description before it can be saved, define and verify that requirement in the model. The generated ViewModel and Xamarin Forms binding then work with the same modeled data rather than a separate client-side representation.

Generated ViewModels also make model usage easier to trace: the ViewModel declares what it uses, and cross-references can show where model elements are used. When requirements change—such as adding a property to Item—update the model and generated code, then adjust the affected binding rather than searching through unrelated mock-data code.

Local data and later synchronization

The XML approach shown here is appropriate for a single user's local device data. It stores the modeled objects on the device and reloads them when the app starts.

It does not by itself synchronize local changes with a central server. A later design can synchronize data with an MDriven Turnkey server through REST APIs when connectivity is available. Define conflict handling, the data scope to synchronize, and offline behavior as part of that design; do not assume that local XML persistence provides these features.

Extend the device client

A device client can combine local modeled data with platform capabilities. For example, a warehouse user can scan a barcode, identify an item, and update a modeled shelf or item object. Keep barcode scanning integration in the device application and keep the resulting business data and validation in the model. For the Android barcode example and sample location, see Documentation:Barcode - on Android - with Xamarin and MDriven.

Troubleshooting

Symptom Check
Portable and device projects cannot reference each other. Check that their target frameworks are compatible. The walkthrough required matching framework compatibility between the original project and the portable library.
The app still displays template mock data. Verify that the ViewModel data store has received the active EcoSpace and that the ViewModel retrieves instances of the generated model class, not the template's mock class.
New data disappears after restart. Verify that the XML save callback runs, that it writes the expected file, and that the load callback reads the same path and sets LoadedDataAsXml.
Android persistence code does not work on another platform. This is expected. File locations and storage APIs are platform-specific; implement the load/save callbacks for that platform.

Scope and version note

This guidance documents a Xamarin Forms and Android example created with Visual Studio 2017 and MDriven Framework build 9205 or later. Confirm supported current toolchains, package versions, device permissions, and storage requirements before starting a new application.

See also