
आधुनिक अनुप्रयोगों के उपयोगकर्ता इंटरफ़ेस आमतौर पर जटिल होते हैं - यह अक्सर पृष्ठ नेविगेशन समर्थन को लागू करने, विभिन्न इनपुट क्षेत्रों को संसाधित करने और उपयोगकर्ता द्वारा चुने गए मापदंडों के आधार पर जानकारी को प्रदर्शित करने या छिपाने के लिए आवश्यक होता है। उसी समय, UX को बेहतर बनाने के लिए, एप्लिकेशन को निलंबन या शटडाउन के दौरान इंटरफ़ेस तत्वों की स्थिति को डिस्क पर सहेजना होगा, प्रोग्राम को पुनरारंभ होने पर डिस्क से राज्य को पुनर्स्थापित करें।
रिएक्टिविवई एमवीवीएम फ्रेमवर्क एक कार्यक्रम की स्थिति को प्रस्तुत करने के लिए प्रस्तुति मॉडल के ग्राफ को क्रमबद्ध करके एक आवेदन की स्थिति को संरक्षित करने का प्रस्ताव रखता है, जबकि निलंबन के क्षण को निर्धारित करने के तंत्र चौखटे और प्लेटफार्मों के लिए अलग हैं। तो, WPF के लिए, Exit
इवेंट का उपयोग किया जाता है, Xamarin.Android के लिए - ActivityPaused
DidEnterBackground
, Xamarin.iOS के लिए - DidEnterBackground
, UWP के लिए - OnLaunched
अधिभार।
इस लेख में, हम एक उदाहरण के रूप में एवलोनिया क्रॉस-प्लेटफ़ॉर्म जीयूआई फ्रेमवर्क का उपयोग करके एक राउटर की स्थिति सहित जीयूआई के साथ सॉफ्टवेयर की स्थिति को बचाने और पुनर्स्थापित करने के लिए रिएक्टिवयूआई के उपयोग पर विचार करेंगे। सामग्री MVVM डिजाइन पैटर्न और प्रतिक्रियाशील प्रोग्रामिंग की मूल समझ को C # भाषा और रीडर के लिए .NET प्लेटफ़ॉर्म के रूप में मानती है। इस आलेख के चरण Windows 10 और Ubuntu 18 पर लागू होते हैं।
परियोजना निर्माण
कार्रवाई में रूटिंग का प्रयास करने के लिए, Avalonia टेम्पलेट से एक नया .NET कोर प्रोजेक्ट बनाएं, Avalonia.ReactiveUI
पैकेज - Avalonia और ReactiveUI एकीकरण की एक पतली परत स्थापित करें। सुनिश्चित करें कि आपके पास शुरू होने से पहले .NET कोर SDK और git स्थापित है।
git clone https://github.com/AvaloniaUI/avalonia-dotnet-templates git --git-dir ./avalonia-dotnet-templates/.git checkout 9263c6b dotnet new --install ./avalonia-dotnet-templates dotnet new avalonia.app -o ReactiveUI.Samples.Suspension cd ./ReactiveUI.Samples.Suspension dotnet add package Avalonia.ReactiveUI dotnet add package Avalonia.Desktop dotnet add package Avalonia
सुनिश्चित करें कि आवेदन शुरू होता है और एक विंडो प्रदर्शित करता है जो वेलकम टू एवलोनिया कहती है!
# Use .NET Core version which you have installed. # It can be netcoreapp2.0, netcoreapp2.1 and so on. dotnet run --framework netcoreapp3.0

Avalonia को MyGet से प्री-बिल्ड कनेक्ट करें
कनेक्ट करने के लिए और नवीनतम एवलोनिया बिल्ड का उपयोग करने के लिए जो स्वचालित रूप से MyGet पर प्रकाशित होते हैं जब GitHub में एवलोनिया रिपॉजिटरी master
शाखा बदलती है, हम nuget.config
पैकेज स्रोत कॉन्फ़िगरेशन फ़ाइल का उपयोग करते हैं। IDE और .NET कोर CLI के लिए nuget.config
देखने के लिए , आपको ऊपर बनाई गई परियोजना के लिए एक sln
फ़ाइल जनरेट करनी होगी। हम .NET कोर CLI के टूल का उपयोग करते हैं:
dotnet new sln # Ctrl+C dotnet sln ReactiveUI.Samples.Suspension.sln add ReactiveUI.Samples.Suspension.csproj
निम्नलिखित सामग्री की .sln
फ़ाइल के साथ एक फ़ोल्डर में एक nuget.config
फ़ाइल बनाएँ:
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="AvaloniaCI" value="https://www.myget.org/F/avalonia-ci/api/v2" /> </packageSources> </configuration>
आपको IDE को पुनरारंभ करने, या अनलोड करने और संपूर्ण समाधान डाउनलोड करने की आवश्यकता हो सकती है। हम आपके IDE के NuGet पैकेज प्रबंधक इंटरफ़ेस का उपयोग करके या विंडोज कमांड लाइन टूल या लिनक्स टर्मिनल का उपयोग करके आवश्यक संस्करण (कम से कम 0.9.1
) में एवलोनिया पैकेज को अपडेट करेंगे:
dotnet add package Avalonia.ReactiveUI --version 0.9.1 dotnet add package Avalonia.Desktop --version 0.9.1 dotnet add package Avalonia --version 0.9.1 cat ReactiveUI.Samples.Suspension.csproj
अब ReactiveUI.Samples.Suspension.csproj
प्रोजेक्ट फ़ाइल कुछ इस प्रकार है:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> <ItemGroup> <Compile Update="**\*.xaml.cs"> <DependentUpon>%(Filename)</DependentUpon> </Compile> <AvaloniaResource Include="**\*.xaml"> <SubType>Designer</SubType> </AvaloniaResource> </ItemGroup> <ItemGroup> <PackageReference Include="Avalonia" Version="0.9.1" /> <PackageReference Include="Avalonia.Desktop" Version="0.9.1" /> <PackageReference Include="Avalonia.ReactiveUI" Version="0.9.1" /> </ItemGroup> </Project>
प्रोजेक्ट रूट में Views/
और ViewModels/
फ़ोल्डर बनाएँ, सुविधा के लिए MainWindow
वर्ग का नाम MainView
, इसे Views/
निर्देशिका में ले जाएं, ReactiveUI.Samples.Suspension.Views
अनुसार नामस्थान बदल रहे हैं। Program.cs
और App.xaml.cs
की सामग्री को संपादित करें - Avalonia एप्लिकेशन बिल्डर को UseReactiveUI
कॉल लागू करें, अनुप्रयोग जीवनचक्र प्रबंधन अनुशंसाओं का पालन करने के लिए, OnFrameworkInitializationCompleted
में मुख्य दृश्य के प्रारंभ को स्थानांतरित करें:
Program.cs
class Program {
App.xaml.cs
public class App : Application { public override void Initialize() => AvaloniaXamlLoader.Load(this);
आपको using Avalonia.ReactiveUI
का using Avalonia.ReactiveUI
Program.cs
जोड़ना होगा। सुनिश्चित करें कि संकुल अद्यतन करने के बाद, परियोजना शुरू होती है और डिफ़ॉल्ट स्वागत विंडो प्रदर्शित करती है।
# Use .NET Core version which you have installed. # It can be netcoreapp2.0, netcoreapp2.1 and so on. dotnet run --framework netcoreapp3.0

एक नियम के रूप में, .NET अनुप्रयोग के पृष्ठों के बीच नेविगेशन को लागू करने के लिए दो मुख्य दृष्टिकोण हैं - दृश्य-प्रथम और दृश्य मॉडल-प्रथम। व्यू-प्रथम दृष्टिकोण में MVVM शब्दावली में व्यू स्तर पर पृष्ठों के बीच नेविगेशन स्टैक और नेविगेशन को नियंत्रित करना शामिल है - उदाहरण के लिए, UWP या WPF के मामले में फ़्रेम और पेज कक्षाओं का उपयोग करना, और व्यू मॉडल-प्रथम दृष्टिकोण का उपयोग करते समय, नेविगेशन को प्रस्तुति मॉडल के स्तर पर लागू किया जाता है। ReactiveUI टूल जो एप्लिकेशन में रूटिंग को व्यवस्थित करते हैं, वे दृश्य मॉडल-प्रथम दृष्टिकोण का उपयोग करने पर केंद्रित हैं। ReactiveUI रूटिंग में एक IScreen
कार्यान्वयन होता है जिसमें राउटर की IRoutableViewModel
कई कार्यान्वयन और प्लेटफ़ॉर्म- RoutedViewHost
XAML नियंत्रण, RoutedViewHost
।

राउटर की स्थिति को RoutingState
ऑब्जेक्ट द्वारा दर्शाया जाता है जो नेविगेशन स्टैक को नियंत्रित करता है। IScreen
नेविगेशन स्टैक की जड़ है, और एप्लिकेशन में कई नेविगेशन रूट हो सकते हैं। RoutedViewHost
XAML नियंत्रण के संबंधित IRoutableViewModel
को एम्बेड करके नेविगेशन स्टैक में परिवर्तन का जवाब देते हुए, इसके संबंधित RoutingState
राउटर की स्थिति की निगरानी करता है। वर्णित कार्यक्षमता नीचे दिए गए उदाहरणों द्वारा चित्रित की जाएगी।
डिस्क पर दृश्य मॉडल की स्थिति को सहेजना
सूचना खोज स्क्रीन के एक विशिष्ट उदाहरण पर विचार करें।

हमें यह निर्धारित करना चाहिए कि एप्लिकेशन के निलंबन या शटडाउन के दौरान डिस्क को सहेजने के लिए स्क्रीन प्रतिनिधित्व मॉडल के कौन से तत्व हैं, और जो शुरू होने पर प्रत्येक बार पुनः बनाने के लिए -। ReactiveUI कमांड्स की स्थिति को बचाने की कोई आवश्यकता नहीं है जो ICommand
इंटरफ़ेस को लागू करते हैं और बटन से जुड़े होते हैं - ReactiveCommand<TIn, TOut>
को ReactiveCommand<TIn, TOut>
में बनाया और आरंभ किया जाता है, जबकि CanExecute
संकेतक की स्थिति दृश्य मॉडल के गुणों पर निर्भर करती है और जब वे बदलते हैं तो पुनर्गणना होती है। खोज परिणामों को सहेजने की आवश्यकता - एक मूट बिंदु - आवेदन की बारीकियों पर निर्भर करता है, लेकिन SearchQuery
इनपुट क्षेत्र की स्थिति को बचाने और पुनर्स्थापित करने में समझदारी होगी!
ViewModels / SearchViewModel.cs
[DataContract] public class SearchViewModel : ReactiveObject, IRoutableViewModel { private readonly ReactiveCommand<Unit, Unit> _search; private string _searchQuery;
दृश्य मॉडल के वर्ग को [DataContract]
विशेषता के साथ चिह्नित किया गया है, और जिन गुणों को [DataMember]
साथ क्रमबद्ध किया जाना है। यह पर्याप्त है अगर धारावाहिक उपयोग करने वाले ऑप्ट-इन दृष्टिकोण का उपयोग करता है - यह केवल उन गुणों को बचाता है जो डिस्क के लिए विशेषताओं के साथ स्पष्ट रूप से चिह्नित होते हैं, ऑप्ट-आउट दृष्टिकोण के मामले में, [IgnoreDataMember]
गुणों के साथ चिह्नित करना आवश्यक है, जिन्हें डिस्क पर सहेजने की आवश्यकता नहीं है। इसके अतिरिक्त, हम अपने दृश्य मॉडल में IRoutableViewModel
इंटरफ़ेस लागू करते हैं ताकि बाद में यह एप्लिकेशन राउटर के नेविगेशन फ्रेम का हिस्सा बन सके।
इसी तरह, हम प्राधिकरण पृष्ठ प्रस्तुति मॉडल को लागू करते हैंViewModels / LoginViewModel.cs
[DataContract] public class LoginViewModel : ReactiveObject, IRoutableViewModel { private readonly ReactiveCommand<Unit, Unit> _login; private string _password; private string _username;
आवेदन के दो पन्नों के लिए प्रस्तुति मॉडल तैयार हैं, IRoutableViewModel
इंटरफ़ेस को लागू करें और इसे IScreen
राउटर में बनाया जा सकता है। अब हम सीधे IScreen
लागू करते हैं। हम [DataContract]
विशेषताओं की सहायता से चिह्नित करते हैं कि दृश्य मॉडल के कौन से गुण क्रमबद्ध हैं और जिन्हें अनदेखा करना है। नीचे दिए गए उदाहरण में [DataMember]
के साथ चिह्नित संपत्ति के सार्वजनिक सेटर पर ध्यान दें - संपत्ति जानबूझकर लेखन के लिए खुली है ताकि धारावाहिक निर्माता मॉडल डिसेरिएलाइजेशन के दौरान ऑब्जेक्ट के नए सिरे से बनाए गए उदाहरण को संशोधित कर सके।
ViewModels / MainViewModel.cs
[DataContract] public class MainViewModel : ReactiveObject, IScreen { private readonly ReactiveCommand<Unit, Unit> _search; private readonly ReactiveCommand<Unit, Unit> _login; private RoutingState _router = new RoutingState(); public MainViewModel() {
हमारे आवेदन में, केवल RoutingState
को डिस्क पर सहेजने की आवश्यकता है, स्पष्ट कारणों के लिए, आदेशों को डिस्क पर सहेजने की आवश्यकता नहीं है - उनकी स्थिति पूरी तरह से राउटर पर निर्भर करती है। क्रमबद्ध ऑब्जेक्ट में IRoutableViewModel
लागू करने वाले प्रकारों के बारे में विस्तारित जानकारी शामिल होनी चाहिए ताकि नेविगेशन स्टैक को IRoutableViewModel
पर पुनर्स्थापित किया जा सके। हम MainViewModel
व्यू MainViewModel
के तर्क का वर्णन करते हैं, क्लास को ViewModels/MainViewModel.cs
और संबंधित ReactiveUI.Samples.Suspension.ViewModels
नाम स्थान में रखें।

Avalonia ऐप में रूटिंग
मॉडल के लेयर लेवल पर यूजर इंटरफेस लॉजिक और डेमो एप्लिकेशन के प्रेजेंटेशन मॉडल को कार्यान्वित किया जाता है और इसे .NET मानक के उद्देश्य से एक अलग असेंबली में ले जाया जा सकता है, क्योंकि यह GUI फ्रेमवर्क के बारे में कुछ भी नहीं जानता है। आइए प्रेजेंटेशन लेयर पर एक नजर डालते हैं। MVVM शब्दावली में, प्रस्तुति परत स्क्रीन पर प्रस्तुति मॉडल की स्थिति प्रदान करने के लिए जिम्मेदार है। RoutingState
राउटर की वर्तमान स्थिति को प्रस्तुत करने के लिए, Avalonia.ReactiveUI
पैकेज में निहित XAML RoutedViewHost
नियंत्रण का Avalonia.ReactiveUI
। हम SearchViewModel
लिए GUI लागू करते हैं - इसके लिए, Views/
निर्देशिका में, दो फ़ाइलें बनाएँ: SearchView.xaml
और SearchView.xaml.cs
।
एवलोनिया में उपयोग की जाने वाली XAML बोली का उपयोग करने वाले उपयोगकर्ता इंटरफ़ेस का विवरण डेवलपर्स के लिए विंडोज प्रेजेंटेशन फाउंडेशन, यूनिवर्सल विंडोज प्लेटफॉर्म या Xamarin.Forms पर परिचित होने की संभावना है। ऊपर के उदाहरण में, हम खोज फ़ॉर्म के लिए एक तुच्छ इंटरफ़ेस बनाते हैं - हम खोज क्वेरी और खोज शुरू करने वाले एक बटन को दर्ज करने के लिए एक पाठ क्षेत्र आकर्षित करते हैं, जबकि हम ऊपर परिभाषित SearchViewModel
मॉडल के गुणों पर नियंत्रण को बांधते हैं।
दृश्य / SearchView.xaml
<UserControl xmlns="https://github.com/avaloniaui" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DataContext="{d:DesignInstance viewModels:SearchViewModel}" xmlns:viewModels="clr-namespace:ReactiveUI.Samples.Suspension.ViewModels" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ReactiveUI.Samples.Suspension.Views.SearchView" xmlns:reactiveUi="http://reactiveui.net" mc:Ignorable="d"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="48" /> <RowDefinition Height="48" /> <RowDefinition Height="48" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="Search view" Margin="5" /> <TextBox Grid.Row="1" Text="{Binding SearchQuery, Mode=TwoWay}" /> <Button Grid.Row="2" Content="Search" Command="{Binding Search}" /> </Grid> </UserControl>
दृश्य / SearchView.xaml.cs
public sealed class SearchView : ReactiveUserControl<SearchViewModel> { public SearchView() {
SearchView.xaml
कंट्रोल का कोड- SearchView.xaml
परिचित WPF, UWP और XF SearchView.xaml
को भी दिखाई देगा। जब किसी दृश्य या प्रस्तुति मॉडल को सक्रिय और निष्क्रिय करने के समय कुछ कोड को निष्पादित करने के लिए व्हॉट्सएप किए गए कॉल का उपयोग किया जाता है। यदि आपका एप्लिकेशन हॉट ऑब्ज़र्वबल्स (टाइमर, जियोलोकेशन, मैसेज बस से कनेक्शन) का उपयोग करता है, तो DisposeWith
CompositeDisposable
कॉल CompositeDisposable
उन्हें DisposeWith
संलग्न करना बुद्धिमान होगा ताकि जब आप DisposeWith
कंट्रोल और इसके संबंधित व्यू मॉडल को DisposeWith
कर DisposeWith
तो DisposeWith
नए मान प्रकाशित करना बंद कर दें और कोई लीक न हो। स्मृति।
इसी तरह, हम प्राधिकरण पृष्ठ के प्रतिनिधित्व को लागू करते हैं।दृश्य / LoginView.xaml
<UserControl xmlns="https://github.com/avaloniaui" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DataContext="{d:DesignInstance viewModels:LoginViewModel, IsDesignTimeCreatable=True}" xmlns:viewModels="clr-namespace:ReactiveUI.Samples.Suspension.ViewModels" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ReactiveUI.Samples.Suspension.Views.LoginView" xmlns:reactiveUi="http://reactiveui.net" mc:Ignorable="d"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="48" /> <RowDefinition Height="48" /> <RowDefinition Height="48" /> <RowDefinition Height="48" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="Login view" Margin="5" /> <TextBox Grid.Row="1" Text="{Binding Username, Mode=TwoWay}" /> <TextBox Grid.Row="2" PasswordChar="*" Text="{Binding Password, Mode=TwoWay}" /> <Button Grid.Row="3" Content="Login" Command="{Binding Login}" /> </Grid> </UserControl>
दृश्य / LoginView.xaml.cs
public sealed class LoginView : ReactiveUserControl<LoginViewModel> { public LoginView() { this.WhenActivated(disposables => { }); AvaloniaXamlLoader.Load(this); } }
Views/MainView.xaml
और Views/MainView.xaml.cs
। मुख्य स्क्रीन पर RoutedViewHost
नाम स्थान से XAML RoutedViewHost
RoutingState
गुण को RoutingState
राउटर की स्थिति असाइन करें। खोज और प्राधिकरण पृष्ठों पर नेविगेट करने के लिए बटन जोड़ें, उन्हें ऊपर वर्णित ViewModels/MainViewModel
गुणों से ViewModels/MainViewModel
।
दृश्य / MainView.xaml
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="ReactiveUI.Samples.Suspension.Views.MainView" xmlns:reactiveUi="http://reactiveui.net" Title="ReactiveUI.Samples.Suspension"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="48" /> </Grid.RowDefinitions> <reactiveUi:RoutedViewHost Grid.Row="0" Router="{Binding Router}"> <reactiveUi:RoutedViewHost.DefaultContent> <TextBlock Text="Default Content" /> </reactiveUi:RoutedViewHost.DefaultContent> </reactiveUi:RoutedViewHost> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Button Grid.Column="0" Command="{Binding Search}" Content="Search" /> <Button Grid.Column="1" Command="{Binding Login}" Content="Login" /> <Button Grid.Column="2" Command="{Binding Router.NavigateBack}" Content="Back" /> </Grid> </Grid> </Window>
दृश्य / MainView.xaml.cs
public sealed class MainView : ReactiveWindow<MainViewModel> { public MainView() { this.WhenActivated(disposables => { }); AvaloniaXamlLoader.Load(this); } }
ReactiveUI और Avalonia रूटिंग क्षमताओं का प्रदर्शन करने वाला एक सरल अनुप्रयोग तैयार है। जब Search
और Login
बटन पर क्लिक किया जाता है, तो संबंधित आदेशों को कॉल किया जाता है, दृश्य मॉडल का एक नया उदाहरण बनाया जाता है, और RoutingState
अपडेट किया जाता है। XAML नियंत्रण RoutedViewHost
, जो RoutedViewHost
में परिवर्तन की सदस्यता RoutingState
, IViewFor<TViewModel>
प्राप्त करने की कोशिश करता है, जहां TViewModel
से व्यू मॉडल प्रकार है। यदि IViewFor<TViewModel>
एक पंजीकृत कार्यान्वयन पाया IViewFor<TViewModel>
है, तो एक नया उदाहरण बनाया जाएगा, RoutedViewHost
में बनाया गया और Avalonia एप्लिकेशन विंडो में प्रदर्शित किया जाएगा।

हम आवश्यक घटकों को रजिस्टर करते हैं IViewFor<TViewModel>
और IScreen
को App.OnFrameworkInitializationCompleted
विधि में Locator.CurrentMutable
का उपयोग करके पंजीकृत करते हैं। IViewFor<TViewModel>
RoutedViewHost
काम RoutedViewHost
लिए आवश्यक RoutedViewHost
, और IScreen
पंजीकरण आवश्यक है ताकि SearchViewModel
, SearchViewModel
और LoginViewModel
को SearchViewModel
और LoginViewModel
बिना कंस्ट्रक्टर का उपयोग करके सही ढंग से आरंभ किया जा सके।
App.xaml.cs
public override void OnFrameworkInitializationCompleted() {
एप्लिकेशन चलाएँ और सुनिश्चित करें कि रूटिंग सही तरीके से काम करती है। यदि XAML मार्कअप में कोई त्रुटि है, तो एवलोनिया में इस्तेमाल किया गया XamlIl संकलक हमें बताएगा कि संकलन के स्तर पर कहां है। XamlIl IDE डिबगर में XAML डिबगिंग का भी समर्थन करता है !
dotnet run --framework netcoreapp3.0

संपूर्ण एप्लिकेशन स्थिति को सहेजना और पुनर्स्थापित करना
अब जब राउटिंग कॉन्फ़िगर किया गया है और काम कर रहा है, तो सबसे दिलचस्प हिस्सा शुरू होता है - आपको राउटर की स्थिति के साथ, डिस्क को सहेजने और डिस्क से डेटा को पढ़ने पर डिस्क को सहेजने के डेटा को लागू करने की आवश्यकता होती है। हुक की शुरूआत जो अनुप्रयोग प्रारंभ और करीबी घटनाओं को AutoSuspendHelper
, एक विशेष AutoSuspendHelper
वर्ग द्वारा संभाला जाता है, जो प्रत्येक प्लेटफॉर्म के लिए AutoSuspendHelper
है जो रिएक्टिवुई का समर्थन करता है। डेवलपर का कार्य इस वर्ग को आवेदन की संरचना के मूल में बहुत पहले से शुरू करना है। RxApp.SuspensionHost.CreateNewAppState
फ़ंक्शन के RxApp.SuspensionHost.CreateNewAppState
को प्रारंभ करने के लिए भी आवश्यक है जो अनुप्रयोग की डिफ़ॉल्ट स्थिति को वापस कर देगा यदि कोई सहेजे गए राज्य नहीं है या एक अप्रत्याशित त्रुटि हुई है, या यदि सहेजी गई फ़ाइल क्षतिग्रस्त है।
इसके बाद, आपको RxApp.SuspensionHost.SetupDefaultSuspendResume
विधि को कॉल करने की आवश्यकता है, इसे ISuspensionDriver
कार्यान्वयन से ISuspensionDriver
, ड्राइवर जो राज्य ऑब्जेक्ट ISuspensionDriver
और पढ़ता है। ISuspensionDriver
को लागू करने के लिए, ISuspensionDriver
फाइल सिस्टम के साथ काम करने के लिए Newtonsoft.Json
लाइब्रेरी और System.IO
नामस्थान का उपयोग करते हैं। ऐसा करने के लिए, Newtonsoft.Json
पैकेज स्थापित करें:
dotnet add package Newtonsoft.Json
ड्राइवर / NewtonsoftJsonSuspensionDriver.cs
public class NewtonsoftJsonSuspensionDriver : ISuspensionDriver { private readonly string _file; private readonly JsonSerializerSettings _settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }; public NewtonsoftJsonSuspensionDriver(string file) => _file = file; public IObservable<Unit> InvalidateState() { if (File.Exists(_file)) File.Delete(_file); return Observable.Return(Unit.Default); } public IObservable<object> LoadState() { var lines = File.ReadAllText(_file); var state = JsonConvert.DeserializeObject<object>(lines, _settings); return Observable.Return(state); } public IObservable<Unit> SaveState(object state) { var lines = JsonConvert.SerializeObject(state, _settings); File.WriteAllText(_file, lines); return Observable.Return(Unit.Default); } }
— System.IO
Universal Winows Platform, — File
Directory
StorageFile
StorageFolder
. , IRoutableViewModel
, Newtonsoft.Json
TypeNameHandling.All
. Avalonia — App.OnFrameworkInitializationCompleted
:
public override void OnFrameworkInitializationCompleted() {
AutoSuspendHelper
Avalonia.ReactiveUI
IApplicationLifetime
— , ISuspensionDriver
. ISuspensionDriver
appstate.json
:
appstate.json— $type
, , .
{ "$type": "ReactiveUI.Samples.Suspension.ViewModels.MainViewModel, ReactiveUI.Samples.Suspension", "Router": { "$type": "ReactiveUI.RoutingState, ReactiveUI", "_navigationStack": { "$type": "System.Collections.ObjectModel.ObservableCollection`1[[ReactiveUI.IRoutableViewModel, ReactiveUI]], System.ObjectModel", "$values": [ { "$type": "ReactiveUI.Samples.Suspension.ViewModels.SearchViewModel, ReactiveUI.Samples.Suspension", "SearchQuery": "funny cats" }, { "$type": "ReactiveUI.Samples.Suspension.ViewModels.LoginViewModel, ReactiveUI.Samples.Suspension", "Username": "worldbeater" } ] } } }
, , , , , , ! , , ReactiveUI — UWP WPF, Xamarin.Forms.

: ISuspensionDriver
Akavache — UserAccount
Secure
iOS UWP , , Android BundleSuspensionDriver ReactiveUI.AndroidSupport
. JSON Xamarin.Essentials SecureStorage
. , — !