Зарегистрированные службы не найдены в движке DI при публикации приложения Xamarin в режиме выпуска - PullRequest
0 голосов
/ 04 июля 2018

Я пишу приложение Android Wear с использованием Xamarin. Я использую библиотеку Microsoft.Extensions.DependencyInjection для обработки внедрения зависимости сервиса в моём приложении. Он работает совершенно нормально, когда я запускаю приложение в режиме отладки через Visual Studio (Ctrl + F5) на моих реальных умных часах. Приложение работает правильно и все. Однако, когда я публикую приложение с помощью функции «Архивировать» набора инструментов Xamarin, а затем загрузил опубликованную версию в мой SmartWatch, приложение вылетает при запуске с исключением, указывающим System.InvalidOperationException: A suitable constructor for type 'My.Library.SomeManager' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.. Это порождает вызов IServiceProvider.GetService для типа SomeManager.

Я не знаю, почему это так. Я регистрируюсь в logcat, когда регистрирую службы, и вижу, что они зарегистрированы в опубликованной версии, но по какой-то странной причине механизм внедрения зависимостей не может их найти. Я не знаю достаточно о внутренней работе Xamarin, чтобы выбрать направление для устранения этой проблемы. Кто-нибудь знает, что вызвало бы это странное поведение?

1 Ответ

0 голосов
/ 04 июля 2018

Предполагается, что в вашей конфигурации выпуска для Linker установлено что-то другое , чем None?

Классы, конструкторы и / или методы, на которые ссылаются только посредством отражающих вызовов для активации и которые используются через интерфейсы (типичные для DI), не могут быть видны при статическом анализе, который выполняет Mono Linker, и, таким образом, удаляются из сборки (й). ), чтобы получить окончательный размер пакета приложения до «приемлемого» размера.

Примечание. Этот процесс сравним с инструментом Proguard, и его замена R8 используется для удаления неиспользуемого кода Java и имеет некоторые «ограничения», и большинство моих Xamarin.Android проектов заканчиваются пользовательским Mono linker и файл конфигурации Proguard / R8.

Если вы не «владеете» кодом, который удаляется, вы можете вручную ссылаться на класс / метод, чтобы компоновщик не удалял его:

[Preserve]
public static class LinkerPreserve
{
    static LinkerPreserve()
    {
        throw new Exception(typeof(My.Library.SomeManager).FullName);
    }
}

Если вы владеете кодом, вы можете применить PreserveAttribute к классу.

[Preserve]
public class SomeManager
{
    ~~~~
}

Вы также можете применить --linkskip=ASSEMBLY в опциях сборки ...

Подробнее см. В документах:

Он принимает полный контроль над процессом связывания Mono, вы можете создать собственный файл конфигурации связывания:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...