Многократное управление навигацией через внедрение зависимости - PullRequest
1 голос
/ 22 марта 2019

Мой базовый класс контента.Я использовал этот класс в качестве темы для моего проекта.Я не знаю, эта информация актуальна или нет.Здесь я создаю абстрактный метод, который будет перегружать метод навигации.

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

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

    public abstract void Navigate(SelectedItemChangedEventArgs e);
}

В моем локаторе, где я строю зависимость Injection, открытый класс Locator.В этом классе основное внимание уделяется добавлению этого класса в контейнер, чтобы связать все потери кода

    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>();   }

В моем app.Xaml.Cs файле

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

    public static IContainer Container;

Я использовал этот метод для навигации в коде моего представления за страницей

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

Этот код работает отлично, но он может перейти только на одну страницу. В качестве примера на одной странице у нас есть две кнопки для навигациидве разные страницы.Я не знаю, как реализовать эту задачу, используя вышеуказанный навигационный перегружатель.Как это сделать, может кто-нибудь дать предложение по преодолению проблемы?Также я использовал autofac для внедрения зависимостей. Спасибо

1 Ответ

2 голосов
/ 22 марта 2019

Вы можете определить контейнер в CustomNavigationPage и использовать его в каждом экземпляре страницы навигации.

public class CustomNavigationPage : NavigationPage
{
   public static IContainer Container;

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

Это фиктивный код, о котором я упоминал.

Вы создаетестраница навигации, которая настроена.Таким образом, вы можете использовать это для навигации по своим страницам, например:

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

Если вы используете эту функцию, ваша пользовательская страница навигации будет разрешать ваши зависимости при каждом вызове.

Для повышения производительности вы можете зарегистрироватьсяваши зависимости с синглтонКогда приложение запустится, зависимости будут зарегистрированы.После того, как вы используете эти зарегистрированные зависимости.

Есть улучшение: вы определяете статический локатор с одноэлементным шаблоном, он регистрирует зависимости в 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;
    }
    }
    }
    }

И в вашем app.cs:

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

    public static IContainer Container;

Таким образом, вы только один раз регистрируете свои зависимости.Там нет дублирования кода.Будет использован только один экземпляр.

...