18
[C#][Uno Platform] Create desktop applications on Ubuntu 2
This time, I will try installing NuGet packages, using DI, firing life-cycle events.
- Ubuntu ver.21.10
- .NET ver.6.0.101
- Uno Platform ver.4.0.11
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.
Sometimes, I want to execute something on loading the page, closing the page, and so on.
In "UnoSample.Shared", I can use "Loaded" event in MainPage.xaml.cs to execute on the page loaded.
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.
When I open MainPage, these classes are instantiated in sequence.
![](https://res.cloudinary.com/practicaldev/image/fetch/s--YHWJJNdH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsvaddmqfz62ox67s4ih.png)
In "UnoSample.Skia.Gtk" project, there is only "Main" method.
So I can execute closing operations after "host.Run()".
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.
}
}
}
}
How shall I call methods in UnoSample.Shared classes?
I can access App.xaml.cs like below.
...
namespace UnoSample
{
public sealed partial class App : Application
{
private Window _window;
public void Greet(string message)
{
Console.WriteLine($"SharedApp {message}");
}
...
...
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");
}
}
}
}
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.
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();
}
}
}
...
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();
...
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.
18