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);
}
大家好,我正在使用 Autofac 作为我的 DI 代码库,我正在遵循此解决方案
在那个解决方案中我对此有点困惑
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);
}