diff --git a/src/Avalonia.Controls/AppBuilderBase.cs b/src/Avalonia.Controls/AppBuilderBase.cs
index d741e5b977..a2dedd7340 100644
--- a/src/Avalonia.Controls/AppBuilderBase.cs
+++ b/src/Avalonia.Controls/AppBuilderBase.cs
@@ -17,7 +17,7 @@ namespace Avalonia.Controls
///
/// Gets or sets the instance.
///
- public IRuntimePlatform RuntimePlatform { get; private set; }
+ public IRuntimePlatform RuntimePlatform { get; set; }
///
/// Gets or sets a method to call the initialize the runtime platform services (e. g. AssetLoader)
@@ -105,7 +105,7 @@ namespace Avalonia.Controls
return Self;
}
- public AppBuilder AfterSetup(Action callback)
+ public TAppBuilder AfterSetup(Action callback)
{
AfterSetupCallback = (Action)Delegate.Combine(AfterSetupCallback, callback);
return Self;
diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj
index 1f5fd7c449..c7bfcf7ac4 100644
--- a/src/Avalonia.Controls/Avalonia.Controls.csproj
+++ b/src/Avalonia.Controls/Avalonia.Controls.csproj
@@ -59,6 +59,7 @@
+
diff --git a/src/Avalonia.Controls/Platform/ExportWindowingSubsystemAttribute.cs b/src/Avalonia.Controls/Platform/ExportWindowingSubsystemAttribute.cs
new file mode 100644
index 0000000000..628f73ca80
--- /dev/null
+++ b/src/Avalonia.Controls/Platform/ExportWindowingSubsystemAttribute.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Platform
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
+ public class ExportWindowingSubsystemAttribute : Attribute
+ {
+ public ExportWindowingSubsystemAttribute(OperatingSystemType requiredRuntimePlatform, int priority, string name, Type initializationType, string initializationMethod)
+ {
+ Name = name;
+ InitializationType = initializationType;
+ InitializationMethod = initializationMethod;
+ RequiredOS = requiredRuntimePlatform;
+ Priority = priority;
+ }
+
+ public string InitializationMethod { get; private set; }
+ public Type InitializationType { get; private set; }
+ public string Name { get; private set; }
+ public int Priority { get; private set; }
+ public OperatingSystemType RequiredOS { get; private set; }
+ }
+}
diff --git a/src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs b/src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs
index 508a23866c..157fb7acd9 100644
--- a/src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs
+++ b/src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Platform;
using Avalonia.Shared.PlatformSupport;
+using System.IO;
namespace Avalonia
{
@@ -23,22 +24,47 @@ namespace Avalonia
public AppBuilder UsePlatformDetect()
{
- var platformId = (int)Environment.OSVersion.Platform;
- if (platformId == 4 || platformId == 6)
- {
- UseRenderingSubsystem("Avalonia.Cairo");
- UseWindowingSubsystem("Avalonia.Gtk");
- WindowingSubsystemName = "Gtk";
- RenderingSubsystemName = "Cairo";
- }
- else
+ var os = RuntimePlatform.GetRuntimeInfo().OperatingSystem;
+
+ LoadAssembliesInDirectory();
+
+ var windowingSubsystemAttribute = (from assembly in RuntimePlatform.GetLoadedAssemblies()
+ from attribute in assembly.GetCustomAttributes()
+ where attribute.RequiredOS == os
+ orderby attribute.Priority ascending
+ select attribute).First();
+
+ var renderingSubsystemAttribute = (from assembly in RuntimePlatform.GetLoadedAssemblies()
+ from attribute in assembly.GetCustomAttributes()
+ where attribute.RequiredOS == os
+ where attribute.RequiresWindowingSubsystem == null
+ || attribute.RequiresWindowingSubsystem == windowingSubsystemAttribute.Name
+ orderby attribute.Priority ascending
+ select attribute).First();
+
+ UseWindowingSubsystem(() => windowingSubsystemAttribute.InitializationType
+ .GetRuntimeMethod(windowingSubsystemAttribute.InitializationMethod, Type.EmptyTypes).Invoke(null, null));
+ WindowingSubsystemName = windowingSubsystemAttribute.Name;
+
+ UseRenderingSubsystem(() => renderingSubsystemAttribute.InitializationType
+ .GetRuntimeMethod(renderingSubsystemAttribute.InitializationMethod, Type.EmptyTypes).Invoke(null, null));
+ RenderingSubsystemName = renderingSubsystemAttribute.Name;
+
+ return this;
+ }
+
+ private void LoadAssembliesInDirectory()
+ {
+ foreach (var file in new FileInfo(Assembly.GetEntryAssembly().Location).Directory.EnumerateFiles("*.dll"))
{
- UseRenderingSubsystem("Avalonia.Direct2D1");
- UseWindowingSubsystem("Avalonia.Win32");
- WindowingSubsystemName = "Win32";
- RenderingSubsystemName = "Direct2D1";
+ try
+ {
+ Assembly.LoadFile(file.FullName);
+ }
+ catch (Exception)
+ {
+ }
}
- return this;
}
}
}
diff --git a/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj b/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj
index 55a4578f59..b58ad3af1e 100644
--- a/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj
+++ b/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj
@@ -64,6 +64,10 @@
{D2221C82-4A25-4583-9B43-D791E3F6820C}
Avalonia.Controls
+
+ {eb582467-6abb-43a1-b052-e981ba910e3a}
+ Avalonia.SceneGraph
+
{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}
Avalonia.Styling
@@ -81,4 +85,4 @@
-->
-
+
\ No newline at end of file
diff --git a/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj b/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
index 25a79307e6..1f2734b2e9 100644
--- a/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
+++ b/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
@@ -100,6 +100,7 @@
+
diff --git a/src/Avalonia.SceneGraph/Platform/ExportRenderingSubsystemAttribute.cs b/src/Avalonia.SceneGraph/Platform/ExportRenderingSubsystemAttribute.cs
new file mode 100644
index 0000000000..a020bf9b1c
--- /dev/null
+++ b/src/Avalonia.SceneGraph/Platform/ExportRenderingSubsystemAttribute.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Platform
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
+ public class ExportRenderingSubsystemAttribute : Attribute
+ {
+ public ExportRenderingSubsystemAttribute(OperatingSystemType requiredOS, int priority, string name, Type initializationType, string initializationMethod)
+ {
+ Name = name;
+ InitializationType = initializationType;
+ InitializationMethod = initializationMethod;
+ RequiredOS = requiredOS;
+ Priority = priority;
+ }
+
+ public string InitializationMethod { get; private set; }
+ public Type InitializationType { get; private set; }
+ public string Name { get; private set; }
+ public int Priority { get; private set; }
+ public OperatingSystemType RequiredOS { get; private set; }
+ public string RequiresWindowingSubsystem { get; set; }
+ }
+}
diff --git a/src/Gtk/Avalonia.Cairo/CairoPlatform.cs b/src/Gtk/Avalonia.Cairo/CairoPlatform.cs
index 493416d15f..c97a95a1ed 100644
--- a/src/Gtk/Avalonia.Cairo/CairoPlatform.cs
+++ b/src/Gtk/Avalonia.Cairo/CairoPlatform.cs
@@ -14,7 +14,7 @@ namespace Avalonia
{
public static T UseCairo(this T builder) where T : AppBuilderBase, new()
{
- builder.RenderingSubsystemInitializer = Cairo.CairoPlatform.Initialize;
+ builder.UseRenderingSubsystem(Cairo.CairoPlatform.Initialize);
builder.RenderingSubsystemName = "Cairo";
return builder;
}
diff --git a/src/Gtk/Avalonia.Cairo/Properties/AssemblyInfo.cs b/src/Gtk/Avalonia.Cairo/Properties/AssemblyInfo.cs
index cdda1132bb..63457cc1a2 100644
--- a/src/Gtk/Avalonia.Cairo/Properties/AssemblyInfo.cs
+++ b/src/Gtk/Avalonia.Cairo/Properties/AssemblyInfo.cs
@@ -1,6 +1,8 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using Avalonia.Cairo;
+using Avalonia.Platform;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -37,3 +39,7 @@ using System.Runtime.InteropServices;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+
+[assembly: ExportRenderingSubsystem(OperatingSystemType.WinNT, 2, "Cairo", typeof(CairoPlatform), nameof(CairoPlatform.Initialize), RequiresWindowingSubsystem = "GTK")]
+[assembly: ExportRenderingSubsystem(OperatingSystemType.Linux, 1, "Cairo", typeof(CairoPlatform), nameof(CairoPlatform.Initialize), RequiresWindowingSubsystem = "GTK")]
+[assembly: ExportRenderingSubsystem(OperatingSystemType.OSX, 2, "Cairo", typeof(CairoPlatform), nameof(CairoPlatform.Initialize), RequiresWindowingSubsystem = "GTK")]
diff --git a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
index b54b6d3e71..15c16b3c2c 100644
--- a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
+++ b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs
@@ -16,7 +16,7 @@ namespace Avalonia
{
public static T UseGtk(this T builder) where T : AppBuilderBase, new()
{
- builder.WindowingSubsystemInitializer = Gtk.GtkPlatform.Initialize;
+ builder.UseWindowingSubsystem(Gtk.GtkPlatform.Initialize);
builder.WindowingSubsystemName = "Gtk";
return builder;
}
diff --git a/src/Gtk/Avalonia.Gtk/Properties/AssemblyInfo.cs b/src/Gtk/Avalonia.Gtk/Properties/AssemblyInfo.cs
index 6c970b77f6..f0e9ab4ccb 100644
--- a/src/Gtk/Avalonia.Gtk/Properties/AssemblyInfo.cs
+++ b/src/Gtk/Avalonia.Gtk/Properties/AssemblyInfo.cs
@@ -1,6 +1,8 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using Avalonia.Gtk;
+using Avalonia.Platform;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -19,3 +21,8 @@ using System.Runtime.CompilerServices;
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
+
+[assembly: ExportWindowingSubsystem(OperatingSystemType.WinNT, 2, "GTK", typeof(GtkPlatform), nameof(GtkPlatform.Initialize))]
+[assembly: ExportWindowingSubsystem(OperatingSystemType.Linux, 1, "GTK", typeof(GtkPlatform), nameof(GtkPlatform.Initialize))]
+[assembly: ExportWindowingSubsystem(OperatingSystemType.OSX, 2, "GTK", typeof(GtkPlatform), nameof(GtkPlatform.Initialize))]
+
diff --git a/src/Skia/Avalonia.Skia.Desktop/Properties/AssemblyInfo.cs b/src/Skia/Avalonia.Skia.Desktop/Properties/AssemblyInfo.cs
index 0afee62368..69a3f34489 100644
--- a/src/Skia/Avalonia.Skia.Desktop/Properties/AssemblyInfo.cs
+++ b/src/Skia/Avalonia.Skia.Desktop/Properties/AssemblyInfo.cs
@@ -1,3 +1,5 @@
+using Avalonia.Platform;
+using Avalonia.Skia;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -34,3 +36,5 @@ using System.Runtime.InteropServices;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+
+[assembly: ExportRenderingSubsystem(OperatingSystemType.WinNT, 3, "Skia", typeof(SkiaPlatform), nameof(SkiaPlatform.Initialize))]
diff --git a/src/Skia/Avalonia.Skia/SkiaPlatform.cs b/src/Skia/Avalonia.Skia/SkiaPlatform.cs
index 3523af0b35..a49bb8bb13 100644
--- a/src/Skia/Avalonia.Skia/SkiaPlatform.cs
+++ b/src/Skia/Avalonia.Skia/SkiaPlatform.cs
@@ -10,7 +10,7 @@ namespace Avalonia
{
public static T UseSkia(this T builder) where T : AppBuilderBase, new()
{
- builder.RenderingSubsystemInitializer = Avalonia.Skia.SkiaPlatform.Initialize;
+ builder.UseRenderingSubsystem(Skia.SkiaPlatform.Initialize);
builder.RenderingSubsystemName = "Skia";
return builder;
}
diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
index 8d94ebd1e9..22d4a498cc 100644
--- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
+++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
@@ -14,7 +14,7 @@ namespace Avalonia
{
public static T UseDirect2D1(this T builder) where T : AppBuilderBase, new()
{
- builder.RenderingSubsystemInitializer = Avalonia.Direct2D1.Direct2D1Platform.Initialize;
+ builder.UseRenderingSubsystem(Direct2D1.Direct2D1Platform.Initialize);
builder.RenderingSubsystemName = "Direct2D1";
return builder;
}
diff --git a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs
index a4556b001f..3ab086b156 100644
--- a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs
+++ b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs
@@ -2,5 +2,9 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Reflection;
+using Avalonia.Platform;
+using Avalonia.Direct2D1;
[assembly: AssemblyTitle("Avalonia.Direct2D1")]
+[assembly: ExportRenderingSubsystem(OperatingSystemType.WinNT, 1, "Direct2D1", typeof(Direct2D1Platform), nameof(Direct2D1Platform.Initialize))]
+
diff --git a/src/Windows/Avalonia.Win32/Properties/AssemblyInfo.cs b/src/Windows/Avalonia.Win32/Properties/AssemblyInfo.cs
index cf7be620be..5b4d2cef23 100644
--- a/src/Windows/Avalonia.Win32/Properties/AssemblyInfo.cs
+++ b/src/Windows/Avalonia.Win32/Properties/AssemblyInfo.cs
@@ -1,6 +1,9 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using Avalonia.Platform;
+using Avalonia.Win32;
using System.Reflection;
[assembly: AssemblyTitle("Avalonia.Win32")]
+[assembly: ExportWindowingSubsystem(OperatingSystemType.WinNT, 1, "Win32", typeof(Win32Platform), nameof(Win32Platform.Initialize))]
diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs
index 5c6309b17a..6b5f55cb47 100644
--- a/src/Windows/Avalonia.Win32/Win32Platform.cs
+++ b/src/Windows/Avalonia.Win32/Win32Platform.cs
@@ -23,7 +23,7 @@ namespace Avalonia
{
public static T UseWin32(this T builder) where T : AppBuilderBase, new()
{
- builder.WindowingSubsystemInitializer = Win32.Win32Platform.Initialize;
+ builder.UseWindowingSubsystem(Win32.Win32Platform.Initialize);
builder.WindowingSubsystemName = "Win32";
return builder;
}
diff --git a/src/iOS/Avalonia.iOS/iOSPlatform.cs b/src/iOS/Avalonia.iOS/iOSPlatform.cs
index 6a14904b35..4a25b7d374 100644
--- a/src/iOS/Avalonia.iOS/iOSPlatform.cs
+++ b/src/iOS/Avalonia.iOS/iOSPlatform.cs
@@ -15,7 +15,7 @@ namespace Avalonia
{
public static T UseiOS(this T builder) where T : AppBuilderBase, new()
{
- builder.WindowingSubsystemInitializer = iOSPlatform.Initialize;
+ builder.UseWindowingSubsystem(iOSPlatform.Initialize);
builder.WindowingSubsystemName = "iOS";
return builder;
}