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));