通过依赖注入进行多重导航控制

时间:2019-03-22 05:18:47

标签: c# mvvm xamarin.forms autofac

我的基本内容类。我将此类用作我项目的主题。我不知道此信息是否相关。在这里,我创建了一个抽象方法,该方法将使导航方法超载。

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

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

    public abstract void Navigate(SelectedItemChangedEventArgs e);
}

在我的依赖关系构建公共注入的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 个答案:

答案 0 :(得分:2)

  

您可以在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;

这样,您只需一次注册您的依赖项。没有重复的代码。将仅使用一个实例。