ish1104
ish1104

Reputation: 421

Multiple navigation control through dependency injection

My base content class. I used this class as a theme for my project. I do not know this info relevant or not. In here I create an abstract method that would overload the navigation method.

public abstract class BaseContentPage : ContentPage
{
    public readonly BaseViewModel BaseViewModel;

    public BaseContentPage(BaseViewModel baseViewModel)
    {
        BaseViewModel = baseViewModel;
    }

    public abstract void Navigate(SelectedItemChangedEventArgs e);
}

In my locator where I build the dependency Injection public class Locator. in this class mainly focus on adding this class to the container to make the all code loss coupling

    private readonly ContainerBuilder _builder;

    public Locator()
    {
        _builder = new ContainerBuilder();
        RegisterTypes();
        Container = _builder.Build();
    }

    public IContainer Container { get; set; }

    private void RegisterTypes()
    {
        _builder.RegisterType<WardListService>().As<IWardListService>();
        _builder.RegisterType<WardListPageViewModel>();
        _builder.RegisterType<WardListPage>();

        _builder.RegisterType<PatientService>().As<IPatientService>();
        _builder.RegisterType<PatientListPageViewModel>();
        _builder.RegisterType<PatientListViewPage>();

        _builder.RegisterType<PatientDetailsPageViewModel>();
        _builder.RegisterType<PatientDetailsViewPage>();   }

In my app.Xaml.Cs file

 public App()
    {
        InitializeComponent();              
        Locator locator = new Locator();
        Container = locator.Container;
        MainPage = new NavigationPage(Container.Resolve<WardListPage>());
    }

    public static IContainer Container;

I used this method for navigation in my view code behind page

    public async override void Navigate(SelectedItemChangedEventArgs e)
    {
        PatientDetailsViewPage patientDetailsViewPage = App.Container.Resolve<PatientDetailsViewPage>();
        patientDetailsViewPage.BaseViewModel.SelectedPatient = e.SelectedItem as PatientViewModel;
        await Navigation.PushAsync(patientDetailsViewPage);
    }

This code is working perfectly but this only can navigate to one page.meaning as an example on one page we have two buttons that navigate to two different pages. I don't know how to implement this task using above navigate overloader. How to do it can anyone give suggestion to overcome the problem?. Also, I used autofac for dependency injection Thank you

Upvotes: 1

Views: 350

Answers (1)

Batuhan
Batuhan

Reputation: 1611

You can define container in your CustomNavigationPage and use in every navigation page instance.

public class CustomNavigationPage : NavigationPage
{
   public static IContainer Container;

   public CustomNavigationPage()
   {
       Locator locator = new Locator();
       locator.RegisterTypes();
       Container = locator.Container();
   }
}

It is dummy code what i mentioned.

You creating a navigation page that customized. So you can use this navigating your pages for example:

CustomNavigationPage.PushASync(new TestPage(Container.Resolve<WardListPage>())):

If use this your custom navigation page will be resolve your dependencies every call.

To improve performance you can register your dependencies with singleton pattern. When the app started, dependencies will be registered. After you use this registered dependencies.

There is an improvement : You define a static locator with singleton pattern it registers dependencies in app.cs

public sealed class Locator
    {
    private static Locator locator = null;
    private static readonly object padlock = new object();

    Locator()
    {
      //your registries
    }

    public static Locator Locator
    {
    get
    {
    lock (padlock)
    {
    if (locator == null)
    {
    locator = new Locator();
    }
    return locator;
    }
    }
    }
    }

And your app.cs :

 public App()
    {
        InitializeComponent();              
        Locator locator = new Locator();
        Container = locator.Container;
        .
        .
    }

    public static IContainer Container;

This way you only one time register your dependencies. There is no duplication of code. Only one instance will be used.

Upvotes: 2

Related Questions