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

时间:2016-08-01 08:52:43

标签: xamarin xamarin.forms autofac xamarin-studio

嘿大家我正在使用Autofac作为我的DI代码库我遵循此解决方案Using Navigation in MasterDetailPage with Autofac and Xamarin.Forms因为tabbedPage中的Press按钮无法导航到下一页或链接页面。在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;
    }


   }
}

1 个答案:

答案 0 :(得分:0)

你在说

  

当我用...替换整个模块时

当您使用单个注册实际替换整个模块时,异常会自行解释。 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);
}