Skip to content

Commit

Permalink
Improve Hot Reload Integration (#851)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattleibow authored and PureWeen committed Apr 27, 2021
1 parent e289c34 commit 0edc29e
Show file tree
Hide file tree
Showing 17 changed files with 188 additions and 96 deletions.
19 changes: 19 additions & 0 deletions src/Core/src/Hosting/AppHost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#nullable enable

namespace Microsoft.Maui.Hosting
{
public static class AppHost
{
public static IAppHostBuilder CreateDefaultBuilder()
{
var builder = new AppHostBuilder();

builder.UseMauiServiceProviderFactory(false);

builder.UseMauiHandlers();
builder.ConfigureFonts();

return builder;
}
}
}
14 changes: 1 addition & 13 deletions src/Core/src/Hosting/AppHostBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,6 @@ public AppHostBuilder()

public IDictionary<object, object> Properties => new Dictionary<object, object>();

public static IAppHostBuilder CreateDefaultAppBuilder()
{
var builder = new AppHostBuilder();

builder.UseMauiServiceProviderFactory(false);

builder.UseMauiHandlers();
builder.ConfigureFonts();

return builder;
}

public IAppHost Build()
{
_services = _serviceCollectionFactory();
Expand Down Expand Up @@ -76,7 +64,7 @@ public IAppHost Build()

ConfigureServiceCollectionBuilders(_serviceProvider);

return new AppHost(_serviceProvider, null);
return new Internal.AppHost(_serviceProvider, null);
}

public IAppHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate)
Expand Down
44 changes: 8 additions & 36 deletions src/Core/src/Hosting/AppHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Hosting.Internal;
using Microsoft.Maui.HotReload;

namespace Microsoft.Maui.Hosting
{
Expand Down Expand Up @@ -64,6 +62,13 @@ public static IAppHostBuilder ConfigureServices<TBuilder>(this IAppHostBuilder b
return builder;
}

public static IAppHostBuilder ConfigureServices<TBuilder>(this IAppHostBuilder builder)
where TBuilder : IMauiServiceBuilder, new()
{
builder.ConfigureServices<TBuilder>((_, services) => { });
return builder;
}

public static IAppHostBuilder ConfigureAppConfiguration(this IAppHostBuilder builder, Action<IConfigurationBuilder> configureDelegate)
{
builder.ConfigureAppConfiguration((_, config) => configureDelegate(config));
Expand Down Expand Up @@ -96,40 +101,7 @@ public static IAppHostBuilder UseMauiServiceProviderFactory(this IAppHostBuilder
return builder;
}

public static IAppHostBuilder EnableHotReload(this IAppHostBuilder builder, string? ideIp = null, int idePort = 9988)
{
builder.ConfigureMauiHandlers((context, handlersCollection) =>
{
if (handlersCollection is IMauiServiceCollection mauiCollection)
MauiHotReloadHelper.Init(mauiCollection);
else
throw new NotSupportedException("Hot Reload only works with a IMauiServiceCollection");
});
Reloadify.Reload.Instance.ReplaceType = (d) =>
{
MauiHotReloadHelper.RegisterReplacedView(d.ClassName, d.Type);
};

Reloadify.Reload.Instance.FinishedReload = () =>
{
MauiHotReloadHelper.TriggerReload();
};
Task.Run(async () =>
{
try
{
var success = await Reloadify.Reload.Init(ideIp, idePort);
Console.WriteLine($"HotReload Initialize: {success}");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
});
return builder;
}

class HandlerCollectionBuilder : MauiServiceCollection, IMauiHandlersCollection, IMauiServiceBuilder
class HandlerCollectionBuilder : MauiHandlersCollection, IMauiServiceBuilder
{
public void ConfigureServices(HostBuilderContext context, IServiceCollection services)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Hosting/IMauiHandlersCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Microsoft.Maui.Hosting
{
public interface IMauiHandlersCollection : IServiceCollection
public interface IMauiHandlersCollection : IMauiServiceCollection
{
}
}
2 changes: 1 addition & 1 deletion src/Core/src/Hosting/IMauiHandlersServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Microsoft.Maui
{
public interface IMauiHandlersServiceProvider : IServiceProvider
public interface IMauiHandlersServiceProvider : IMauiServiceProvider
{
Type? GetHandlerType(Type iview);

Expand Down
8 changes: 8 additions & 0 deletions src/Core/src/Hosting/Internal/MauiHandlersCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#nullable enable

namespace Microsoft.Maui.Hosting.Internal
{
class MauiHandlersCollection : MauiServiceCollection, IMauiHandlersCollection
{
}
}
10 changes: 8 additions & 2 deletions src/Core/src/Hosting/Internal/MauiHandlersServiceProvider.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#nullable enable
using System;
using Microsoft.Maui.HotReload;

namespace Microsoft.Maui.Hosting.Internal
{
class MauiHandlersServiceProvider : MauiServiceProvider, IMauiHandlersServiceProvider
class MauiHandlersServiceProvider : MauiServiceProvider, IMauiHandlersServiceProvider, IHotReloadableHandlersServiceProvider
{
public MauiHandlersServiceProvider(IMauiServiceCollection collection)
readonly IMauiHandlersCollection _collection;

public MauiHandlersServiceProvider(IMauiHandlersCollection collection)
: base(collection, false)
{
_collection = collection;
}

public IViewHandler? GetHandler(Type type)
Expand All @@ -17,5 +21,7 @@ public MauiHandlersServiceProvider(IMauiServiceCollection collection)
=> GetHandler(typeof(T));

public Type? GetHandlerType(Type iview) => GetServiceType(iview)?.ImplementationType;

public IMauiHandlersCollection GetCollection() => _collection;
}
}
24 changes: 24 additions & 0 deletions src/Core/src/Hosting/MauiHandlersCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Microsoft.Maui.Hosting
{
Expand Down Expand Up @@ -28,5 +29,28 @@ public static IMauiHandlersCollection AddHandler<TType, TTypeRender>(this IMauiH
handlersCollection.AddTransient(typeof(TType), typeof(TTypeRender));
return handlersCollection;
}

public static IMauiHandlersCollection TryAddHandlers(this IMauiHandlersCollection handlersCollection, Dictionary<Type, Type> handlers)
{
foreach (var handler in handlers)
{
handlersCollection.TryAddTransient(handler.Key, handler.Value);
}
return handlersCollection;
}

public static IMauiHandlersCollection TryAddHandler(this IMauiHandlersCollection handlersCollection, Type viewType, Type handlerType)
{
handlersCollection.AddTransient(viewType, handlerType);
return handlersCollection;
}

public static IMauiHandlersCollection TryAddHandler<TType, TTypeRender>(this IMauiHandlersCollection handlersCollection)
where TType : IFrameworkElement
where TTypeRender : IViewHandler
{
handlersCollection.AddTransient(typeof(TType), typeof(TTypeRender));
return handlersCollection;
}
}
}
2 changes: 1 addition & 1 deletion src/Core/src/Hosting/StartupExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static IAppHostBuilder CreateAppHostBuilder(this IStartup startup)
if (startup is IAppHostBuilderStartup hostBuilderStartup)
return hostBuilderStartup.CreateAppHostBuilder();

return AppHostBuilder.CreateDefaultAppBuilder();
return AppHost.CreateDefaultBuilder();
}

public static IAppHostBuilder ConfigureUsing(this IAppHostBuilder appHostBuilder, IStartup startup)
Expand Down
66 changes: 66 additions & 0 deletions src/Core/src/HotReload/AppHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#nullable enable
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Maui.HotReload;

namespace Microsoft.Maui.Hosting
{
public static partial class AppHostBuilderExtensions
{
public static IAppHostBuilder EnableHotReload(this IAppHostBuilder builder, string? ideIp = null, int idePort = 9988)
{
builder.ConfigureServices<HotReloadBuilder>(hotReload =>
{
hotReload.IdeIp = ideIp;
hotReload.IdePort = idePort;
});
return builder;
}

class HotReloadBuilder : IMauiServiceBuilder
{
public string? IdeIp { get; set; }

public int IdePort { get; set; } = 9988;

public void ConfigureServices(HostBuilderContext context, IServiceCollection services)
{
}

public async void Configure(HostBuilderContext context, IServiceProvider services)
{
var handlers = services.GetRequiredService<IMauiHandlersServiceProvider>();
if (handlers is IHotReloadableHandlersServiceProvider hotReloadable)
MauiHotReloadHelper.Init(hotReloadable.GetCollection());
else
throw new NotSupportedException($"Hot Reload only works with a {nameof(IHotReloadableHandlersServiceProvider)}.");

Reloadify.Reload.Instance.ReplaceType = (d) =>
{
MauiHotReloadHelper.RegisterReplacedView(d.ClassName, d.Type);
};

Reloadify.Reload.Instance.FinishedReload = () =>
{
MauiHotReloadHelper.TriggerReload();
};

await Task.Run(async () =>
{
try
{
var success = await Reloadify.Reload.Init(IdeIp, IdePort);
Console.WriteLine($"HotReload Initialize: {success}");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
});
}
}
}
}
6 changes: 3 additions & 3 deletions src/Core/src/HotReload/HotReloadHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ namespace Microsoft.Maui.HotReload
{
public static class MauiHotReloadHelper
{
static IMauiServiceCollection? HandlerService;
static IMauiHandlersCollection? HandlerService;
//static IMauiHandlersServiceProvider? HandlerServiceProvider;
public static void Init(IMauiServiceCollection handlerService)
public static void Init(IMauiHandlersCollection handlerService)
{
HandlerService = handlerService;
//HandlerServiceProvider = new MauiHandlersServiceProvider(handlerService);
Expand Down Expand Up @@ -148,7 +148,7 @@ static void RegisterHandler(KeyValuePair<Type, Type> pair, Type newHandler)
var newType = newHandler;
if (pair.Value.IsGenericType)
newType = pair.Value.GetGenericTypeDefinition().MakeGenericType(newHandler);
HandlerService.AddTransient(view, newType);
HandlerService.AddHandler(view, newType);
}

public static void TriggerReload()
Expand Down
10 changes: 10 additions & 0 deletions src/Core/src/HotReload/IHotReloadableHandlersServiceProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#nullable enable
using Microsoft.Maui.Hosting;

namespace Microsoft.Maui.HotReload
{
public interface IHotReloadableHandlersServiceProvider : IMauiHandlersServiceProvider
{
IMauiHandlersCollection GetCollection();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public class GetHandlersBenchmarker
[GlobalSetup(Target = nameof(GetHandlerUsingDI))]
public void SetupForDI()
{
_host = AppHostBuilder
.CreateDefaultAppBuilder()
_host = AppHost
.CreateDefaultBuilder()
.Build();
}

Expand Down
Loading

0 comments on commit 0edc29e

Please sign in to comment.