As a proof of concept I wanted to give a try of using Uno Platform and XPO together. Uno has been gaining popularity and I have to say that after this I will have a tough decision on the framework selection for my next mobile project. I love Xamarin but the benefits that Uno brings to the table are hard to pass.
From their own website:
- Uno-built native apps can be compiled to WASM with no additional development efforts!
- Ramp up time is minimal and you can take advantage of all that the Visual Studio ecosystem has to offer for testing, deploying, project management, and more.
What that means to us?
First, A web front end thanks to web assembly (I honestly don’t know why Xamarin has not invested in this route yet. Besides Ooui that I believe it is awesome but not even close to production, there is nothing else out there)
Update: UNO has WebAssembly Renderers for Xamarin Forms.
And second, a UWP first approach where all the VS tooling just work. Including Designers, Hot reload, Brushes and more.
If you are curious about UNO and want to learn more I suggest their getting started so you can get a feel of the framework.
Now, back to XPO.
The sample is simple. Just one class Item. A SQLite Database and a ListView.
Let’s create the connection, update the schema and persist some objects so we can display something.
public App() { ConfigureFilters(Uno.Extensions.LogExtensionPoint.AmbientLoggerFactory); this.InitializeComponent(); this.Suspending += OnSuspending; string connectionString = "XpoProvider = SQLite; Data Source = test.db"; var DataStore = XpoDefault.GetConnectionProvider(connectionString, DevExpress.Xpo.DB.AutoCreateOption.DatabaseAndSchema); var dictionary = new ReflectionDictionary(); dictionary.GetDataStoreSchema(typeof(Item).Assembly); SimpleDataLayer UpdateSchemaDal = new SimpleDataLayer(dictionary, DataStore); UnitOfWork UpdateSchemaUoW = new UnitOfWork(UpdateSchemaDal); UpdateSchemaUoW.UpdateSchema(); UpdateSchemaUoW.CreateObjectTypeRecords(); XpoDefault.DataLayer = new SimpleDataLayer(dictionary, DataStore); var uoW = new UnitOfWork(XpoDefault.DataLayer); if((int)uoW.Evaluate(typeof(Item), CriteriaOperator.Parse("Count()"), CriteriaOperator.Parse("Active = true")) == 0) { Item item1 = new Item(uoW); item1.Name = "Item One"; item1.Description = "My first Xpo Object in Xamarin"; item1.Active = true; Item item2 = new Item(uoW); item2.Name = "Item Two"; item2.Description = "My second Xpo Object in Xamarin"; item2.Active = true; Item item3 = new Item(uoW); item3.Name = "Item Three"; item3.Description = "My third Xpo Object in Xamarin"; item3.Active = true; if (uoW.InTransaction) uoW.CommitChanges(); } }
After this is as simple as:
<Page x:Class="UnoXpoDemo.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:UnoXpoDemo" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid> <ListView x:Name="itemListView" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Orange"> <ListView.ItemTemplate> <DataTemplate> <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0"> <TextBlock Text ="Name:"/> <TextBox Text="{Binding Name}" TextWrapping="NoWrap"/> <TextBlock Text ="Description:"/> <TextBox Text="{Binding Description}" TextWrapping="NoWrap"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid> </Page>
public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); XPCollection<Item> itemCollection = new XPCollection<Item>(); ObservableCollection<Item> Data = new ObservableCollection<Item>(itemCollection); this.itemListView.ItemsSource = Data; } }
Run the app and:
Really neat, now I can use XPO as we are used to and have some fun.
While doing this POC, I had to add the line below in the first PropertyGroup element in UWP csproj due to:
Error PRI175 : 0x80073b0f – Processing Resources failed with error : Duplicate Entry. 1>GENERATEPROJECTPRIFILE : error PRI278: 0xdef00531 – ” or one if its parents is defined as both resource and scope, which is not allowed.
You can check more known issues here.
<AppxGeneratePrisForPortableLibrariesEnabled>false</AppxGeneratePrisForPortableLibrariesEnabled>
My friend Joche Ojeda put a ticket to DevExpress and this was their answer:
Couple more observations:
This was an extremely simple exercise and of course dealing with mobile apps I will never connect directly to the DB (that is why I am using Sqlite here, but proving that this work means that now we can use the RestDataStore and trough ASP.Net Core Web Api use XPO in UNO and Xamarin exactly as we do in XAF. I don’t know about you but I can not be more excited with this.
Until next time, UNO out!
Some links to look at:
https://github.com/jjcolumb/UnoXpoDemo
Replacing WCF with AspNetCore Rest API as transport layer for XPO
Getting Started with Platform Uno
Uno Platform and WebAssembly with CSLA v5
Update: I just got the news Joche is using the RestDataStore successfully as we predicted it. That means: UWP, iOS, Android – duh but most important Web Assembly. I will wait for him to share his results and then I will add that link right here.
Now, for real, UNO Out!
Hello,
Have you done yet a concrete project with Uno ?
I would to have some realworld feedbacks.
BR
ISA