I have a running XF App with a lot of database accesses through an Azure API. So far all was running quite well. Due to layout changes I changed to a shell based navigation. I worked through the whole stuff but faces a huge problem. My app.xaml.cs is loding a lot of controllers:
Public partical class App : Xamarin.Forms.Application, INotifyPropertyChanged {public static CampaignController CampaignController { get; private set; }}
And in OnStart()
CampaignController = new CampaignController(new RestService());
In public App() I load the AppShell() as Mainpage
MainPage = new AppShell();
This is my AppShell.xaml
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:EY365OCMobileApp"
x:Class="EY365OCMobileApp.AppShell">
<ShellContent Route="WelcomePage" ContentTemplate="{DataTemplate local:WelcomePage}">
</ShellContent>
The WelcomePage.xaml.cs looks like this:
protected async override void OnAppearing()
{
try
{
base.OnAppearing();
Campaigns = await App.CampaignController.GetCampaignsAsync(364840001);
CarouselView.ItemsSource = Campaigns;
BindingContext = Campaigns;
}
catch (Exception ex)
{
await CreateNewBug.CreateANewBug(ex.Message,"Error in Module " ex.Source,"\nMessage---\n{ 0}" ex.Message "\nInnerException---\n{ 0}" ex.InnerException "\nStackTrace---\n{ 0}" ex.StackTrace "\nTargetSite---\n{ 0}" ex.TargetSite);
ToastOptions toastOptions = Message.ShowMessage("An error was raised and a new bug created in our system.", "error");
await this.DisplayToastAsync(toastOptions);
}
}
This line creates an error:
Campaigns = await App.CampaignController.GetCampaignsAsync(364840001);
Object reference not set to an instance of an object.
When I debug it seems that the initialization of the app.xaml.cs doesn't run though because it jumps to the AppShell.xaml.cs. When I move the code from App.xaml.cs to AppShell.xaml.cs it brings the same error. Any idea how to initialize the rest-service controller in a shell environment of Xamarin?
CodePudding user response:
You can lazy load the controller whenever you use it .
App
CampaignController _controller;
Public CampaignController controller{
get
{
if(_controller == null)
{
_controller = new CampaignController(new RestService());
}
return _controller;
}
}
WelcomePage
Campaigns = await (App.Current as App).controller.GetCampaignsAsync(364840001);
CarouselView.ItemsSource = Campaigns;