diff --git a/Perspex.sln b/Perspex.sln
index 54c810f636..20a7fa624e 100644
--- a/Perspex.sln
+++ b/Perspex.sln
@@ -79,6 +79,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9B9E
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DEF5-D50F-4975-8B72-124C9EB54066}"
ProjectSection(SolutionItems) = preProject
+ src\Shared\PclPlatformWrapper.cs = src\Shared\PclPlatformWrapper.cs
src\Shared\SharedAssemblyInfo.cs = src\Shared\SharedAssemblyInfo.cs
EndProjectSection
EndProject
diff --git a/src/Gtk/Perspex.Gtk/GtkPlatform.cs b/src/Gtk/Perspex.Gtk/GtkPlatform.cs
index d02e112845..2881bd292f 100644
--- a/src/Gtk/Perspex.Gtk/GtkPlatform.cs
+++ b/src/Gtk/Perspex.Gtk/GtkPlatform.cs
@@ -28,6 +28,7 @@ namespace Perspex.Gtk
public static void Initialize()
{
var locator = Locator.CurrentMutable;
+ locator.Register(() => new PclPlatformWrapper(), typeof(IPclPlatformWrapper));
locator.Register(() => new WindowImpl(), typeof(IWindowImpl));
locator.Register(() => new PopupImpl(), typeof(IPopupImpl));
locator.Register(() => new ClipboardImpl(), typeof(IClipboard));
diff --git a/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj b/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj
index 563d87b2a3..95d3c8c5c5 100644
--- a/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj
+++ b/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj
@@ -58,6 +58,9 @@
+
+ PclPlatformWrapper.cs
+
diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs
index 45894a58eb..cf16bcb8f7 100644
--- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs
+++ b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq;
using System.Reflection;
using Glass;
using OmniXaml;
@@ -16,6 +17,10 @@ using Perspex.Markup.Xaml.DataBinding;
using Perspex.Markup.Xaml.MarkupExtensions;
using Perspex.Media;
using Perspex.Media.Imaging;
+using Perspex.Metadata;
+using Perspex.Platform;
+using Perspex.Styling;
+using Splat;
namespace Perspex.Markup.Xaml.Context
{
@@ -39,37 +44,27 @@ namespace Perspex.Markup.Xaml.Context
{
var xamlNamespaceRegistry = new XamlNamespaceRegistry();
- var rootType = typeof(Control);
- var bindingType = typeof(BindingExtension);
- var templateType = typeof(XamlDataTemplate);
-
- var definitionForRoot = XamlNamespace
- .Map(PerspexNs)
- .With(
- new[]
- {
- Route.Assembly(rootType.GetTypeInfo().Assembly).WithNamespaces(
- new[]
- {
- rootType.Namespace
- }),
- Route.Assembly(bindingType.GetTypeInfo().Assembly).WithNamespaces(
- new[]
- {
- bindingType.Namespace,
- }),
- Route.Assembly(templateType.GetTypeInfo().Assembly).WithNamespaces(
- new[]
- {
- templateType.Namespace,
- })
- });
-
- foreach (var ns in new List { definitionForRoot })
+ var forcedAssemblies = new[]
{
- xamlNamespaceRegistry.AddNamespace(ns);
+ typeof (Control),
+ typeof(Style)
+ }.Select(t => t.GetTypeInfo().Assembly);
+
+ foreach (var nsa in
+ forcedAssemblies
+ .Concat(Locator.Current.GetService().GetLoadedAssemblies())
+ .Distinct()
+ .SelectMany(asm
+ => asm.GetCustomAttributes().Select(attr => new {asm, attr}))
+ .GroupBy(entry => entry.attr.XmlNamespace))
+ {
+ var def = XamlNamespace.Map(nsa.Key)
+ .With(nsa.GroupBy(x => x.asm).Select(
+ a => Route.Assembly(a.Key)
+ .WithNamespaces(a.Select(entry => entry.attr.ClrNamespace).ToList())
+ ));
+ xamlNamespaceRegistry.AddNamespace(def);
}
-
xamlNamespaceRegistry.RegisterPrefix(new PrefixRegistration(string.Empty, PerspexNs));
return xamlNamespaceRegistry;
diff --git a/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs b/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs
index eea5e0803d..07a61a6798 100644
--- a/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs
+++ b/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs
@@ -2,5 +2,8 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Reflection;
+using Perspex.Metadata;
[assembly: AssemblyTitle("Perspex.Markup.Xaml")]
+[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Markup.Xaml.MarkupExtensions")]
+[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Markup.Xaml.Templates")]
\ No newline at end of file
diff --git a/src/Perspex.Base/Metadata/XmlnsDefinitionAttribute.cs b/src/Perspex.Base/Metadata/XmlnsDefinitionAttribute.cs
new file mode 100644
index 0000000000..63371bf80f
--- /dev/null
+++ b/src/Perspex.Base/Metadata/XmlnsDefinitionAttribute.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Perspex.Metadata
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
+ public class XmlnsDefinitionAttribute : Attribute
+ {
+ public string XmlNamespace { get; set; }
+ public string ClrNamespace { get; set; }
+
+ public XmlnsDefinitionAttribute(string xmlNamespace, string clrNamespace)
+ {
+ XmlNamespace = xmlNamespace;
+ ClrNamespace = clrNamespace;
+ }
+ }
+}
diff --git a/src/Perspex.Base/Perspex.Base.csproj b/src/Perspex.Base/Perspex.Base.csproj
index 8370b131f1..0ab51860f1 100644
--- a/src/Perspex.Base/Perspex.Base.csproj
+++ b/src/Perspex.Base/Perspex.Base.csproj
@@ -46,8 +46,10 @@
+
+
diff --git a/src/Perspex.Base/Platform/IPclPlatformWrapper.cs b/src/Perspex.Base/Platform/IPclPlatformWrapper.cs
new file mode 100644
index 0000000000..c57b87a738
--- /dev/null
+++ b/src/Perspex.Base/Platform/IPclPlatformWrapper.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Perspex.Platform
+{
+ public interface IPclPlatformWrapper
+ {
+ Assembly[] GetLoadedAssemblies();
+ }
+}
diff --git a/src/Perspex.Controls/Properties/AssemblyInfo.cs b/src/Perspex.Controls/Properties/AssemblyInfo.cs
index 479c2fc91b..4cda6c4aa5 100644
--- a/src/Perspex.Controls/Properties/AssemblyInfo.cs
+++ b/src/Perspex.Controls/Properties/AssemblyInfo.cs
@@ -3,6 +3,10 @@
using System.Reflection;
using System.Runtime.CompilerServices;
+using Perspex.Metadata;
[assembly: AssemblyTitle("Perspex.Controls")]
-[assembly: InternalsVisibleTo("Perspex.Controls.UnitTests")]
\ No newline at end of file
+[assembly: InternalsVisibleTo("Perspex.Controls.UnitTests")]
+
+[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Controls")]
+[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Controls.Primitives")]
\ No newline at end of file
diff --git a/src/Perspex.Styling/Properties/AssemblyInfo.cs b/src/Perspex.Styling/Properties/AssemblyInfo.cs
index 3dbe71ef35..f06c17710e 100644
--- a/src/Perspex.Styling/Properties/AssemblyInfo.cs
+++ b/src/Perspex.Styling/Properties/AssemblyInfo.cs
@@ -2,5 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Reflection;
+using Perspex.Metadata;
[assembly: AssemblyTitle("Perspex.Styling")]
+[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Styling")]
\ No newline at end of file
diff --git a/src/Shared/PclPlatformWrapper.cs b/src/Shared/PclPlatformWrapper.cs
new file mode 100644
index 0000000000..9057a8085b
Binary files /dev/null and b/src/Shared/PclPlatformWrapper.cs differ
diff --git a/src/Windows/Perspex.Win32/Perspex.Win32.csproj b/src/Windows/Perspex.Win32/Perspex.Win32.csproj
index a55bba662b..68093baf10 100644
--- a/src/Windows/Perspex.Win32/Perspex.Win32.csproj
+++ b/src/Windows/Perspex.Win32/Perspex.Win32.csproj
@@ -62,6 +62,9 @@
+
+ PclPlatformWrapper.cs
+
Properties\SharedAssemblyInfo.cs
diff --git a/src/Windows/Perspex.Win32/Win32Platform.cs b/src/Windows/Perspex.Win32/Win32Platform.cs
index da4be6b6a6..4cfe797450 100644
--- a/src/Windows/Perspex.Win32/Win32Platform.cs
+++ b/src/Windows/Perspex.Win32/Win32Platform.cs
@@ -40,6 +40,7 @@ namespace Perspex.Win32
private static void InitializeInternal()
{
var locator = Locator.CurrentMutable;
+ locator.Register(()=>new PclPlatformWrapper(), typeof(IPclPlatformWrapper));
locator.Register(() => new PopupImpl(), typeof(IPopupImpl));
locator.Register(() => new ClipboardImpl(), typeof(IClipboard));
locator.Register(() => WindowsKeyboardDevice.Instance, typeof(IKeyboardDevice));