MvvmCross IoC не может разрешить службу

Я следую инструкциям на YouTube для N=2: Котята и списки

KittenView взрывается, когда попадает в OnCreate()

Cirrious.CrossCore.Exceptions.MvxException: не удалось загрузить ViewModel для типа MyApp.Core.ViewModels.KittenViewModel из локатора MvxDefaultViewModelLocator

Кажется, что он не может разрешить службу (IKittenGenesisService), потому что, когда я добавляю пустой конструктор, приложение запускается без ошибок. Но очевидно, что представление не будет работать должным образом без зависимостей.

Это же решение также имеет более раннее руководство, которое включает в себя FirstViewModel, в котором используется ICalculationService. Эта служба нормально разрешается и работает, поэтому я знаю, что MVVM IoC работает. Но я не могу найти никаких различий между ними. Не помогает то, что я не могу выполнить отладку в проекте PCL, но это другая проблема.

public class App: MvxApplication
{
    public override void Initialize()
    {
        CreatableTypes()
            .EndingWith("Service")
            .AsInterfaces()
            .RegisterAsLazySingleton();
        RegisterAppStart<KittenViewModel>();
    }
}

[Activity(Label = "View for KittenViewModel")]
public class KittenView : MvxActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.KittenView);
    }
}

public class KittenViewModel: MvxViewModel
{
    public KittenViewModel(IKittenGenesisService service)
    {
        var kittenList = new List<Kitten>();
        for (var i = 0; i < 100; i++)
        {
            var newKitten = service.CreateNewKitten(i.ToString());
            kittenList.Add(newKitten);
        }
        Kittens = kittenList;
    }

    private List<Kitten> _kittens;
    public List<Kitten> Kittens
    {
        get { return _kittens; }
        set
        {
            _kittens = value;
            RaisePropertyChanged(() => Kittens);
        }
    }
}

public class KittenGenesisService: IKittenGenesisService
{
    private readonly List<string> _names;
    private readonly Random _random;

    public KittenGenesisService()
    {
        _random = new Random();
        _names = new List<string>()
        {
            "Tiddles",
            "Amazon",
            "Pepsi",
            "Solomon",
            "Butler",
            "Snoopy",
            "Harry",
            "Holly",
            "Paws"
        }; 
    }

    public Kitten CreateNewKitten(string extra = "")
    {
        return new Kitten()
            {
                Name = _names[Random(_names.Count)] + extra,
                ImageUrl = string.Format("http://placekitten.com/{0}/{0}"),
                Price = RandomPrice()
            };
    }

    public int Random(int count)
    {
        return _random.Next(count);
    }

    public int RandomPrice()
    {
        return Random(23) + 3;
    }
}

Тем не менее, они отлично работают:

[Activity(Label = "View for FirstViewModel")]
public class FirstView : MvxActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.FirstView);
    }
}

public class FirstViewModel: MvxViewModel
{
    private readonly ICalculationService _calculationService;

    public FirstViewModel(ICalculationService calculationService)
    {
        _calculationService = calculationService;
        _generosity = 20;
        _subTotal = 100;
        Recalc();
    }
    // more code
}

Вот модульный тест, который я добавил, он сразу же взрывается с нулевой ссылкой, когда пытается создать новый KittenViewModel, конструктор KittenGenesisService вызывается нормально.

[TestFixture]
public class KittenViewModelTests
{
    private KittenViewModel _sut;

    [SetUp]
    public void given_a_kittenviewmodel()
    {
        _sut = new KittenViewModel(new KittenGenesisService());
    }

    [Test]
    public void the_view_model_contains_kittens()
    {
        _sut.Kittens.Should().NotBeEmpty();
    }
}

person Ryan Langton    schedule 25.06.2013    source источник


Ответы (1)


Я думаю, что, возможно, стоит проверить некоторые основы, такие как:

  • существует ли открытый класс, который реализует сервис генезиса?
  • у него есть общедоступный конструктор без параметров? (Или конструктор, который сам может быть построен)

Если с этим все в порядке, то, вероятно, стоит попробовать некоторые методы отладки:

  • включение трассировки, чтобы вы могли видеть внутренние детали проблем - см. использование MvvmCross Mvx.Trace
  • экспериментируете с некоторым тестовым кодом в вашем app.cs - после регистрации сервисов возвращает ли Mvx.CanResolve<IKittenGenesisService>() значение true?
  • пытаясь вызвать код вашей модели представления из модульного теста - это работает нормально?
person Stuart    schedule 26.06.2013
comment
Спасибо за советы. Я добавил свой код KittenGenesisService, а также модульный тест. Он взрывается при попытке вызвать конструктор KittenViewModel. - person Ryan Langton; 26.06.2013
comment
Если это действительно взорвется, пожалуйста, опубликуйте видео - как я хотел бы посмотреть. Если вместо этого он просто выдает исключение, проверьте сообщение об ошибке исключения и строку, из которой оно выбрасывается, так как это может сказать вам, что на самом деле происходит не так... я предполагаю, что это будет FormatException, вызванное string.Format("http://placekitten.com/{0}/{0}") - person Stuart; 26.06.2013
comment
Не думайте, что это указывает на проблему, у меня есть аналогичный модульный тест для FirstViewModel, и он выдает исключение в том же месте. Что-то под обложками с mvvm не позволяет мне создать новую модель представления для модульного тестирования. - person Ryan Langton; 26.06.2013
comment
Хорошо, вы нашли проблему, это было исключение формата. Я хотел бы знать, как люди справляются с этим, хотя. Кажется излишне сложным отследить простые ошибки. Отладка не работает с PCL. Есть ли способ сделать модульные тесты? Как я уже упоминал, мои модульные тесты вообще не работают, и они не делают ничего, кроме попытки построить модель представления. - person Ryan Langton; 26.06.2013