Autofac.Core.DependencyResolutionException ViewModel 尚未注册 Autofac Xamarin.Forms

Autofac.Core.DependencyResolutionException ViewModel has not been registered Autofac Xamarin.Forms

大家好,我正在使用 Autofac 作为我的 DI 代码库,我正在遵循此解决方案 ,因为我在 tabbedPage 中的 Press 按钮无法导航到下一页或 link 页面。在 xaml.

中使用 Button={Binding MyNextPage}

在那个解决方案中我对此有点困惑

     builder.RegisterInstance<Func<Page>>(() => ((NavigationPage)Application.Current.MainPage).CurrentPage);

作为我的模块,我单独注册它们

   public class ClientModule : Module
   {
    //Register Here for Singleton
    protected override void Load(ContainerBuilder builder)
    {
        //RegServ Service
        builder.RegisterType<PersonInfoService>().As<IPersonInfoService>().SingleInstance();
        builder.RegisterType<PhoneContactService>().As<IPhoneContacts>().SingleInstance();

        //RegServ View Model 
        builder.RegisterType<PersonViewModel>();
        builder.RegisterType<PhoneContactViewModelProp>();
        builder.RegisterType<LoginViewModel>(); 


        builder.RegisterType<LoginPageViewModel>().SingleInstance();
        builder.RegisterType<PersonsViewModel>().SingleInstance();
        builder.RegisterType<PersonDetailViewModel>().SingleInstance();
        builder.RegisterType<RegistrationViewModel>().SingleInstance();
        builder.RegisterType<PhoneContactViewModel>().SingleInstance();
        builder.RegisterType<MainPageViewModel>().SingleInstance();


        //RegServ Views 
        builder.RegisterType<MainPage>().SingleInstance();
        builder.RegisterType<BarcodePage>().SingleInstance();
        builder.RegisterType<CustomScanPageView>().SingleInstance();
        builder.RegisterType<CQRCodeOptionPage>().SingleInstance();
        builder.RegisterType<PersonPageView>().SingleInstance();
        builder.RegisterType<PersonDetailViewPage>().SingleInstance();
        builder.RegisterType<RegistrationPage>().SingleInstance();
        builder.RegisterType<ClientReadQRPage>().SingleInstance();
        builder.RegisterType<LoginPage>().SingleInstance();
        builder.RegisterType<PhoneBookPage>().SingleInstance();

    }
}

AutofacBootstrapper.cs

  namespace FormsSample.Core
  {
  public abstract class AutofacBootstrapper
  {
    public void Run()
    {
        var builder = new ContainerBuilder();

        ConfigureContainer(builder);

        var container = builder.Build();
        var viewFactory = container.Resolve<IViewFactory>();

        RegisterViews(viewFactory);

        ConfigureApplication(container);
    }

    protected virtual void ConfigureContainer(ContainerBuilder builder)
    {
        builder.RegisterModule<AutofacModule>();
    }

    protected abstract void RegisterViews(IViewFactory viewFactory);

    protected abstract void ConfigureApplication(IContainer container);
  }
}

AutofacModule.cs

 namespace FormsSample.Core
 {
 public class AutofacModule : Module
 {
    protected override void Load(ContainerBuilder builder)
    {
        // service registration
        builder.RegisterType<ViewFactory>()
            .As<IViewFactory>()
            .SingleInstance();

        builder.RegisterType<Navigator>()
            .As<INavigator>()
            .SingleInstance();

        // navigation registration
        builder.Register<INavigation>(context =>
            App.Current.MainPage.Navigation
        ).SingleInstance();
    }
  }
}

Bootstrapper.cs

  namespace FormsSample.Core
  {
   public class Bootstrapper : AutofacBootstrapper
   {
    private readonly App _application;

    public Bootstrapper(App application)
    {
        _application = application;
    }

    protected override void ConfigureContainer(ContainerBuilder builder)
    {
        base.ConfigureContainer(builder);
        builder.RegisterModule<ClientModule>();
       // builder.RegisterInstance<Func<Page>>(() => ((NavigationPage)Application.Current.MainPage).CurrentPage);
    }

    protected override void RegisterViews(IViewFactory viewFactory)
    {
        // register these with the view factory. ViewModel and View Page
        //Autofac <object class, Func<class, >
        viewFactory.Register<PersonsViewModel, PersonPageView>();
        viewFactory.Register<PersonDetailViewModel, PersonDetailViewPage>();
        viewFactory.Register<LoginPageViewModel, LoginPage>();
        viewFactory.Register<RegistrationViewModel, RegistrationPage>();
        viewFactory.Register<PhoneContactViewModel, PhoneBookPage>();
        viewFactory.Register<MainPageViewModel, MainPage>();
    }

    protected override void ConfigureApplication(IContainer container)
    {
        // set main page
        var viewFactory = container.Resolve<IViewFactory>();
        var mainPage = viewFactory.Resolve<MainPageViewModel>();

        var navigationPage = new NavigationPage(mainPage);
       _application.MainPage = navigationPage;
    }


   }
}

你说的是

When I replace my entire module using ...

当您实际用单一注册替换整个模块时,异常会自行解释。 Autofac 无法解析 MainPageViewModel,因为它尚未注册。

您必须注册您的模块和解析当前页面的函数:

builder.RegisterModule<ClientModule>();
builder.RegisterInstance<Func<Page>>(() => ((NavigationPage)Application.Current.MainPage).CurrentPage);

更新 1

根据您的最后一条评论,我希望 Bootstrapper 看起来像这样:

public class Bootstrapper
{
    public static void Run()
    {
        var builder = new ContainerBuilder();
        builder.RegisterModule<ClientModule>();
        builder.RegisterInstance<Func<Page>>(() => ((NavigationPage)Application.Current.MainPage).CurrentPage);
        var container = builder.Build();

        var page = container.Resolve<MainPage>();
        YourApp.Current.MainPage = new NavigationPage(page);
    }
}

更新 2

鉴于您的示例,我认为如果您不注释掉 ConfigureContainer 方法中的第三行,它应该可以工作:

protected override void ConfigureContainer(ContainerBuilder builder)
{
    base.ConfigureContainer(builder);
    builder.RegisterModule<ClientModule>();
    builder.RegisterInstance<Func<Page>>(() => ((NavigationPage)Application.Current.MainPage).CurrentPage);
}