Xamarin Prism Unable to navigate to LoginPageViewModel - xamarin

I am trying to make my Xamarin Project use MVVM with Prism and DryIoc.
I mostly want to use AutoRegistration like below:
[AutoRegisterForNavigation]
...
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//Pages
containerRegistry.RegisterForNavigation<NavigationPage>();
//Services
containerRegistry.RegisterSingleton<ILocalDatabase, LocalDatabase>();
containerRegistry.RegisterSingleton<IUserProfileDataStore, UserProfileDataStore>();
containerRegistry.RegisterSingleton<IApplicationSettings, ApplicationSettings>();
containerRegistry.RegisterSingleton<ILogger, Logger>();
containerRegistry.RegisterSingleton<IApiService, ApiService>();
containerRegistry.RegisterSingleton<IUserSession, UserSession>();
containerRegistry.Register<IBrowser, BrowserImplementation>();
containerRegistry.Register<IConnectivity, ConnectivityImplementation();
containerRegistry.Register<IFileSystem, FileSystemImplementation>();
containerRegistry.Register<ICoreServices, CoreServices>();
}
I have also tried Manual Registration:
containerRegistry.RegisterForNavigation<LoginPage, LoginPageViewModel>();
Neither works, It hits the Login Page code behind then breaks with the following error:
Exception - High: Prism.Ioc.ContainerResolutionException:
An unexpected error occurred while resolving 'AppetiteApp.ViewModels.LoginPageViewModel' --->
DryIoc.ContainerException: code: UnableToResolveUnknownService; message: Unable to resolve
Resolution root AppetiteApp.ViewModels.LoginPageViewModel
with passed arguments [value(Prism.Navigation.ErrorReportingNavigationService)]
**System.NullReferenceException:** 'Object reference not set to an instance of an object.'
I've also tried using a Linker file setting it's build action to "linkdescription"
As for my Login Page here is the declaration
public LoginPageViewModel(ICoreServices coreServices)
: base(coreServices)

The constructor of LoginPageViewModel requires the ICoreServices argument which is registered.
The error message says that the LoginPageViewModel itself is unknown to the IoC - it means the type LoginPageViewModel is not directly registered and not found through dynamic registrations or unknown service resolvers.
I am not a user of the Xamarin Prism so I am not sure about its mechanism for registering the view models.
Btw, this part of error
Resolution root AppetiteApp.ViewModels.LoginPageViewModel
with passed arguments [value(Prism.Navigation.ErrorReportingNavigationService)]
basically means the view-model was resolved via the foollowing call resolver.Resolve(typeof(LoginPageViewModel), args: new[] { errorReportingNavigationService })
Hope it will help you or someone knowledgeable in Xamarin to track the error cause.

So Once I investigated Inside of ICoreServices I commented out each of the dependencies then discovered that IUserSession was the once causing problems then I dug into that and discovered that the dependences for IAppInfo and IVersionTracking were missing in the App.Xaml.cs registr tyepes so I added that and then it worked!
containerRegistry.Register<IAppInfo, AppInfoImplementation>();
containerRegistry.Register<IVersionTracking, VersionTrackingImplementation>();

Related

ACR Reactive BluetoothLE Plugin Invalid State when starting server

I am building an iOS app with Xamarin and MvvmCross the required the use of Bluetooth LE. I am trying to use this plugin:
https://github.com/aritchie/bluetoothle
Here is my code:
var server = CrossBleAdapter.Current.CreateGattServer();
await server.Start(new AdvertisementData()); // throws exception
It throws an exception when trying to start the server:
{System.ArgumentException: Invalid State - Unknown at
Plugin.BluetoothLE.Server.GattServer.Start
(Plugin.BluetoothLE.Server.AdvertisementData adData) [0x0005f] in
<4281c4bd57f24525b20baae1afdf610b>:0
Apparently this plugin is easy to use so I must be missing something obvious?
That Exception indicates that the hardware is in invalid or initializing state and can be seen here: https://github.com/aritchie/bluetoothle/blob/master/Plugin.BluetoothLE.Apple.Shared/Server/GattServer.cs#L74
if (this.manager.State != CBPeripheralManagerState.PoweredOn)
throw new ArgumentException("Invalid State - " + this.manager.State);
I believe this is a bug in the code as it does not wait for the delegate to signal that the State has changed.
I found a solution. Instead of placing the code in my Core project, I placed it inside the iOS project itself, in a ViewDidAppear function, and placed a global variable in my UIViewController class:
private IGattServer server = CrossBleAdapter.Current.CreateGattServer();
I think you need to access the adapter with the appropriate thread, or at the appropriate time (after other initialization), hence why it was crashing before. I couldn't find an appropriate place to put this in my Core project, so I'm not sure if I have to put this code in each platform. Anyhow here's a solution for anyone else with this problem.

App crashes when Link All Assemblies enabled

I am trying to reduce app size and enabled "Link All Assemblies", but my app crashes with following error
MvvmCross.Platform.Exceptions.MvxException: Failed to construct and initialize ViewModel for type Japam.Core.ViewModels.MantraasViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information
I tried
--linkskip=mvvmcross.platform.ios
--linkskip=mvvmcross.core
--linkskip=mvvmcross.platform
but no luck, kept preserve attribute at assembly level of my core pcl project.
Also added a couple of more methods in LinkerPleaseIncludefile
public void Include(MvvmCross.Platform.IoC.MvxPropertyInjection injection)
{
injection = new MvvmCross.Platform.IoC.MvxPropertyInjection();
}
public void Include(MvxDefaultViewModelLocator locator)
{
locator = new MvxDefaultViewModelLocator();
}
but no use, could somebody help me find out what is missing
MvvmCross.Platform.Exceptions.MvxException: Failed to construct and initialize ViewModel for type
Japam.Core.ViewModels.MantraasViewModel from locator
MvxDefaultViewModelLocator - check InnerException for more information
---> MvvmCross.Platform.Exceptions.MvxException: Problem creating viewModel of type MantraasViewModel --->
MvvmCross.Platform.Exceptions.MvxIoCResolveException: Failed to
construct MantraasViewModel --->
System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. --->
MvvmCross.Platform.Exceptions.MvxIoCResolveException: Failed to
resolve parameter for parameter sqliteConnectionFactory of type
IMvxSqliteConnectionFactory when creating
Japam.Core.Services.DataServices.MantraService
at MvvmCross.Platform.IoC.MvxSimpleIoCContainer.GetIoCParameterValues
(System.Type type, System.Reflection.ConstructorInfo firstConstructor)
[0x00036] in D:\git\MvvmCross\MvvmCross\Platform\Platform\IoC\
Finally I found the issue, it's SQLite problem so I added below three commands and it started working hope this helps someone else
--linkskip=MvvmCross.Plugins.Sqlite
--linkskip=SQLite-net
--linkskip=MvvmCross.Plugins.Sqlite.iOS
I should kept SQLite earlier it self my last project I did kept SQLite but forgot this time

Registering a Sitefinity Custom Membership provider

I am trying to implement a custom membership provider in Sitefinity, and have followed through the documentation at: http://docs.sitefinity.com/tutorial-create-a-custom-membership-provider
When I come to register the provider in the Sitefinity backend, I get the message The following required properties are not set: type
I have checked, double checked and checked again the namespace and class names, and can even declare a variable as the provider type in the code-behind, yet it just won't have it.
My provider is defined thus:
namespace SitefinityWebApp
{
public class WebsiteMembersProvider : MembershipDataProvider
{
public WebsiteMembersProvider()
{
//... etc
I am registering the provider in the SF backend as:
SitefinityWebApp.WebsiteMembersProvider, SitefinityWebApp
And I can go into the code behind on one of my master pages and code:
SitefinityWebApp.WebsiteMembersProvider MyTestProvider;
and indeed, the class appears in the intellisense offerings just fine.
and the project all compiles/runs fine - but SF won't let me use the custom provider! I have also tried adding the provider manually in the securityconfig.config file - similar result.
Any idea anyone?
I went through the tutorial to try it myself and ran into the same problem as you.
Are you sure that you're putting this
SitefinityWebApp.WebsiteMembersProvider, SitefinityWebApp
in the ProviderType field (and not the 'Global resource class ID' field, which is what I initially did)? It seems like that error message shows up if I remove the text from that field and attempt to save (and also when it can't resolve that type).
Otherwise, I'm not sure what else it could be, aside from maybe recycling the app pool.

MVVM-light There is already a factory registered for INavigationService

I'm trying to adjust my WP8 project from self made MVVM implementation to MVVM Light.
The application compiles without errors, but when I open my MainPage.xaml in Expression Blend, I will get this error:
Class project.Services.INavigationService is already registered. App.xaml
My ViewModelLocator.cs:
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
}
else
{
if (!SimpleIoc.Default.IsRegistered<INavigationService>())
{
SimpleIoc.Default.Register<INavigationService>(() => new NavigationService());
}
}
SimpleIoc.Default.Register<MainPage>();
SimpleIoc.Default.Register<SettingsEditViewModel>();
}
As you can see from my code comment, I've already tried the fix supposed here, but I'm still getting this error in Blend. There is no other place left where I could register the INavigationService, so what could be the problem?
Any ideas? :)
I had the same issue, and this seems to be a Visual Studio issue in combination with XAML-Designer, Static Factories/Locators and Design-Time creation of objects. However: The solutions were the following:
Register without a factory (not recommended)
SimpleIoc.Default.Register<INavigationService>();
Or if you want to use a factory, unregister before registering the factory
SimpleIoc.Default.Unregister<INavigationService>();
SimpleIoc.Default.Register<INavigationService>(() => new NavigationService());
Prevent the ViewModelLocator from being created more than once by the designer/Blend by making the constructor static
static ViewModelLocator() { ... }
The error is cumbersome but could happen in this scenario: You create objects during design-time (the ViewModelLocator within App.xaml probably) and whenever you change something in your Code, the Compiler is triggered and the ViewModelLocator gets re-created without ever unregistering the services. Therefore it will complain that in the factory has already been registered. In theory, when registering classes without factories multiple times, there should be an error as-well.
Might already be solved by now, but I think you can just solve the issue in your example case by not using the factory method override.
SimpleIoc.Default.Register<INavigationService, NavigationService>();
If you do need a factory method, then you can mix this line in with your factory method approach using the design mode check like you have been.
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<INavigationService, NavigationService>();
}
else
{
SimpleIoc.Default.Register<INavigationService>(CreateNavigationService);
}
This seems like a super old question, but after hours of googling, this is the only question that's similar to my problem, so answering here for other people.
Make sure that you have IsDataSource on your ViewModelLocator:
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
That solved my problem and my design data popped up straightaway.
Weirdly, after putting that on, all my "INavigationService is already registered" errors goes away!
Not sure why, but I only get this error when my xaml designer window is open. When I compile with it closed, the error goes away and the project is built and runs successfully.

How do I use AutofacWebTypesModule to Resolve HttpServerUtilityBase

I have the following registrations
builder.RegisterModule(new AutofacWebTypesModule());
builder.Register<MyType>(ctx =>
{
var server = ctx.Resolve<HttpServerUtilityBase>();
...
});
When I try to resolve MyType via a constructor on an Controller, I get the following exception. What am I doing wrong?
Autofac.Core.DependencyResolutionException
was unhandled by user code
Message=No scope matching the
expression
'value(Autofac.Builder.RegistrationBuilder`3+<>c__DisplayClass0[System.Web.HttpServerUtilityBase,Autofac.Builder.SimpleActivatorData,Autofac.Builder.SingleRegistrationStyle]).lifetimeScopeTag.Equals(scope.Tag)'
is visible from the scope in which the
instance was requested.
Yikes - that error message has gone all wrong :)
The problem is most likely that you're trying to resolve MyType directly from the container (as opposed to the DependencyResolver or else you're taking a dependency on it from a singleton. The HttpServerUtilityBase component can only be used in the context of a web request.
Trying to resolve it from Applicaiton_Start will also fail in IIS7 integrated pipeline mode.
HTH!
Nick

Resources