34
34
35
35
namespace HotAvalonia
36
36
{
37
+ using global ::System ;
38
+ using global ::System . Diagnostics ;
39
+ using global ::System . Diagnostics . CodeAnalysis ;
40
+ using global ::System . IO ;
41
+ using global ::System . Reflection ;
42
+ using global ::System . Runtime . CompilerServices ;
43
+ using global ::Avalonia ;
44
+
37
45
/// <summary>
38
46
/// Indicates that the decorated method should be called whenever the associated Avalonia control is hot reloaded.
39
47
/// </summary>
@@ -60,56 +68,75 @@ namespace HotAvalonia
60
68
/// }
61
69
/// </code>
62
70
/// </remarks>
63
- [ global :: System . Diagnostics . CodeAnalysis . ExcludeFromCodeCoverage ]
64
- [ global :: System . Diagnostics . Conditional ( "ENABLE_XAML_HOT_RELOAD" ) ]
65
- [ global :: System . AttributeUsage ( global :: System . AttributeTargets . Method ) ]
66
- internal sealed class AvaloniaHotReloadAttribute : global :: System . Attribute
71
+ [ ExcludeFromCodeCoverage ]
72
+ [ Conditional ( "ENABLE_XAML_HOT_RELOAD" ) ]
73
+ [ AttributeUsage ( AttributeTargets . Method ) ]
74
+ internal sealed class AvaloniaHotReloadAttribute : Attribute
67
75
{
68
76
}
69
- }
70
-
71
- #if ENABLE_XAML_HOT_RELOAD && ! DISABLE_XAML_HOT_RELOAD
72
- namespace HotAvalonia
73
- {
74
- using global ::System ;
75
- using global ::System . Diagnostics ;
76
- using global ::System . Diagnostics . CodeAnalysis ;
77
- using global ::System . IO ;
78
- using global ::System . Reflection ;
79
- using global ::System . Runtime . CompilerServices ;
80
- using global ::Avalonia ;
81
77
82
78
/// <summary>
83
79
/// Provides extension methods for enabling and disabling hot reload functionality for Avalonia applications.
84
80
/// </summary>
85
81
[ ExcludeFromCodeCoverage ]
86
82
internal static class AvaloniaHotReloadExtensions
87
83
{
84
+ #if ENABLE_XAML_HOT_RELOAD && ! DISABLE_XAML_HOT_RELOAD
85
+ /// <summary>
86
+ /// Creates a factory method for generating an <see cref="IHotReloadContext"/>
87
+ /// using the specified control type and its XAML file path.
88
+ /// </summary>
89
+ /// <param name="controlType">The control type.</param>
90
+ /// <param name="controlFilePath">The file path to the associated XAML file.</param>
91
+ /// <returns>A factory method for creating an <see cref="IHotReloadContext"/> instance.</returns>
92
+ [ DebuggerStepThrough ]
93
+ private static Func < IHotReloadContext > CreateHotReloadContextFactory ( Type controlType , string ? controlFilePath )
94
+ {
95
+ return new Func < IHotReloadContext > ( ( ) =>
96
+ {
97
+ if ( ! string . IsNullOrEmpty ( controlFilePath ) && ! File . Exists ( controlFilePath ) )
98
+ throw new FileNotFoundException ( "The corresponding XAML file could not be found." , controlFilePath ) ;
99
+
100
+ AvaloniaProjectLocator projectLocator = CreateAvaloniaProjectLocator ( ) ;
101
+ if ( ! string . IsNullOrEmpty ( controlFilePath ) )
102
+ projectLocator . AddHint ( controlType , controlFilePath ) ;
103
+
104
+ return CreateHotReloadContext ( projectLocator ) ;
105
+ } ) ;
106
+ }
107
+
88
108
/// <summary>
89
- /// A mapping between Avalonia <see cref="Application"/> instances and their associated hot reload context.
109
+ /// Creates a factory method for generating an <see cref="IHotReloadContext"/>
110
+ /// using a custom project path resolver.
90
111
/// </summary>
91
- private static readonly ConditionalWeakTable < Application , IHotReloadContext > s_apps =
92
- new ConditionalWeakTable < Application , IHotReloadContext > ( ) ;
112
+ /// <param name="projectPathResolver">The callback function capable of resolving a project path for a given assembly.</param>
113
+ /// <returns>A factory method for creating an <see cref="IHotReloadContext"/> instance.</returns>
114
+ [ DebuggerStepThrough ]
115
+ private static Func < IHotReloadContext > CreateHotReloadContextFactory ( Func < Assembly , string ? > ? projectPathResolver )
116
+ {
117
+ return new Func < IHotReloadContext > ( ( ) =>
118
+ {
119
+ AvaloniaProjectLocator projectLocator = CreateAvaloniaProjectLocator ( ) ;
120
+ if ( ( object ? ) projectPathResolver != null )
121
+ projectLocator . AddHint ( projectPathResolver ) ;
122
+
123
+ return CreateHotReloadContext ( projectLocator ) ;
124
+ } ) ;
125
+ }
93
126
94
127
/// <summary>
95
- /// Enables hot reload functionality for the given Avalonia application .
128
+ /// Creates a hot reload context for the current environment .
96
129
/// </summary>
97
- /// <param name="app">The Avalonia application instance for which hot reload should be enabled.</param>
98
130
/// <param name="projectLocator">The project locator used to find source directories of assemblies.</param>
131
+ /// <returns>A hot reload context for the current environment.</returns>
99
132
[ DebuggerStepThrough ]
100
- private static void EnableHotReload ( Application app , AvaloniaProjectLocator projectLocator )
133
+ private static IHotReloadContext CreateHotReloadContext ( AvaloniaProjectLocator projectLocator )
101
134
{
102
- if ( ! s_apps . TryGetValue ( app , out IHotReloadContext ? context ) )
103
- {
104
135
#if ENABLE_LITE_XAML_HOT_RELOAD
105
- context = AvaloniaHotReloadContext . CreateLite ( projectLocator ) ;
136
+ return AvaloniaHotReloadContext . CreateLite ( projectLocator ) ;
106
137
#else
107
- context = AvaloniaHotReloadContext . Create ( projectLocator ) ;
138
+ return AvaloniaHotReloadContext . Create ( projectLocator ) ;
108
139
#endif
109
- s_apps . Add ( app , context ) ;
110
- }
111
-
112
- context . EnableHotReload ( ) ;
113
140
}
114
141
115
142
/// <summary>
@@ -121,106 +148,79 @@ private static AvaloniaProjectLocator CreateAvaloniaProjectLocator()
121
148
{
122
149
return new AvaloniaProjectLocator ( ) ;
123
150
}
151
+ #endif
124
152
125
153
/// <summary>
126
- /// Enables hot reload functionality for the given Avalonia application .
154
+ /// Enables hot reload functionality for the specified <see cref="AppBuilder"/> instance .
127
155
/// </summary>
128
- /// <param name="app ">The Avalonia application instance for which hot reload should be enabled .</param>
129
- /// <param name="appFilePath" >The file path of the application's main source file. Optional if the method called within the file of interest.</param >
156
+ /// <param name="builder ">The app builder instance.</param>
157
+ /// <returns >The app builder instance.</returns >
130
158
[ DebuggerStepThrough ]
131
- public static void EnableHotReload ( this Application app , [ CallerFilePath ] string ? appFilePath = null )
159
+ public static AppBuilder UseHotReload ( this AppBuilder builder )
132
160
{
133
- _ = app ?? throw new ArgumentNullException ( nameof ( app ) ) ;
134
-
135
- if ( ! string . IsNullOrEmpty ( appFilePath ) && ! File . Exists ( appFilePath ) )
136
- throw new FileNotFoundException ( "The corresponding XAML file could not be found." , appFilePath ) ;
137
-
138
- AvaloniaProjectLocator projectLocator = CreateAvaloniaProjectLocator ( ) ;
139
- if ( ! string . IsNullOrEmpty ( appFilePath ) )
140
- projectLocator . AddHint ( app . GetType ( ) , appFilePath ) ;
141
-
142
- EnableHotReload ( app , projectLocator ) ;
161
+ #if ENABLE_XAML_HOT_RELOAD && ! DISABLE_XAML_HOT_RELOAD
162
+ AvaloniaHotReload . Enable ( builder , CreateHotReloadContextFactory ( null ) ) ;
163
+ #endif
164
+ return builder ;
143
165
}
144
166
145
167
/// <summary>
146
- /// Enables hot reload functionality for the given Avalonia application .
168
+ /// Enables hot reload functionality for the specified <see cref="AppBuilder"/> instance .
147
169
/// </summary>
148
- /// <param name="app ">The Avalonia application instance for which hot reload should be enabled .</param>
170
+ /// <param name="builder ">The app builder instance.</param>
149
171
/// <param name="projectPathResolver">The callback function capable of resolving a project path for a given assembly.</param>
172
+ /// <returns>The app builder instance.</returns>
150
173
[ DebuggerStepThrough ]
151
- public static void EnableHotReload ( this Application app , Func < Assembly , string ? > projectPathResolver )
174
+ public static AppBuilder UseHotReload ( this AppBuilder builder , Func < Assembly , string ? > projectPathResolver )
152
175
{
153
- _ = app ?? throw new ArgumentNullException ( nameof ( app ) ) ;
154
-
155
- AvaloniaProjectLocator projectLocator = CreateAvaloniaProjectLocator ( ) ;
156
- projectLocator . AddHint ( projectPathResolver ) ;
157
-
158
- EnableHotReload ( app , projectLocator ) ;
159
- }
160
-
161
- /// <summary>
162
- /// Disables hot reload functionality for the given Avalonia application.
163
- /// </summary>
164
- /// <param name="app">The Avalonia application instance for which hot reload should be disabled.</param>
165
- [ DebuggerStepThrough ]
166
- public static void DisableHotReload ( this Application app )
167
- {
168
- _ = app ?? throw new ArgumentNullException ( nameof ( app ) ) ;
169
-
170
- if ( s_apps . TryGetValue ( app , out IHotReloadContext ? context ) )
171
- context . DisableHotReload ( ) ;
176
+ #if ENABLE_XAML_HOT_RELOAD && ! DISABLE_XAML_HOT_RELOAD
177
+ AvaloniaHotReload . Enable ( builder , CreateHotReloadContextFactory ( projectPathResolver ) ) ;
178
+ #endif
179
+ return builder ;
172
180
}
173
- }
174
- }
175
- #else
176
- namespace HotAvalonia
177
- {
178
- using global ::System ;
179
- using global ::System . Diagnostics ;
180
- using global ::System . Diagnostics . CodeAnalysis ;
181
- using global ::System . Reflection ;
182
- using global ::Avalonia ;
183
181
184
- /// <summary>
185
- /// Provides extension methods for enabling and disabling hot reload functionality for Avalonia applications.
186
- /// </summary>
187
- [ ExcludeFromCodeCoverage ]
188
- internal static class AvaloniaHotReloadExtensions
189
- {
190
182
/// <summary>
191
183
/// Enables hot reload functionality for the given Avalonia application.
192
184
/// </summary>
193
185
/// <param name="app">The Avalonia application instance for which hot reload should be enabled.</param>
194
186
/// <param name="appFilePath">The file path of the application's main source file. Optional if the method called within the file of interest.</param>
195
- [ Conditional ( "DEBUG " ) ]
187
+ [ Conditional ( "ENABLE_XAML_HOT_RELOAD " ) ]
196
188
[ DebuggerStepThrough ]
197
- public static void EnableHotReload ( this Application app , string ? appFilePath = null )
189
+ public static void EnableHotReload ( this Application app , [ CallerFilePath ] string ? appFilePath = null )
198
190
{
191
+ #if ENABLE_XAML_HOT_RELOAD && ! DISABLE_XAML_HOT_RELOAD
192
+ AvaloniaHotReload . Enable ( app , CreateHotReloadContextFactory ( app ? . GetType ( ) , appFilePath ) ) ;
193
+ #endif
199
194
}
200
195
201
196
/// <summary>
202
197
/// Enables hot reload functionality for the given Avalonia application.
203
198
/// </summary>
204
199
/// <param name="app">The Avalonia application instance for which hot reload should be enabled.</param>
205
200
/// <param name="projectPathResolver">The callback function capable of resolving a project path for a given assembly.</param>
206
- [ Conditional ( "DEBUG " ) ]
201
+ [ Conditional ( "ENABLE_XAML_HOT_RELOAD " ) ]
207
202
[ DebuggerStepThrough ]
208
203
public static void EnableHotReload ( this Application app , Func < Assembly , string ? > projectPathResolver )
209
204
{
205
+ #if ENABLE_XAML_HOT_RELOAD && ! DISABLE_XAML_HOT_RELOAD
206
+ AvaloniaHotReload . Enable ( app , CreateHotReloadContextFactory ( projectPathResolver ) ) ;
207
+ #endif
210
208
}
211
209
212
210
/// <summary>
213
211
/// Disables hot reload functionality for the given Avalonia application.
214
212
/// </summary>
215
213
/// <param name="app">The Avalonia application instance for which hot reload should be disabled.</param>
216
- [ Conditional ( "DEBUG " ) ]
214
+ [ Conditional ( "ENABLE_XAML_HOT_RELOAD " ) ]
217
215
[ DebuggerStepThrough ]
218
216
public static void DisableHotReload ( this Application app )
219
217
{
218
+ #if ENABLE_XAML_HOT_RELOAD && ! DISABLE_XAML_HOT_RELOAD
219
+ AvaloniaHotReload . Disable ( app ) ;
220
+ #endif
220
221
}
221
222
}
222
223
}
223
- #endif
224
224
225
225
#nullable restore
226
226
#pragma warning restore
0 commit comments