I have a DLL which contains a custom Avalonia control and its default style and resources.
I can load the DLL dynamically like this and use the control without issue:
var basePath = Directory.GetCurrentDirectory();
var dll = Assembly.LoadFile(Path.Combine(basePath, "Components.dll"));
foreach (var type in dll.GetExportedTypes())
{
if (type.IsAssignableTo(typeof(IComponentPlugin)))
{
var instance = Activator.CreateInstance(type);
if (instance is IComponentPlugin plugin)
{
// Do Stuff
}
}
}
Now, i want to add the default style and resources to my Application
's, and it's somehow very hard.
I can retrieve a StyleInclude
and ResourceInclude
from my DLL, by putting this in IComponentPlugin
:
public ResourceInclude? GetResources()
{
var uri = new Uri("avares://DefaultResources.axaml");
return new ResourceInclude(uri) { Source = uri };
}
public StyleInclude? GetStyle()
{
var uri = new Uri("avares://DefaultStyle.axaml");
return new StyleInclude(uri) { Source = uri };
}
But, when i try to add it to my Application
's resources, AvaloniaXamlLoader
complains. "No precompiled XAML found for avares://DefaultResources.axaml/ (baseUri: avares://DefaultResources.axaml/)".
I tried instead getting the content of the file and loading it with AvaloniaRuntimeXamlLoader
from the Avalonia.Markup.Xaml.Loader
package:
public Stream? GetResources()
{
return AssetLoader.Open(new Uri("avares://DefaultResources.axaml"));
}
But then, i get a FileNotFoundException
"The resource avares://DefaultResources.axaml/ could not be found.". I also tried with "avares://Components/DefaultResources.axaml"
to no avail.
What would be the way to add the resources to my Application
?
I managed to find a workaround by setting DefaultResources.axaml
and DefaultStyles.axaml
to EmbeddedResources, and the following code:
foreach (var resourceName in dll.GetManifestResourceNames())
{
if (resourceName.EndsWith("DefaultResources.axaml"))
{
var resourceStream = dll.GetManifestResourceStream(resourceName);
if (resourceStream != null)
{
var resource = AvaloniaRuntimeXamlLoader.Load(resourceStream, dll);
if (resource is IResourceProvider resourceProvider)
Application.Current.Resources.MergedDictionaries.Add(resourceProvider);
}
}
// Same for DefaultStyle.axaml
}
It would be more convenient to be able to use AvaloniaResources, though.