-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi-Project solution support #7
Comments
Hello! As stated in the README:
So, yes, there are definitely plans to add proper support for referenced projects. The only thing that's missing here is establishing a relevance between a given referenced control assembly and its source project location. For instance, if you were to manually do something like this: var context = AvaloniaHotReloadContext.FromAsembly(typeof(MyControl).Assembly, "/path/to/project/root/");
context.EnableHotReload(); // Note: the context needs to be saved somewhere, so the GC doesn't throw it away. It should already work. I just haven't found an elegant way to:
Also, if you (or somebody else) would make a PR that moves some controls from the Demo app to another project for testing/demonstration purposes - that would be nice! :) |
Thanks for the quick response. I tried to make it work in my app but it doesn't do anything :( Need to dig further in when I have time. I would be happy with the ability to specify projects manually like you described. I'm wondering why hot reload isn't working for me at all. I guess there's no logging/tracing which can be enabled, right? |
It worked well for me, and fortunately it appears this can happen after AvaloniaXamlLoader.Load(this), as my plugin system wouldn't have kicked in by then. Here is what I ended up doing private void SetupHotReload()
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
string? path = TryLocateAssembly(assembly);
if (path is null)
{
continue;
}
AvaloniaHotReloadContext context = AvaloniaHotReloadContext.FromAssembly(assembly, path);
context.EnableHotReload();
contexts.Add(context);
}
}
private string? TryLocateAssembly(Assembly assembly, [CallerFilePath] string? appFilePath = null)
{
if (appFilePath is null)
{
return null;
}
string? assemblyName = assembly.GetName().Name;
if (assemblyName is null || assemblyName.StartsWith("System."))
{
return null;
}
Uri root = new(Path.Combine(appFilePath, "../../.."));
foreach (string project in Directory.EnumerateFiles(root.LocalPath, "*.csproj", SearchOption.AllDirectories))
{
if (Path.GetFileNameWithoutExtension(project) == assemblyName)
{
return Path.GetDirectoryName(project);
}
}
return null;
} (NOTE: This cannot be combined with .EnableHotReload() on the app, or else you'll get an ExecutionEngineException) Usage is to call SetupHotReload at the end of my OnFrameworkInitializationCompleted. You'll have to alter how TryLocateAssembly works as that was just a quick hack to make it work my project layout. |
@StefanKoell, do you have an MRE I can check? If hot reload doesn't work for you at all, it may be worth opening a separate issue!
Welp, not really. I've added logging here and there, but only where something could actively go wrong. So, if you don't see any errors in the debug output, it means there were none. Are you trying to debug a regular desktop app? What kind of code editor/IDE do you use? Have you tried if hot reload works when saving a file via a basic notepad of some kind?
@ClxS, yeah, looks about right for a personal setup. Don't forget to wrap this with
This is not a hard requirement. The only thing is HotAvalonia needs to be initialized before a control is created so that it can be hot reloaded as is. If control(s) are initialized before that, HotAvalonia won't know that they exist until they are rebuilt (e.g., by closing and then opening a containing view again).
You cannot create the
That's why this feature isn't built into HotAvalonia yet. It's easy to wire it for a project at hand, but getting all the required information dynamically for a project with an unknown layout is challenging. I have an idea that involves debug symbols, which of course contain all the information we need. However, a part of me wants to find a solution that may work even in release mode, where debug symbols are usually not present, if somebody, for some reason, decides to incorporate HotAvalonia into their app as a feature and not as a development tool. |
@ClxS your solution works well for me. Thanks for sharing! @Kir-Antipov thanks again for all the help and the great work! |
That's great to hear! :) However, I'm gonna leave this issue open, as it's something HotAvalonia needs to learn how to do out of the box. |
It probably won't be the solution, but maybe it's possible to use a source generator to generate those contexts for referenced projects? At least as a temporary solution. |
While it's definitely a solution, it has its downsides. Namely:
Thus, I think I'm going to stick with the debug symbols-related solution. |
That makes sense. If it's going to take a longer while, I could volunteer some of my time to create some simple generators for The Big Three, and to keep them working. Once you'd finish the debug symbols based solution, source generator could get deprecated and subsequently removed. That would only make sense, if the solution you want to go with would take considerably longer to be made, hence my question. |
In my better years, I could have done this in a day. However, without going into too much detail, I'm not in my most productive form at the moment, so it's more like a "will do it in an hour within a week" kind of deal. Since this is going to be a breaking change anyways (I need to abstract So, what I'm saying here is it will take some time, but not a lot, really.
The sentiment is very much appreciated! However, it will definitely be faster for me to implement the solution I already settled on :) |
All right, in that case I will patiently wait! |
@ClxS, does your plugin system load assemblies via |
On a slightly more generic note, I'm currently trying to think of a good way for users to provide location hints for their assemblies when it's really truly needed. Within the current model, where hot reload is only enabled for a single project, it's easy - this.EnableHotReload("/path/to/control.cs"); However, a single string is not going to cut it in a multi-project setup. Any bright ideas, folks? P.S. - by the way, everything else is already implemented, so I hope you will be able to at least test the new multi-project-oriented system in a few days when I'm done wiring up this last thing :) |
@Kir-Antipov at the moment it's the string path form. I might move it towards the byte[] eventually but that's a long way off |
@ClxS, that's great, actually, because assemblies loaded via Since you use |
Now `AvaloniaHotReloadExtensions` uses new AppDomain-wide `IHotReloadContext` out of the box. Closes #7
I think I'm done here. If this.EnableHotReload(
asm => TryLocateAssemblyProject(asm, out string? directoryName) ? directoryName : null
); However, I genuinely think that you won't need that with your current setups. Anyway, if you folks could test it on your end as well, it would be very much appreciated :) |
Hi!
I was wondering if there is a plan to support more complex solutions with multiple projects containing controls?
cheers,
Stefan
The text was updated successfully, but these errors were encountered: