How do you initialize theMvvmCross SQLite plugin

2019-09-05 15:53发布

I am creating a MvvmCross application that requires a DB. I have been following the N+1 KittenDB example. I no not understand how the initializer for the DataStore ever gets called. I have noted the initializer for the FirstViewModel has it as a parameter.

I run my code and I get

Unhandled Exception:
Cirrious.CrossCore.Exceptions.MvxException: Failed to construct and initialise ViewModel for type VrWizard.Core.FirstViewModel

My Initializer is

private IRepository _repository;
public FirstViewModel(IRepository repository)
{
    _repository  = repository;

}

Repository is the my version of the DataStore:

public Repository(ISQLiteConnectionFactory factory)
{
    _connection = factory.Create ("vrwizard.sql");
    CreateTables ();
}

How do I initialize the Repository?

Don French

Added 9/23

Tis is a stack trace of the error on Android. I get the same error on iPhone.

mvx:Diagnostic:  1.95 Creating ViewModel for ActionMain
[mvx]   2.07 Problem creating viewModel of type FirstViewModel - problem MvxException: Failed to resolve parameter for parameter factory of type ISQLiteConnectionFactory when creating VrWizard.Core.Services.DataStore.RepositoryService
[mvx]     at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo firstConstructor) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.IoCConstruct (System.Type type) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.Mvx.IocConstruct (System.Type t) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxLazySingletonCreator.get_Instance () [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxTypeExtensions+<>c__DisplayClass43.<RegisterAsLazySingleton>b__42 () [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer+ConstructingSingletonResolver.Resolve () [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.InternalTryResolve (System.Type type, ResolveOptions resolveOptions, System.Object& resolved) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.InternalTryResolve (System.Type type, System.Object& resolved) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.TryResolve (System.Type type, System.Object& resolved) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo firstConstructor) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.IoCConstruct (System.Type type) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.CrossCore.Mvx.IocConstruct (System.Type t) [0x00000] in <filename unknown>:0 
[mvx]   at Cirrious.MvvmCross.ViewModels.MvxDefaultViewModelLocator.TryLoad (System.Type viewModelType, IMvxBundle parameterValues, IMvxBundle savedState, IMvxViewModel& viewModel) [0x00000] in <filename unknown>:0 
mvx:Warning:  2.07 Problem creating viewModel of type FirstViewModel - problem MvxException: Failed to resolve parameter for parameter factory of type ISQLiteConnectionFactory when creating VrWizard.Core.Services.DataStore.RepositoryService
      at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo firstConstructor) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.IoCConstruct (System.Type type) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.Mvx.IocConstruct (System.Type t) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxLazySingletonCreator.get_Instance () [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxTypeExtensions+<>c__DisplayClass43.<RegisterAsLazySingleton>b__42 () [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer+ConstructingSingletonResolver.Resolve () [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.InternalTryResolve (System.Type type, ResolveOptions resolveOptions, System.Object& resolved) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.InternalTryResolve (System.Type type, System.Object& resolved) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.TryResolve (System.Type type, System.Object& resolved) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo firstConstructor) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.IoCConstruct (System.Type type) [0x00000] in <filename unknown>:0 
  at Cirrious.CrossCore.Mvx.IocConstruct (System.Type t) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.ViewModels.MvxDefaultViewModelLocator.TryLoad (System.Type viewModelType, IMvxBundle parameterValues, IMvxBundle savedState, IMvxViewModel& viewModel) [0x00000] in <filename unknown>:0 
[MonoDroid] UNHANDLED EXCEPTION: Cirrious.CrossCore.Exceptions.MvxException: Failed to construct and initialise ViewModel for type VrWizard.Core.FirstViewModel from locator MvxDefaultViewModelLocator - check MvxTrace for more information
[MonoDroid] at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest,Cirrious.MvvmCross.ViewModels.IMvxBundle,Cirrious.MvvmCross.ViewModels.IMvxViewModelLocator) <0x00148>
[MonoDroid] at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest,Cirrious.MvvmCross.ViewModels.IMvxBundle) <0x0006b>
[MonoDroid] at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.DirectLoad (Cirrious.MvvmCross.ViewModels.IMvxBundle,System.Type) <0x0008b>
[MonoDroid] at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.Load (Android.Content.Intent,Cirrious.MvvmCross.ViewModels.IMvxBundle,System.Type) <0x000ab>
[MonoDroid] at Cirrious.MvvmCross.Droid.Views.MvxActivityViewExtensions.LoadViewModel (Cirrious.MvvmCross.Droid.Views.IMvxAndroidView,Cirrious.MvvmCross.ViewModels.IMvxBundle) <0x00137>
[MonoDroid] at Cirrious.MvvmCross.Droid.Views.MvxActivityViewExtensions/<>c__DisplayClass3.<OnViewCreate>b__1 () <0x00027>
[MonoDroid] at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate (Cirrious.MvvmCross.Views.IMvxView,System.Func`1<Cirrious.MvvmCross.ViewModels.IMvxViewModel>) <0x00053>
[MonoDroid] at Cirrious.MvvmCross.Droid.Views.MvxActivityViewExtensions.OnViewCreate (Cirrious.MvvmCross.Droid.Views.IMvxAndroidView,Android.OS.Bundle) <0x001d7>
[MonoDroid] at Cirrious.MvvmCross.Droid.Views.MvxActivityAdapter.EventSourceOnCreateCalled (object,Cirrious.CrossCore.Core.MvxValueEventArgs`1<Android.OS.Bundle>) <0x000f7>
[MonoDroid] at (wrapper delegate-invoke) System.EventHandler`1<Cirrious.CrossCore.Core.MvxValueEventArgs`1<Android.OS.Bundle>>.invoke_void__this___object_TEventArgs (object,Cirrious.CrossCore.Core.MvxValueEventArgs`1<Android.OS.Bundle>) <0x000ab>
[MonoDroid] at Cirrious.CrossCore.Droid.Views.MvxDelegateExtensionMethods.Raise<Android.OS.Bundle> (System.EventHandler`1<Cirrious.CrossCore.Core.MvxValueEventArgs`1<Android.OS.Bundle>>,object,Android.OS.Bundle) <0x0004b>
[MonoDroid] at Cirrious.CrossCore.Droid.Views.MvxEventSourceActivity.OnCreate (Android.OS.Bundle) <0x00033>
[MonoDroid] at VrWizard.Droid.FirstView.OnCreate (Android.OS.Bundle) <0x0001b>
[MonoDroid] at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x0005b>
[MonoDroid] at (wrapper dynamic-method) object.23d26989-db28-4670-bfbb-658531972ead (intptr,intptr,intptr) <0x00043>
[mono] 
[mono] Unhandled Exception:
[mono] Cirrious.CrossCore.Exceptions.MvxException: Failed to construct and initialise ViewModel for type VrWizard.Core.FirstViewModel from locator MvxDefaultViewModelLocator - check MvxTrace for more information
[mono]   at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0 
[mono]   at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0 
[mono]   at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.DirectLoad (IMvxBundle savedState, System.Type viewModelTypeHint) [0x00000] in <filename unknown>:0 
[mono]   at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.Load (Android.Content.Intent intent, IMvxBundle savedState, System.Type viewModelTypeHint) [0x00000] in <filename unknown>:0 
[mono]   at Cirrious.MvvmCross.Droid.Views.
[mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: Cirrious.CrossCore.Exceptions.MvxException: Failed to construct and initialise ViewModel for type VrWizard.Core.FirstViewModel from locator MvxDefaultViewModelLocator - check MvxTrace for more information
[mono-rt]   at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator) [0x00000] in <filename unknown>:0 
[mono-rt]   at Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel (Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState) [0x00000] in <filename unknown>:0 
[mono-rt]   at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.DirectLoad (IMvxBundle savedState, System.Type viewModelTypeHint) [0x00000] in <filename unknown>:0 
[mono-rt]   at Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.Load (Android.Content.Intent intent, IMvxBundle savedState, System.Type viewModelTypeHint) [0x00000] in <filename unknown>:0 
[mono-rt]   at Cirrious.MvvmCross

4条回答
狗以群分
2楼-- · 2019-09-05 16:39

For your specific case:

You could simply add a line to Initialize in your App.cs to allow you to Register your Repository class as providing a singleton IRepository instance:

     Mvx.ConstructAndRegisterSingleton<IRepository, Repository>(); 

MvvmCross would then create your Repository using an ISQLiteConnectionFactory from the plugin, and it would store that IRepository reference.

This would then allow MvvmCross to later create your FirstViewModel


For a more general answer:

This area of 'service construction' is often referred using terms like 'Inversion of Control', 'Service Location' and 'Dependency Injection'.

MvvmCross provides a static helper class Mvx which provides mechanisms to allow you to Register and Resolve classes and instances.

These mechanisms include:

  • RegisterSingleton<IMyInterface>(new MyThing()) which allows you to register an instance of a class as the one-and-only-thing that will implement a particular interface.
  • Resolve<IMyInterface>() which finds and returns what has been registered for a particular interface
  • IoCConstruct<MyClass>() which will create an instance of the requested class using Resolve to fill in any interface references required for its public constructor.

Plugins - like SQLite-Net - sit on top of this layer and use Register mechanisms to make services available for application code to use.

One other commonly used option is that your application code can also choose to Register one or more bulk sets of classes using a naming convention - which is why you will often see a block in App.cs like:

    CreatableTypes()
        .EndingWith("Service")
        .AsInterfaces()
        .RegisterAsLazySingleton(); 

This block simply means "find classes with names ending in Service and then register them according to the interfaces they implement". Note that Service is just a postfix word here - you can easily use a different naming convention by changing the EndingWith line.

This block is included in the Kittens sample - and its KittenGenesisService and DataService classes rely on this block for their construction - see:


For more information:

查看更多
劫难
3楼-- · 2019-09-05 16:44

That is only Because of you have not added the NuGet package of SQLite in the Project which is Containing the View,(Means Windows Phone 8 Project)

查看更多
家丑人穷心不美
4楼-- · 2019-09-05 16:49

Yes check your UI project closely. You need to include the same mvvm packages in them as in your core project. I was working with monotouch layer today and getting this error. As soon as I added the SQLite plugin to the Touch UI my problems were resolved.

查看更多
ら.Afraid
5楼-- · 2019-09-05 16:52

A few tips that might have been overlooked (they are in Stuart's examples):

  • somewhere the Sqlite plugin must be initialized, look for the bootstrap classes.

    using Cirrious.CrossCore.Plugins;

    namespace myapp.UI.Android.Bootstrap
    {
        public class SqlitePluginBootstrap
            : MvxPluginBootstrapAction<Cirrious.MvvmCross.Plugins.Sqlite.PluginLoader>
        {
        }
    }
    

Second, check the error more thoroughly. Most of the time more info is provided, which parameter could not be constructed.

Third: constructing multiple instances of your service could lead to errors under certain circumstances of Sqlite settings.

Hope this helps you to getting started.

查看更多
登录 后发表回答