[C#][Uno Platform] Create desktop applications on Ubuntu 2
Masui Masanori
Posted on January 2, 2022
Intro
- [C#][Uno Platform] Create desktop applications on Ubuntu 1
- [.NET 6][Uno Platform][Ubuntu 21.10] Using Leap Motion
This time, I will try installing NuGet packages, using DI, firing life-cycle events.
Environments
- Ubuntu ver.21.10
- .NET ver.6.0.101
- Uno Platform ver.4.0.11
Installing NuGet packages
To log, using DI, etc., I want to install NuGet packages.
When I install packages by NuGet Package Manager, I have to select the target project.
To use the packages in all projects, I have to install into "UnoSolutionTemplate.net6.csproj".
If the package is only for specific platform, I have to add in specific projects.
Life-cycle events
Sometimes, I want to execute something on loading the page, closing the page, and so on.
Shared project
In "UnoSample.Shared", I can use "Loaded" event in MainPage.xaml.cs to execute on the page loaded.
MainPage.xaml.cs
using Windows.UI.Xaml.Controls;
using UnoSample.ViewModels;
namespace UnoSample
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.Loaded += (sender, e) => Console.WriteLine("Loaddeded");
this.InitializeComponent();
this.DataContext = new MainPageViewModel();
}
}
}
How about closing applications event?
I can't find any events what are called on closing.
So I think I shall use closing events in every specific platform projects.
For example, WPF can use "OnClosing" and "OnClosed" methods.
Executing on closing
When I open MainPage, these classes are instantiated in sequence.
In "UnoSample.Skia.Gtk" project, there is only "Main" method.
So I can execute closing operations after "host.Run()".
Program.cs
using GLib;
using Uno.UI.Runtime.Skia;
using UnoSample.Skia.Gtk.MotionControllers;
namespace UnoSample.Skia.Gtk
{
class Program
{
static void Main(string[] args)
{
// I also can use "using statement"
using(var motionController = new MotionController())
{
ExceptionManager.UnhandledException += delegate (UnhandledExceptionArgs expArgs)
{
expArgs.ExitApplication = true;
};
var host = new GtkHost(() => new App(), args);
host.Run();
// execute closing operations.
}
}
}
}
Call methods in UnoSample.Shared classes
How shall I call methods in UnoSample.Shared classes?
I can access App.xaml.cs like below.
App.xaml.cs
...
namespace UnoSample
{
public sealed partial class App : Application
{
private Window _window;
public void Greet(string message)
{
Console.WriteLine($"SharedApp {message}");
}
...
Program.cs
...
class Program
{
static void Main(string[] args)
{
using(var motionController = new MotionController())
{
...
var host = new GtkHost(() => new App(), args);
host.Run();
// Because I can't get instances by "App.Current" before executing "host.Run()",
// I can only execute closing operations from Program.cs.
((App)App.Current).Greet("Call from Gtk");
}
}
}
}
DI (Dependency Injection)
Because I want to avoid the classes are coupled tightly, I try using DI framework.
In this time, I tried using "Microsoft.Extensions.DependencyInjection(ver.6.0.0)"
Because I couldn't find the way to inject View and their code behinds, I put IServiceProvider into App.xaml.cs of the shared project and get injected instances from it.
Program.cs
using GLib;
using Microsoft.Extensions.DependencyInjection;
using Uno.UI.Runtime.Skia;
using UnoSample.ViewModels;
namespace UnoSample.Skia.Gtk
{
class Program
{
static void Main(string[] args)
{
var servicesProvider = BuildDi(args);
using (servicesProvider as IDisposable)
{
...
var host = new GtkHost(() => new App(servicesProvider), args);
host.Run();
}
}
private static IServiceProvider BuildDi(string[] args)
{
var services = new ServiceCollection();
services.AddScoped<MainPageViewModel>();
return services.BuildServiceProvider();
}
}
}
App.xaml.cs
...
namespace UnoSample
{
public sealed partial class App : Application
{
private Window? _window;
public IServiceProvider ServiceProvider { get; }
public App(IServiceProvider serviceProvider)
{
this.ServiceProvider = serviceProvider;
InitializeLogging();
this.InitializeComponent();
...
MainPage.xaml.cs
using Windows.UI.Xaml.Controls;
using UnoSample.ViewModels;
namespace UnoSample
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.DataContext = ((App)App.Current).ServiceProvider.GetService(typeof(MainPageViewModel));
}
}
}
I'm not sure if this is the best method.
Maybe it's better to use another DI framework。
If I will find more better one, I will edit this post or write new post.
Posted on January 2, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.