Daddoon / BlazorMobile

Create full C# driven hybrid-apps for iOS, Android, UWP & Desktop with Blazor!
MIT License
413 stars 55 forks source link

Register a different service implementation per platform #231

Open egarim opened 3 years ago

egarim commented 3 years ago

Hi is there any example on how to have different implementations of services for xamarin forms and for blazor web ?

here is the case I want to solve, I have implemented authentication in my BlazorMobile Application, so how I need to store authentication token in a different way on each platform

Daddoon commented 3 years ago

What is the blocking thing you encountered at Xamarin level ?

I mean, what prevent you to register your own Services implementation per platform in addition to the interop layer ? I mean, just by following the basic dependency injection tutorial would be sufficient in my opinion: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction

You may just have to register your "platform" specific service in the platform specific project in order to access the API specific code, but it would be just sufficient. You would call it through DependencyService.Get on your Xamarin.Forms project (where the interop is), and then call your platform specific method implementation.

egarim commented 3 years ago

Hi, @Daddoon thanks for your answer, maybe I'm implementing in the wrong place, this is my project structures

BlazorMobileAuth BlazorMobileAuth.Android BlazorMobileAuth.AppPackage BlazorMobileAuth.Blazor BlazorMobileAuth.Blazor.Server BlazorMobileAuth.Common BlazorMobileAuth.Desktop BlazorMobileAuth.iOS BlazorMobileAuth.UWP

so far I have implemented the authentication service in the services folder on the BlazorMobileAuth.Blazor

https://github.com/egarim/BlazorMobileAuth/tree/master/BlazorMobileAuth.Blazor/Services

I instantiate the services in this file

https://github.com/egarim/BlazorMobileAuth/blob/master/BlazorMobileAuth.Blazor/Program.cs

this is how I'm storing my authentication token

https://github.com/egarim/BlazorMobileAuth/blob/master/BlazorMobileAuth.Blazor/Services/LocalStorageService.cs

in that service, I'm using local storage to save the user information

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

I thought that was going to work even on mobile but it does not

I think that my current implementation on the service folder https://github.com/egarim/BlazorMobileAuth/tree/master/BlazorMobileAuth.Blazor/Services might be in the wrong place, maybe the right place to define the services is this project

BlazorMobileAuth.Common

and then do the implementation for xamarin forms on this project

BlazorMobileAuth

and blazor web on this project

BlazorMobileAuth.Blazor.Server

my project is public so if you need to see my current implementation this is the address

https://github.com/egarim/BlazorMobileAuth

Daddoon commented 3 years ago

The fact that localstorage does not works on BlazorMobile is by Design. Maybe a bad decision on my side, but everything is cleared at app boot for the web storage/cache/cookie, for the app.

Short story, PWA was not present a long time ago, and also, i was having some caching issues on UWP, so i decided to consider that everything must be wiped out at app start.

So the Mobile implementation would be instead on the Native side, where you have full control on what should behave.

Anyway, you shoud declare and register your "specific" platform services at the beginning of your platform specific projects, before the Xamarin.Forms shared project is loaded.

So in:

BlazorMobileAuth.Android BlazorMobileAuth.Blazor.Server (Just for debugging purpose, on Startup.cs) BlazorMobileAuth.Desktop BlazorMobileAuth.iOS BlazorMobileAuth.UWP

Implement a shared service interface in the Xamarin.Forms project (as an example), and create your platform specific code implementation with this interface on each platform project. Then register it.

Then just interop between BlazorWeb and the native side (did you have created a specific method for this communication yet ?), and then call from the interop service class the platform specific service for the storage.

Sorry, i don't have enough time (for now) to write you a full example, but i mean, if you follow the BlazorMobile doc about interop communication and how to dependency injection from the Microsoft doc it should be enough. Of course maybe implement a way to store the data on the Device, but it's then up to your personnal choice (SQLite, file etc.).

Also on a side note, Mobile Blazor Bindings project (from Microsoft) is supporting more and more OS support. You may also take this route in consideration, as it now do the same kind of things like this project, just the way to implement is different.

Don't know yet if UWP is available on it, i know that they are planning to target it with some kind of Desktop pack in a near future. But iOS and Android implementation is here.