webBG - програмисти, машинно обучение, javascript, python, php, питам, говорим, публикации

Има ли начин за динамично внедряване на интерфейсни класове на API в kotlin с bytebuddy? (модел на миксини)

Нека обобщя това, което се опитвам да постигна. По принцип искам начин да имам набор от интерфейси, които да сървърират api, които външните добавки използват за взаимодействие с двигателя.

Ето как в момента настройвам нещата.

class Engine : ApiEngine {

    override fun start() {
        println("Starting Engine")
    }

    override fun stop() {
        println("Stopping Engine.")
    }
}
interface ApiEngine {

    fun start()

    fun stop()

}

Това е тромаво и съм виждал някои други решения, използващи ASM и динамично инжектиране на интерфейса в класа "Engine". Виждал съм нещо подобно в друг източник, но никога не можах да разбера напълно как да го направя.

@Implements("ApiEngine")
class Engine {

    @Export("start")
    fun start() {
        println("Starting Engine")
    }

    @Export("stop")
    fun stop() {
        println("Stopping Engine.")
    }
}
interface ApiEngine {

    @Import("start")
    fun start()

    @Import("stop")
    fun stop()

}

Въпросът ми е в ByteBuddy възможно ли е ефективно да накарам Engine да внедри ApiEngine, така че екземпляр на Engine() да може да бъде прехвърлен към ApiEngine за използване на API?


  • Мисля, че може да искате да изберете нещо друго освен наследство. Ако всичко, което искате, е Engine да внедри ApiEngine, тогава какво ви пречи да направите това по време на компилация? 27.11.2019
  • Ако приемем, че нямате достъп до ApiEngine преди времето за компилиране и по някакъв начин успеете да промените байт-кода на екземпляра Engine, за да се държи също като ApiEngine, тогава има и проблемът да знаете какви методи има ApiEngine, за да може Engine също да предостави определения за тези методи. Моля, добавете повече подробности към въпроса си 27.11.2019
  • Ако е така, че тези външни плъгини знаят за този интерфейс, тогава може би най-добрият начин да направите това е да използвате инжектиране на зависимости, за да инжектирате екземпляр на ApiEngine в Engine. Ако наистина искате вашият Engine да се държи като ApiEngine, тогава в допълнение към DI можете да използвате вградения делегатен модел на Kotlin, за да постигнете това. Groovy също е друг език, който поддържа този вид делегиране 27.11.2019
  • smac89 Имате ли информация за това. Използвам Koin за инжектиране на зависимости и знам, че има функцията за свързване. Запазвайки модела на делегиране в kotlin, разгледах това преди, но никога не можах да намеря информация за това как да направя това. По принцип, ако имам ApiEngine интерфейс в свой собствен модул, отделен от Engine, не искам да внедрявам api модула в двигателя. Искам да са отделни. 27.11.2019
  • Това, което предлагах, беше следното: class Engine (val apiEngine: ApiEngine): ApiEngine by apiEngine и това означава, че Engine ще имплементира ApiEgine, но поради делегирането вече ще има всички свойства на ApiEngine. Не съм сигурен дали това е, което искате, защото в последния ви коментар се казва, че не искате да внедрявате API модула, но въпросът ви питаше как да прехвърлите Engine към ApiEngine. Струва ми се, че ако искате да можете да прехвърляте един към друг, имате нужда от наследяване, за да работи това и не съм сигурен каква магия ще предостави bytebuddy, за да избегне това 27.11.2019

Отговори:


1

Това е много възможно. Можете например да интегрирате Byte Buddy като инструмент за изграждане, където генерирате интерфейси при откриване. Просто внедрете интерфейса Plugin и типовете съвпадение въз основа на присъствието на вашата анотация.

Като следваща стъпка ще трябва да инструментирате тези типове, за да реализирате допълнителен интерфейс, използвайки DynamicType.Builder DSL, който Byte Buddy ви предоставя. Ако вашите методи винаги съответстват на техния подпис, няма какво повече да се направи, тъй като Byte Buddy автоматично открива тези замени. Ако сигнатурите на метода могат да варират, ще трябва да внедрите интерфейсните методи, като използвате MethodCall, за да приложите делегиране към действителното изпълнение.

28.11.2019
Нови материали

Създайте разширение за Chrome с помощта на Angular
Този урок е базиран на манифеста на разширението на chrome версия 3 (MV3), а също и на Angular версия 2+ (2, 3 и...). Ако не сте използвали манифест версия 3, можете да следвате този урок ,..

За да научите нов език за програмиране, започнете отначало
Първоначално публикувано на http://www.mberlove.com/blog/a-new-programming-language-starting-over/ Програмистите се гордеят със способността си да усвояват лесно нови умения , разчитайки..

5 Youtubers на Data Science, които трябва да следвате
Защото всички можем да се справим с малко продуктивно отлагане Всички сме падали в заешката дупка на Youtube, така че защо да не я направим продуктивна?! Като непрекъснато нарастващ източник..

Бих казал, че точно това е проблемът с Twitter — това е инструмент на суперпотребител.
Бих казал, че точно това е проблемът с Twitter — това е инструмент на суперпотребител. По същия начин, по който суперкодерът сочи vim като единствения начин за кодиране, но останалите от нас..

Основи на Gradio
Gradio е най-ефективният метод за демонстриране на вашия модел на машинно обучение и разполага с удобен за потребителя онлайн интерфейс, който го прави достъпен от всяко място. Какво прави..

Илюстрация (GIF) за обяснение на дълбоки конволюционни мрежи (DCNN)
В света на компютърното зрение най-основният и често срещан алгоритъм за разпознаване на изображения е конволюционната мрежа. С популярността на рамки като tensorflow и pytorch, стана по-лесно да..

Python Bootcamp — Data Science Day 165
Python Bootcamp от Giles McMullen-Klein беше абсолютно невероятно. Джайлс има този уникален начин да улови аудиторията си, като същевременно прави съдържанието на курса много интересно...