Laden...

Injecten von Services in .MAUI Blazor

Erstellt von Alesia vor einem Jahr Letzter Beitrag vor einem Jahr 739 Views
A
Alesia Themenstarter:in
15 Beiträge seit 2022
vor einem Jahr
Injecten von Services in .MAUI Blazor

Hallo zusammen,

gibt es einen Weg bei einem Hybrid Projekt, dass auf Shared Ressourcen zugreift, einen @inject Service Plattformabhängig zu definieren?

Ich habe einen DialogService der nur auf mobilen Geräten verfügbar ist und dort die nativen MAUI Funktionen nutzt.
Starte ich das Projekt jetzt im Browser, funktioniert natürlich die Seite mit dem jeweiligen Service @inject nicht mehr, da dies nicht in der Program.cs referenziert werden kann.

Ein Javascript Inject habe ich bereits, der abfängt ob ich mich auf Mobil oder Desktop bewege.
Ein "einfach Gedachter" Ansatz war das ganze im @Code Block abzufangen innerhalb der benötigten Funktion.
Da ich jedoch relativ neu mit Blazor arbeite, verstehe ich noch nicht so eine Menge davon.


    async void findAnschrift()
    {
        if (ansSuchBeg is not null)
        {
            var result = anschriftService.GetAnschriften(ansSuchBeg);
            anschriften = result;
        }
        else
        {
            if (isDevice == "mobile")
            {
                await DialogService.DisplayAlert("Kein Suchbegriff", "Bitte einen Suchbegriff eingeben", "OK");
            }
        }
    }

Geht leider nicht.
Der zweite Ansatz war die OnInitialized


    protected async override void OnInitialized()
    {
        base.OnInitialized();
        mobile = await jsRuntime.InvokeAsync<bool>("isDevice");
        isDevice = mobile ? "Mobile" : "Desktop";
        if (isDevice == "mobile")
        {
            @inject IDialogService DialogService
        }
    }

Leider geht das auch nicht.
Scheint mir so als ob es egal ist wo das @inject steht, es wird sofort beim laden der Seite bearbeitet ohne Code zu beachten.
Hab irgendwie dazu auch nichts bei Onkle Google gefunden.

P
441 Beiträge seit 2014
vor einem Jahr

Ohne einen Service registriert zu haben, wird dir beim erstellen der Component eine Exception erscheinen.
Du könntest einfach einen DesktopDialogService implementieren, der einfach nichts macht (oder das Äquivalent von den Dialogen auf Desktop Ebene darstellt).

C
55 Beiträge seit 2020
vor einem Jahr

Hallo Alesia

Wenn man mal davon absieht, dass du den DialogService im if Block zwar anlegst aber nicht zuweist, kann dein Code eigentlich auch nicht in den if Block gelangen da:


isDevice = mobile ? "Mobile" : "Desktop";
if (isDevice == "mobile")

niemals true sein wird, da die strings unterschiedlich sind. Einmal wird 'Mobile' groß geschieben und in der nächsten Zeile klein und dabei ist noch nicht einmal berücksichtig dein Umgang mit strings an dieser Stelle nicht gerade Optimal ist.
Zusätzlich kommt hinzu, dass dein DialogService nur im if Block gültig ist und sonst gibt es diesen nirgends. In C# werden Dependencies meistens über den Klassen Konstruktor als Parameter injected und in eine Klassenvariable gespeichert, dazu muss die Dependency in einem Dependency Container, wie Papst erwähnt hat, registriert werden.

Grüße

2.079 Beiträge seit 2012
vor einem Jahr

..., deshalb ein Enum für sowas 😉

In C# werden Dependencies meistens über den Klassen Konstruktor als Parameter injected

Nicht in Blazor - nicht nur zumindest.
Da gibt es das InjectAttribute, was Property injection aktiviert.
Constructor injection ist bei Komponenten standardmäßig nicht möglich.
Ändern kann man das, indem man seinen eigenen IComponentenActivator erstellt und im Container registriert, der Default ist ziemlich simpel: DefaultComponentActivator. Einfach einen IServiceContainer im Konstruktor entgegen nehmen und anstelle des Activators die ActivatorUtilities nutzen.

Wie das bei MAUI mit Blazor aussieht, weiß ich nicht, aber vermutlich genauso.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

A
Alesia Themenstarter:in
15 Beiträge seit 2022
vor einem Jahr

Hallo zusammen,

Danke für die Antworten erstmal.

Was Papst schreibt, ist so nicht Abbildbar, da die Klasse im Web auf Modal basiert und auf Native mit DisplayAlert greift.
Jedoch habe ich nen weg über den Javascript Inject mit Alert() gefunden das zu lösen.
War jedoch auch nicht die beste Entscheidung das so zu splitten.

Ich hab gestern mal ein umfangreiches Tutorial noch angeschaut, was meine Grundlagen von Blazor in ein deutlich anderes Licht gerückt hat.
Wen es interessiert: CodingDroplet auf Youtube, der hat da was für C# and Blazor.
Er deckt so in der Basis alles ab, was ich mich grundsätzlich gefragt und die letzten paar Tage mit rumgeärgert habe.
Natürlich war dabei auch der Lernfaktor deutlich höher als bei Onkel google den ganzen Tag alte Beiträge zu lesen, wo jeder anders an die Sache rangeht.

Bin gerade dabei meine WinForms App eben umzuschreiben, hab aber erst angefangen.
Ich werde auf Basis des Tutorials nochmal neu aufbauen und schauen wie weit mich da der Weg trägt 🙂

2.079 Beiträge seit 2012
vor einem Jahr

Ich hab mir deine Frage nochmal durchgelesen.

Du hast einen Service per Dependency Injection, den es nur auf Mobile-Geräten gibt?
Also beim Aufbau des Containers wird dieser Service nur für Mobile-Geräte registriert?

Was hinter dich daran, diesen Service auch für alle anderen Geräte zu registrieren, zur Not eine Dummy-Implementierung, die nichts tut? Stichwort Null object pattern
Oder Du rufst den Service optional ab, das geht über den Constructor (Parameter muss optional sein), mit Inject weiß ich nicht.
Oder Du registrierst eine Func<IMyService>, die den Service abruft und die Func rufst Du nur für Mobile-Geräte ab.

JavaScript brauchst Du dafür ganz sicher nicht.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.