MobileBlazorBindings icon indicating copy to clipboard operation
MobileBlazorBindings copied to clipboard

Is it possible to control the hosting environment in a MBB hybrid app?

Open TheCakeMonster opened this issue 4 years ago • 6 comments
trafficstars

There is some code in the BlazorWebHost class to change behaviour by environment, but I can't find any way to control the environment in which the application considers itself to be running. To be specific, I can't see any way to set HostingEnvironment.EnvironmentName.

As far as I can see, no environment variables are being added, for example - presumably because environment variables are not available in some hosts and/or not considered a sufficiently secure way to switch behaviours on a client-side app.

I can't see any way to customise this behaviour by specifying an environment for those people who consider it an acceptable risk. There doesn't seem to be any way to add a call to the ConfigureHostConfiguration method of the underlying HostBuilder instance being used prior to its CreateDefaultBuilder method having completed, and the setup of the environment being too late to affect most of the behaviours you would expect to be able to control.

Am I missing a hook that allows us to specify the environment in which a MBB host app is running somehow?

I think this is a limitation of Xamarin rather than anything else, but I'd appreciate people's thoughts on the security and other aspects associated with this feature, as well as ideas on how it might be managed.

TheCakeMonster avatar Feb 26 '21 12:02 TheCakeMonster

Having thought about this some more, I'm wondering if a sensible approach might be to add hooks to allow it to be controlled through conditional compilation of the host application.

If you added just enough hooks into the BlazorWebHost and MobileBlazorBindingsHost classes to enable the environment to be set by conditional compilation (debug versus release, for example) then people would have a modicum of control for their development needs without exposing a significant security risk. Accompanying documentation would be needed to highlight the risk of controlling the environment by anything other than conditional compilation - unless Xamarin Forms developers already have a secure way of doing this somehow?

TheCakeMonster avatar Feb 26 '21 12:02 TheCakeMonster

You can set the environment in App.cs like this:

using Microsoft.Extensions.Hosting;
...
            var hostBuilder = MobileBlazorBindingsHost.CreateDefaultBuilder()
                .UseEnvironment("staging123") // Set this to whatever you want
                .ConfigureServices((hostContext, services) =>
                { ... }

And then you can read the environment by getting the IHostEnvironment service from DI:

@inject Microsoft.Extensions.Hosting.IHostEnvironment Env 

<h1>Current env: @Env.EnvironmentName</h1>

image

The default is always "Production" because that is the safe default setting. You can then set up your app to use different environments in different configurations either from code (as seen above), or using env variables (where supported), or any other configuration pattern.

Eilon avatar Feb 26 '21 17:02 Eilon

Ah, that's great. Thanks. Sorry, I missed that completely.

I'll add some conditional compilation to enable me to switch by build configuration, so that moves me forward a bit.

However, I think I am right in saying that this needs to come after the MobileBlazorBindingsHost.CreateDefaultBuilder() method call, which means the environment gets changed after the BlazorWebHost.CreateDefaultBuilder() method has completed. As a result, things like the loading of environment-specific settings files that is done in BlazorWebHost.CreateDefaultBuilder() will already have completed - using the hard-coded environment.

It seems that you can affect the environment name just slightly too late. I wonder if a similar static method needs to be added to MobileBlazorBindingsHost as well, and then used to customise BlazorWebHost before the call to its CreateDefaultBuilder() method.

TheCakeMonster avatar Feb 26 '21 18:02 TheCakeMonster

Oh I think I see. You're saying that even though you can set the environment name with this API, it happens too late for some built-in features done by the BlazorWebHost that have already run?

Eilon avatar Feb 26 '21 19:02 Eilon

BTW most of what's done in BlazorWebHost is "deferred" in the sense that it's defining method callbacks up front, but they don't run until "later." I'll have to test this to see if the order is already correct. (Just looking at the code can be deceptive!)

Eilon avatar Feb 26 '21 19:02 Eilon

@Eilon yep, I think you've managed to struggle through my gibberish and get to the core of the problem: I think there's an issue with the order of execution.

I know exactly what you mean about deferred execution; anything to do with delegates can be, erm, lets say "cerebrally challenging." With delegates you are defining code that will run in the future. I understand anyone who complains that their head hurts when that is happening! However, in this case, I think the calls to the CreateDefaultBuilder() methods are regular method calls, and chained, and as a result they are not affected by the deferred execution of the delegates in this area of the code.

If your machine is set up to do so easily, setting a breakpoint on line 34 of BlazorWebHost.cs and then trying to hit it would tell us one way or another. I don't think it would be possible to execute that line of code, as the code is structured at the moment.

But there be delegates, and they be like (future) dragons, so I make no promises!

TheCakeMonster avatar Feb 26 '21 19:02 TheCakeMonster