如何使用 IoC 构造函数注入 (MvvmCross (MvvmCross.Platform.Exceptions.MvxIoCResolveException))

How To Use IoC Constructor Injection (MvvmCross (MvvmCross.Platform.Exceptions.MvxIoCResolveException))

所以我对 MVVM(MvvmCross)/Android 还是个新手。如果我做的事情真的很愚蠢,请道歉。

我一直在 "MvxGeoLocation" 和 "IMvxMessenger" 上关注 Stuart Lodge 的 N=9 视频,我确信我一直在关注它,但我不知道我在哪里'我出错了。

但是我的应用程序无法从构造函数解析接口。

App.cs:

public override void Initialize()
{
    CreatableTypes()
        .EndingWith("Service")
        .AsInterfaces()
        .RegisterAsLazySingleton();

    RegisterAppStart<ViewModels.MainViewModel>();
}

MainViewModel.cs:

public MainViewModel(ILocationService locationService, IMvxMessenger messenger)
{
    _subscriptionToken = messenger.Subscribe<LocationMessage>(OnLocationMessage);
}

LocationService.cs:

Public class LocationService : ILocationService
{
    private readonly MvxLocationWatcher _locationWatcher;
    private readonly IMvxMessenger _messenger;

    public LocationService(MvxLocationWatcher locationWatcher, IMvxMessenger messenger)
    {
        _locationWatcher = locationWatcher;
        _messenger = messenger;
        if (!_locationWatcher.Started) _locationWatcher.Start(new MvxLocationOptions(), OnLocation, OnError);
    }

    private void OnLocation(MvxGeoLocation location)
    {
        System.Diagnostics.Debug.WriteLine(location.Coordinates.Longitude.ToString(), location.Coordinates.Latitude);
        var message = new LocationMessage(this, location.Coordinates.Longitude, location.Coordinates.Latitude);
        _messenger.Publish(message);
    }

    public void CustomLocation(double lng, double lat)
    {
        var message = new LocationMessage(this, lng, lat);
        _messenger.Publish(message);
    }

    private void OnError(MvxLocationError error)
    {
        Mvx.Error(error.Code.ToString());
    }
}

public class LocationMessage : MvxMessage
{
    public LocationMessage(object sender, double lng, double lat) : base(sender)
    {
        Lng = lng;
        Lat = lat;
    }

    public double Lng { get; private set; }
    public double Lat { get; private set; }
}

现在 ILocationService 接口是空的。出于国际奥委会的原因,它就在那里。现在,当我 运行 应用程序时,它在 "base.OnCreate(bundle);" 上的 MainView Activity 上崩溃。

现在在重写 InitializeIoC 方法中我什至不能 "Mvx.RegisterSingleton(new LocationService());" 因为我需要给出我显然不能给出的参数。我什至尝试使用 "Mvx.IocConstruct();",但我意识到这行不通,因为 MvvmCross 会自动执行此操作。


所以报错信息:

Failed to construct and initialize ViewModel for type Core.ViewModels.MainViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information

InnerException:

{MvvmCross.Platform.Exceptions.MvxException: Problem creating viewModel of type MainViewModel ---> MvvmCross.Platform.Exceptions.MvxIoCResolveException: Failed to resolve parameter for parameter locationService of type ILocationService when creating Core.ViewModels.MainViewModel at MvvmCross.Platform.IoC.MvxSimpleIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo firstConstructor) [0x00036] in C:\projects\mvvmcross\MvvmCross\Platform\Platform\IoC\MvxSimpleIoCContainer.cs:502 at MvvmCross.Platform.IoC.MvxSimpleIoCContainer.IoCConstruct (System.Type type) [0x0002c] in C:\projects\mvvmcross\MvvmCross\Platform\Platform\IoC\MvxSimpleIoCContainer.cs:312 at MvvmCross.Platform.Mvx.IocConstruct (System.Type t) [0x00006] in C:\projects\mvvmcross\MvvmCross\Platform\Platform\Mvx.cs:169 at MvvmCross.Core.ViewModels.MvxDefaultViewModelLocator.Load (System.Type viewModelType, MvvmCross.Core.ViewModels.IMvxBundle parameterValues, MvvmCross.Core.ViewModels.IMvxBundle savedState) [0x00000] in C:\projects\mvvmcross\MvvmCross\Core\Core\ViewModels\MvxDefaultViewModelLocator.cs:33 --- End of inner exception stack trace --- at MvvmCross.Core.ViewModels.MvxDefaultViewModelLocator.Load (System.Type viewModelType, MvvmCross.Core.ViewModels.IMvxBundle parameterValues, MvvmCross.Core.ViewModels.IMvxBundle savedState) [0x0000f] in C:\projects\mvvmcross\MvvmCross\Core\Core\ViewModels\MvxDefaultViewModelLocator.cs:37 at MvvmCross.Core.ViewModels.MvxViewModelLoader.LoadViewModel (MvvmCross.Core.ViewModels.MvxViewModelRequest request, MvvmCross.Core.ViewModels.IMvxBundle savedState, MvvmCross.Core.ViewModels.IMvxViewModelLocator viewModelLocator) [0x0000e] in C:\projects\mvvmcross\MvvmCross\Core\Core\ViewModels\MvxViewModelLoader.cs:69 }

如果需要可以提供 StackTrace。 那么我究竟做错了什么?我花了很多时间试图弄清楚这一点。没头绪。

更新:

添加 StackTrace(以防有帮助):

" at MvvmCross.Core.ViewModels.MvxViewModelLoader.LoadViewModel (MvvmCross.Core.ViewModels.MvxViewModelRequest request, MvvmCross.Core.ViewModels.IMvxBundle savedState, MvvmCross.Core.ViewModels.IMvxViewModelLocator viewModelLocator) [0x00020] in C:\projects\mvvmcross\MvvmCross\Core\Core\ViewModels\MvxViewModelLoader.cs:73 \n at MvvmCross.Core.ViewModels.MvxViewModelLoader.LoadViewModel (MvvmCross.Core.ViewModels.MvxViewModelRequest request, MvvmCross.Core.ViewModels.IMvxBundle savedState) [0x00020] in C:\projects\mvvmcross\MvvmCross\Core\Core\ViewModels\MvxViewModelLoader.cs:59 \n at MvvmCross.Droid.Views.MvxAndroidViewsContainer.ViewModelFromRequest (MvvmCross.Core.ViewModels.MvxViewModelRequest viewModelRequest, MvvmCross.Core.ViewModels.IMvxBundle savedState) [0x00006] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidViewsContainer.cs:104 \n at MvvmCross.Droid.Views.MvxAndroidViewsContainer.CreateViewModelFromIntent (Android.Content.Intent intent, MvvmCross.Core.ViewModels.IMvxBundle savedState) [0x00029] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidViewsContainer.cs:98 \n at MvvmCross.Droid.Views.MvxAndroidViewsContainer.Load (Android.Content.Intent intent, MvvmCross.Core.ViewModels.IMvxBundle savedState, System.Type viewModelTypeHint) [0x00089] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxAndroidViewsContainer.cs:67 \n at MvvmCross.Droid.Views.MvxActivityViewExtensions.LoadViewModel (MvvmCross.Droid.Views.IMvxAndroidView androidView, MvvmCross.Core.ViewModels.IMvxBundle savedState) [0x00065] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxActivityViewExtensions.cs:137 \n at MvvmCross.Droid.Views.MvxActivityViewExtensions+<>c__DisplayClass1_0.b__1 () [0x00000] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxActivityViewExtensions.cs:50 \n at MvvmCross.Core.Views.MvxViewExtensionMethods.OnViewCreate (MvvmCross.Core.Views.IMvxView view, System.Func1[TResult] viewModelLoader) [0x00012] in C:\projects\mvvmcross\MvvmCross\Core\Core\Views\MvxViewExtensionMethods.cs:28 \n at MvvmCross.Droid.Views.MvxActivityViewExtensions.OnViewCreate (MvvmCross.Droid.Views.IMvxAndroidView androidView, Android.OS.Bundle bundle) [0x00068] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxActivityViewExtensions.cs:50 \n at MvvmCross.Droid.Views.MvxActivityAdapter.EventSourceOnCreateCalled (System.Object sender, MvvmCross.Platform.Core.MvxValueEventArgs1[T] eventArgs) [0x00000] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxActivityAdapter.cs:80 \n at (wrapper delegate-invoke) System.EventHandler1[MvvmCross.Platform.Core.MvxValueEventArgs1[Android.OS.Bundle]]:invoke_void_object_TEventArgs (object,MvvmCross.Platform.Core.MvxValueEventArgs1<Android.OS.Bundle>)\n at MvvmCross.Platform.Core.MvxDelegateExtensionMethods.Raise[T] (System.EventHandler1[TEventArgs] eventHandler, System.Object sender, T value) [0x00000] in C:\projects\mvvmcross\MvvmCross\Platform\Platform\Core\MvxDelegateExtensionMethods.cs:21 \n at MvvmCross.Platform.Droid.Views.MvxEventSourceActivity.OnCreate (Android.OS.Bundle bundle) [0x00014] in C:\projects\mvvmcross\MvvmCross\Platform\Droid\Views\MvxEventSourceActivity.cs:34 \n at MvvmCross.Droid.Views.MvxActivity.OnCreate (Android.OS.Bundle bundle) [0x00000] in C:\projects\mvvmcross\MvvmCross\Droid\Droid\Views\MvxActivity.cs:92 \n at Droid.Views.MainView.OnCreate (Android.OS.Bundle bundle) [0x00001] in /Users/jaydeephasmukhlal/Projects/LocationMessengerTest/Droid/Views/MainView.cs:13 \n at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in :0 \n at (wrapper dynamic-method) System.Object:e63afbc8-7ae5-4091-981d-084af38f92fc (intptr,intptr,intptr)"

您正在 LocationService 构造函数 MvxLocationWatcher 中使用具体类型。这应该是 IMvxLocationWatcher,然后 IoC 将根据平台为您注入具体的 class(请记住还要在所有平台上安装位置插件)。您可以查看 MvvmCross Location Plugin docs 了解更多信息。

切换这个:

public LocationService(MvxLocationWatcher locationWatcher, IMvxMessenger messenger)

对此:

public LocationService(IMvxLocationWatcher watcher, IMvxMessenger messenger)

好吧,我终于得到了前辈的帮助,发现了我犯的愚蠢错误。我的界面 class ILocationService 实际上是 class 而不是界面。

示例 ILocationService 是:

public class ILocationService
{
}

而不是:

public interface ILocationService
{
}

因此,将 class 更改为接口解决了问题。这就是它无法初始化 ILocationService 的原因。