├── .gitattributes
├── .gitignore
├── .gitmodules
├── Create-NuGetPackages.ps1
├── LICENSE.md
├── OmniXaml.Attributes
├── ContentAttribute.cs
├── DependsOnAttribute.cs
├── FragmentLoaderAttribute.cs
├── NameAttribute.cs
├── NamescopeAttribute.cs
├── OmniXaml.Attributes.csproj
├── TypeConverterMember.cs
├── XmlnsDefinitionAttribute.cs
└── XmlnsPrefixAttribute.cs
├── OmniXaml.Services
├── AttributeBasedMetadataProvider.cs
├── AttributeBasedStringValueConverter.cs
├── AttributeBasedTypeDirectory.cs
├── AttributeBasedValueConverter.cs
├── BasicXamlLoader.cs
├── DirectCompatibilitySourceValueConverter.cs
├── ExtendedXamlLoader.cs
├── IXamlLoader.cs
├── MarkupExtensionValuePipeline.cs
├── NoActionValuePipeline.cs
├── NodeToObjectBuilder.cs
├── OmniXaml.Services.csproj
├── SimpleInstanceCreator.cs
├── TemplatePipeline.cs
├── TwoPassesNodeAssembler.cs
└── XamlLoader.cs
├── OmniXaml.Tests
├── AssemblyInfo.cs
├── FuncAssignmentApplier.cs
├── FuncInstanceCreator.cs
├── FuncStringConverter.cs
├── FuncStringConverterExtended.cs
├── InstanceCreatorMock.cs
├── Integration
│ └── XamlTests.cs
├── MemberAssigmentApplierTests.cs
├── MemberAssignmentTests.cs
├── Model
│ ├── AttachedEventArgs.cs
│ ├── Button.cs
│ ├── Collection.cs
│ ├── CollectionExtension.cs
│ ├── ConstructionFragmentLoader.cs
│ ├── Converters.cs
│ ├── Custom
│ │ ├── CustomControl.cs
│ │ ├── CustomGrid.cs
│ │ ├── CustomWindow.cs
│ │ └── ParametrizedExtension.cs
│ ├── DataTemplate.cs
│ ├── Grid.cs
│ ├── ItemsControl.cs
│ ├── ModelObject.cs
│ ├── MyImmutable.cs
│ ├── Reference.cs
│ ├── ReferenceTarget.cs
│ ├── ResourceDictionary.cs
│ ├── Setter.cs
│ ├── SimpleExtension.cs
│ ├── TemplateContent.cs
│ ├── TestWindow.cs
│ ├── TextBlock.cs
│ ├── TextWrapping.cs
│ ├── VisualStateGroup.cs
│ ├── VisualStateManager.cs
│ └── Window.cs
├── ObjectAssemblerTests.cs
├── OmniXaml.Tests.csproj
├── Phase2BuilderTests.cs
├── PipelineMock.cs
├── SimpleValueConverter.cs
├── StringValueConverterTests.cs
├── TypeDirectoryTests.cs
└── XmlToNodes
│ ├── AssignmentExtractorTests.cs
│ ├── CData.cs
│ ├── ClassDirective.cs
│ ├── CollectionsTests.cs
│ ├── DictionaryTests.cs
│ ├── EventsTests.cs
│ ├── StandardTests.cs
│ └── XamlToTreeParserTestsBase.cs
├── OmniXaml.sln
├── OmniXaml
├── Ambient
│ ├── AmbientMemberAssignment.cs
│ ├── AmbientRegistrator.cs
│ └── IAmbientRegistrator.cs
├── Annotator.cs
├── Assignment.cs
├── AssignmentExtractor.cs
├── AttachedEvent.cs
├── AttachedProperty.cs
├── AttributeBasedInstanceProperties.cs
├── BuildContext.cs
├── BuiltInConversionParser.cs
├── ComponentModelTypeConverterBasedSourceValueConverter.cs
├── ConstructionNode.cs
├── ConvertContext.cs
├── ConverterValueContext.cs
├── CreationHints.cs
├── CreationResult.cs
├── DelegateParser.cs
├── Dependency.cs
├── Directive.cs
├── DirectiveExtractor.cs
├── ExtensionValueContext.cs
├── IAssignmentExtractor.cs
├── IBuildContext.cs
├── IContentPropertyRegistry.cs
├── IConverterContextFactory.cs
├── IFullObjectBuilder.cs
├── IInlineParser.cs
├── IInstanceCreator.cs
├── IInstanceHolder.cs
├── IInstanceLifecycleSignaler.cs
├── IMarkupExtension.cs
├── IMemberAssigmentApplier.cs
├── INamescopeAnnotator.cs
├── INodeAssembler.cs
├── INodeToObjectBuilder.cs
├── IPrefixAnnotator.cs
├── IPrefixedTypeResolver.cs
├── ISourceValueConverter.cs
├── IStringSourceValueConverter.cs
├── IValueConverter.cs
├── IValuePipeline.cs
├── IXamlToTreeParser.cs
├── IXmlTypeResolver.cs
├── InjectableMember.cs
├── InlineParser.cs
├── InlineParsers
│ └── Extensions
│ │ ├── AssignmentNode.cs
│ │ ├── IdentifierNode.cs
│ │ ├── MarkupExtensionNode.cs
│ │ ├── MarkupExtensionNodeToConstructionNodeConverter.cs
│ │ ├── MarkupExtensionParser.cs
│ │ ├── Option.cs
│ │ ├── OptionsCollection.cs
│ │ ├── PositionalOption.cs
│ │ ├── PropertyOption.cs
│ │ ├── StringNode.cs
│ │ └── TreeNode.cs
├── InstanceLifecycleSignaler.cs
├── KeyedInstance.cs
├── Member.cs
├── MemberAssigmentApplier.cs
├── MemberAssignment.cs
├── Metadata
│ ├── DependencyRegistration.cs
│ ├── DependencyRegistrations.cs
│ ├── FragmentLoaderInfo.cs
│ ├── GenericMetadata.cs
│ ├── IConstructionFragmentLoader.cs
│ ├── IMetadataProvider.cs
│ ├── Metadata.cs
│ └── MetadataProvider.cs
├── MutablePipelineUnit.cs
├── Namescope.cs
├── NamescopeAnnotator.cs
├── NamescopeX.cs
├── NodeAssembler.cs
├── NodeAssignment.cs
├── NodeExtensions.cs
├── ObjectBuilderContext.cs
├── OmniXaml.csproj
├── ParseException.cs
├── ParseResult.cs
├── PositionalParameter.cs
├── PrefixAnnotator.cs
├── PrefixedTypeResolver.cs
├── PrimitiveParser.cs
├── SourceValueConverter.cs
├── SourceValueConverterTypeDescriptorContext.cs
├── StandardEvent.cs
├── StandardProperty.cs
├── StringUtils.cs
├── StringValueConverter.cs
├── SuperSmartSourceValueConverter.cs
├── TypeExtensions.cs
├── TypeLocation
│ ├── Address.cs
│ ├── AddressPack.cs
│ ├── AssemblyNameConfig.cs
│ ├── ClrNamespace.cs
│ ├── ConfiguredAssembly.cs
│ ├── ConfiguredAssemblyWithNamespaces.cs
│ ├── ITypeDirectory.cs
│ ├── Namespace.cs
│ ├── PrefixDeclaration.cs
│ ├── Route.cs
│ ├── TypeDirectory.cs
│ ├── TypeLocationException.cs
│ └── XamlNamespace.cs
├── TypeNotFoundException.cs
├── ValueContext.cs
├── ValuePipeline.cs
├── XamlParserException.cs
├── XamlToTreeParser.cs
└── XmlTypeXmlTypeResolver.cs
├── README.md
├── SampleModel
├── Model.xml
├── Model
│ ├── Animal.cs
│ └── Zoo.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── SampleModel.xproj
├── project.fragment.lock.json
└── project.json
├── UniversalApp
├── Adapters
│ ├── ConstructionFragmentLoader.cs
│ ├── OmniDataTemplate.cs
│ └── TemplateContent.cs
├── App.xaml
├── App.xaml.cs
├── Assets
│ ├── LockScreenLogo.scale-200.png
│ ├── SplashScreen.scale-200.png
│ ├── Square150x150Logo.scale-200.png
│ ├── Square44x44Logo.scale-200.png
│ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ ├── StoreLogo.png
│ └── Wide310x150Logo.scale-200.png
├── Context
│ ├── MetadataProvider.cs
│ ├── Registrator.cs
│ └── XamlLoader.cs
├── MainWindow.xml
├── Package.appxmanifest
├── Properties
│ ├── AssemblyInfo.cs
│ └── Default.rd.xml
├── Sample.xml
├── UwpApp.csproj
├── mario.png
└── project.json
├── WpfApp
├── App.config
├── App.xaml
├── App.xaml.cs
├── Context
│ ├── BasicXamlLoader.cs
│ └── ContentPropertyRegistry.cs
├── MainWindow.xml
├── MyExtension.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Sample.xml
├── TestingWindow.xaml
├── TestingWindow.xaml.cs
├── WpfApp.csproj
├── mario.png
└── project.json
├── XamlLoadTest
├── AssemblyProperties.cs
├── Converters.cs
├── Program.cs
├── Properties
│ └── launchSettings.json
├── XamlLoadTest.csproj
└── test.xaml
└── appveyor.yml
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Zafiro"]
2 | path = Zafiro
3 | url = https://github.com/SuperJMN/Zafiro.git
4 |
--------------------------------------------------------------------------------
/Create-NuGetPackages.ps1:
--------------------------------------------------------------------------------
1 | [CmdletBinding()]
2 | Param(
3 | [Parameter(Mandatory=$True, Position=1)]
4 | [string]$Version
5 | )
6 |
7 | function CreatePackage($file, $version)
8 | {
9 | Write-Host 'Building package inside ' $file.DirectoryName
10 | & 'nuget.exe' 'pack' $file.FullName -Version $version
11 | }
12 |
13 | $csprojs = Get-ChildItem -Filter "*.csproj" -Recurse
14 |
15 | foreach ($proj in $csprojs)
16 | {
17 |
18 | $jsonPath = ($proj.DirectoryName) + '\project.json'
19 | $json = Get-Item $jsonPath
20 |
21 | $content = Get-Content $json.FullName
22 | $contains = $content -match 'packOptions'
23 | if ($contains)
24 | {
25 | CreatePackage $proj $version
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 OmniGUI Platform
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/OmniXaml.Attributes/ContentAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Attributes
2 | {
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Property)]
6 | public class ContentAttribute : Attribute
7 | {
8 | public string Name { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/OmniXaml.Attributes/DependsOnAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Attributes
2 | {
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Property)]
6 | public class DependsOnAttribute : Attribute
7 | {
8 | public DependsOnAttribute(string nameOfDependency)
9 | {
10 | Dependency = nameOfDependency;
11 | }
12 | public string Dependency { get; private set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/OmniXaml.Attributes/FragmentLoaderAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Attributes
2 | {
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Property)]
6 | public class FragmentLoaderAttribute : Attribute
7 | {
8 | public string PropertyName { get; set; }
9 | public Type FragmentLoader { get; set; }
10 | public Type Type { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/OmniXaml.Attributes/NameAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Attributes
2 | {
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Property)]
6 | public class NameAttribute : Attribute
7 | {
8 | }
9 | }
--------------------------------------------------------------------------------
/OmniXaml.Attributes/NamescopeAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Attributes
2 | {
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Class, Inherited = false)]
6 | public class NamescopeAttribute : Attribute
7 | {
8 | }
9 | }
--------------------------------------------------------------------------------
/OmniXaml.Attributes/OmniXaml.Attributes.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard1.2
4 | OmniXaml.Attributes
5 | 2.0.0
6 | José Manuel Nieto (@SuperJMN)
7 | The Cross-platform XAML Framework
8 | false
9 | First release
10 | WPF XAML Cross-Platform Avalonia AvaloniaUI
11 | 2.1.0
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/OmniXaml.Attributes/TypeConverterMember.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Field)]
6 | public class TypeConverterMember : Attribute
7 | {
8 | public Type SourceType { get; }
9 |
10 | public TypeConverterMember(Type sourceType)
11 | {
12 | SourceType = sourceType;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/OmniXaml.Attributes/XmlnsDefinitionAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Attributes
2 | {
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
6 | public sealed class XmlnsDefinitionAttribute : Attribute
7 | {
8 | public string XmlNamespace { get; }
9 |
10 | public string ClrNamespace { get; }
11 |
12 | public string AssemblyName { get; set; }
13 |
14 | public XmlnsDefinitionAttribute(string xmlNamespace, string clrNamespace)
15 | {
16 | if (xmlNamespace == null)
17 | {
18 | throw new ArgumentNullException("xmlNamespace");
19 | }
20 |
21 | if (clrNamespace == null)
22 | {
23 | throw new ArgumentNullException("clrNamespace");
24 | }
25 |
26 | XmlNamespace = xmlNamespace;
27 | ClrNamespace = clrNamespace;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/OmniXaml.Attributes/XmlnsPrefixAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Attributes
2 | {
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
6 | public class XmlnsPrefixAttribute : Attribute
7 | {
8 | public string XmlNamespace { get; }
9 |
10 | /// Gets the recommended prefix associated with this attribute.
11 | /// The recommended prefix string.
12 | public string Prefix { get; }
13 |
14 | public XmlnsPrefixAttribute(string xmlNamespace, string prefix)
15 | {
16 | if (xmlNamespace == null)
17 | {
18 | throw new ArgumentNullException(nameof(xmlNamespace));
19 | }
20 |
21 | if (prefix == null)
22 | {
23 | throw new ArgumentNullException(nameof(prefix));
24 | }
25 |
26 | XmlNamespace = xmlNamespace;
27 | Prefix = prefix;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/AttributeBasedMetadataProvider.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | using System;
4 | using System.Reflection;
5 | using Attributes;
6 | using Zafiro.Core;
7 | using Metadata;
8 |
9 | public class AttributeBasedMetadataProvider : IMetadataProvider
10 | {
11 | public Metadata Get(Type type)
12 | {
13 | return new Metadata
14 | {
15 | ContentProperty = type.GetAttributeFromProperty((info, attribute) => info.Name),
16 | RuntimePropertyName = type.GetAttributeFromProperty((info, attribute) => info.Name),
17 | IsNamescope = type.GetAttributeFromType(attribute => attribute) != null,
18 | FragmentLoaderInfo = type.GetAttributeFromProperty((info, attribute) => GetFragmentLoaderInfo(type, info, attribute)),
19 | PropertyDependencies = GetDependencyRegistrations(type),
20 | };
21 | }
22 |
23 | private DependencyRegistrations GetDependencyRegistrations(Type type)
24 | {
25 | var regs = type.GetAttributesFromProperties(GetDependencyRegistration);
26 | return new DependencyRegistrations(regs);
27 | }
28 |
29 | private static DependencyRegistration GetDependencyRegistration(PropertyInfo info, DependsOnAttribute attribute)
30 | {
31 | return new DependencyRegistration
32 | {
33 | PropertyName = info.Name,
34 | DependsOn = attribute.Dependency,
35 | };
36 | }
37 |
38 | private static FragmentLoaderInfo GetFragmentLoaderInfo(Type type, MemberInfo memberInfo, FragmentLoaderAttribute attribute)
39 | {
40 | var constructionFragmentLoader = (IConstructionFragmentLoader) Activator.CreateInstance(attribute.FragmentLoader);
41 |
42 | return new FragmentLoaderInfo
43 | {
44 | Loader = constructionFragmentLoader,
45 | Type = type,
46 | PropertyName = memberInfo.Name,
47 | };
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/AttributeBasedStringValueConverter.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 |
6 | public class AttributeBasedStringValueConverter : AttributeBasedValueConverter, IStringSourceValueConverter
7 | {
8 | public AttributeBasedStringValueConverter(IList assemblies) : base(assemblies)
9 | {
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/AttributeBasedTypeDirectory.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Reflection;
7 | using Attributes;
8 | using TypeLocation;
9 |
10 | public class AttributeBasedTypeDirectory : ITypeDirectory
11 | {
12 | private readonly ITypeDirectory inner;
13 |
14 | public AttributeBasedTypeDirectory(IList assemblies)
15 | {
16 | inner = new TypeDirectory(GetNamespaces(assemblies));
17 | }
18 |
19 | private IEnumerable GetNamespaces(IEnumerable assemblies)
20 | {
21 | var routes = from a in assemblies
22 | let attributes = a.GetCustomAttributes()
23 | from byNamespace in attributes.GroupBy(arg => arg.XmlNamespace)
24 | let name = byNamespace.Key
25 | let clrNamespaces = byNamespace.Select(arg => arg.ClrNamespace)
26 | let configuredAssemblyWithNamespaces = Route.Assembly(a).WithNamespaces(clrNamespaces.ToArray())
27 | select new {Ns = name, configuredAssemblyWithNamespaces};
28 |
29 | var nss = from route in routes
30 | group route by route.Ns
31 | into g
32 | let ns = g.Select(arg => arg.configuredAssemblyWithNamespaces).ToArray()
33 | select XamlNamespace.Map(g.Key).With(ns);
34 |
35 | return nss;
36 | }
37 |
38 | public Type GetTypeByFullAddress(Address address)
39 | {
40 | return inner.GetTypeByFullAddress(address);
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/AttributeBasedValueConverter.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Reflection;
7 | using Attributes;
8 | using Zafiro.Core;
9 |
10 | public class AttributeBasedValueConverter : IValueConverter
11 | {
12 | private readonly IDictionary> converterFuncs = new Dictionary>();
13 |
14 | public AttributeBasedValueConverter(IList assemblies)
15 | {
16 | AddConvertersFromAssemblies(assemblies);
17 | }
18 |
19 | private void AddConvertersFromAssemblies(IList assemblies)
20 | {
21 | var converterEntries =
22 | from type in assemblies.AllExportedTypes()
23 | from member in type.GetRuntimeFields()
24 | let attr = member.GetCustomAttribute()
25 | where attr != null
26 | where member.IsStatic
27 | select new { type, member, attr.SourceType };
28 |
29 | foreach (var converterEntry in converterEntries)
30 | {
31 | var staticFieldValue = converterEntry.member.GetValue(null);
32 | var converterFunc = (Func)staticFieldValue;
33 | converterFuncs.Add(converterEntry.SourceType, converterFunc);
34 | }
35 | }
36 |
37 | public (bool, object) Convert(TInput input, Type desiredTargetType, ConvertContext context)
38 | {
39 | if (converterFuncs.ContainsKey(desiredTargetType))
40 | {
41 | return converterFuncs[desiredTargetType](input, context);
42 | }
43 |
44 | return (false, null);
45 | }
46 | }
47 |
48 |
49 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/BasicXamlLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Reflection;
3 | using OmniXaml.Metadata;
4 |
5 | namespace OmniXaml.Services
6 | {
7 | public class BasicXamlLoader : XamlLoader
8 | {
9 | private INodeToObjectBuilder builder;
10 |
11 | public BasicXamlLoader(IList assemblies)
12 | {
13 | Assemblies = assemblies;
14 | }
15 |
16 | public IList Assemblies { get; }
17 |
18 | public override IXamlToTreeParser Parser => new XamlToTreeParser(MetadataProvider, InlineParsers, XmlTypeResolver);
19 | public override IMemberAssigmentApplier AssignmentApplier => new MemberAssigmentApplier(ValuePipeline);
20 |
21 | protected override IValuePipeline ValuePipeline => new NoActionValuePipeline();
22 |
23 | protected virtual IEnumerable InlineParsers => new List
24 | {
25 | new InlineParser(XmlTypeResolver)
26 | };
27 |
28 | protected virtual IXmlTypeResolver XmlTypeResolver => new XmlTypeXmlTypeResolver(new AttributeBasedTypeDirectory(Assemblies));
29 |
30 | protected virtual IMetadataProvider MetadataProvider => new AttributeBasedMetadataProvider();
31 |
32 | public override IInstanceCreator InstanceCreator => new SimpleInstanceCreator();
33 |
34 | public override IStringSourceValueConverter StringSourceValueConverter => new SuperSmartSourceValueConverter(
35 | new IStringSourceValueConverter[]
36 | {
37 | new DirectCompatibilitySourceValueConverter(),
38 | new AttributeBasedStringValueConverter(Assemblies), new ComponentModelTypeConverterBasedSourceValueConverter()
39 | });
40 |
41 | public override INodeToObjectBuilder Builder => builder ?? (builder = CreateBuilder());
42 |
43 | private INodeToObjectBuilder CreateBuilder()
44 | {
45 | return new NodeToObjectBuilder(new TwoPassesNodeAssembler(new NodeAssembler(InstanceCreator,
46 | StringSourceValueConverter, AssignmentApplier)));
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/DirectCompatibilitySourceValueConverter.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | using System;
4 | using Zafiro.Core;
5 |
6 | public class DirectCompatibilitySourceValueConverter : IStringSourceValueConverter
7 | {
8 | public (bool, object) Convert(string strValue, Type desiredTargetType, ConvertContext context)
9 | {
10 | if (typeof(string).IsAssignableFrom(desiredTargetType))
11 | {
12 | return (true, strValue);
13 | }
14 |
15 | return (false, null);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/IXamlLoader.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | public interface IXamlLoader
4 | {
5 | object Load(string xaml, object intance = null);
6 | IStringSourceValueConverter StringSourceValueConverter { get; }
7 | }
8 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/MarkupExtensionValuePipeline.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | public class MarkupExtensionValuePipeline : ValuePipeline
4 | {
5 | public MarkupExtensionValuePipeline(IValuePipeline inner) : base(inner)
6 | {
7 | }
8 |
9 | protected override void HandleCore(object parent, Member member, MutablePipelineUnit mutable, INodeToObjectBuilder builder, BuilderContext context)
10 | {
11 | var extension = mutable.Value as IMarkupExtension;
12 | if (extension != null)
13 | {
14 | var keyedInstance = new KeyedInstance(parent);
15 | var assignment = new Assignment(keyedInstance, member, mutable.Value);
16 | var finalValue = extension.GetValue(new ExtensionValueContext(assignment, null, null, null));
17 | mutable.Value = finalValue;
18 | }
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/NoActionValuePipeline.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | public class NoActionValuePipeline : IValuePipeline
4 | {
5 | public void Handle(object parent, Member member, MutablePipelineUnit mutable, INodeToObjectBuilder builder, BuilderContext context)
6 | {
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/NodeToObjectBuilder.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | public class NodeToObjectBuilder : INodeToObjectBuilder
4 | {
5 | private readonly INodeAssembler assembler;
6 |
7 | public NodeToObjectBuilder(INodeAssembler assembler)
8 | {
9 | this.assembler = assembler;
10 | }
11 |
12 | public object Build(ConstructionNode node, BuilderContext context = null)
13 | {
14 | assembler.Assemble(node, this, null, context ?? new BuilderContext());
15 | return node.Instance;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/OmniXaml.Services.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard1.2
4 | OmniXaml.Services
5 | 2.0.0
6 | José Manuel Nieto (@SuperJMN)
7 | The Cross-platform XAML Framework
8 | false
9 | First release
10 | WPF XAML Cross-Platform Avalonia AvaloniaUI
11 | 2.1.0
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/OmniXaml.Services/SimpleInstanceCreator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Services
4 | {
5 | public class SimpleInstanceCreator : IInstanceCreator
6 | {
7 | public CreationResult Create(Type type, CreationHints creationHints)
8 | {
9 | var instance = Activator.CreateInstance(type);
10 | return new CreationResult(instance, new CreationHints());
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/TemplatePipeline.cs:
--------------------------------------------------------------------------------
1 | using OmniXaml.Metadata;
2 |
3 | namespace OmniXaml.Services
4 | {
5 | public class TemplatePipeline : ValuePipeline
6 | {
7 | private readonly IMetadataProvider metadataProvider;
8 |
9 | public TemplatePipeline(IValuePipeline pipeline, IMetadataProvider metadataProvider) : base(pipeline)
10 | {
11 | this.metadataProvider = metadataProvider;
12 | }
13 |
14 | protected override void HandleCore(object parent, Member member, MutablePipelineUnit mutable, INodeToObjectBuilder builder, BuilderContext context)
15 | {
16 | var deferringLoader = metadataProvider.Get(parent.GetType()).FragmentLoaderInfo;
17 |
18 | if (deferringLoader == null)
19 | {
20 | return;
21 | }
22 |
23 | if (IsApplicable(deferringLoader, parent, member))
24 | {
25 | mutable.Value = deferringLoader.Loader.Load(mutable.ParentNode, builder, context);
26 | }
27 | }
28 |
29 | private static bool IsApplicable(FragmentLoaderInfo loader, object parent, Member member)
30 | {
31 | return loader.Type == parent.GetType() && string.Equals(member.MemberName, loader.PropertyName);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/TwoPassesNodeAssembler.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Services
2 | {
3 | public class TwoPassesNodeAssembler : INodeAssembler
4 | {
5 | private readonly NodeAssembler assembler;
6 |
7 | public TwoPassesNodeAssembler(NodeAssembler nodeAssembler)
8 | {
9 | assembler = nodeAssembler;
10 | }
11 |
12 | public void Assemble(ConstructionNode node, INodeToObjectBuilder nodeToObjectBuilder, ConstructionNode parent = null, BuilderContext context = null)
13 | {
14 | assembler.Assemble(node, nodeToObjectBuilder, parent, context);
15 | assembler.Assemble(node, nodeToObjectBuilder, parent, context);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/OmniXaml.Services/XamlLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace OmniXaml.Services
6 | {
7 | public abstract class XamlLoader : IXamlLoader
8 | {
9 | public abstract IXamlToTreeParser Parser { get; }
10 | public abstract IMemberAssigmentApplier AssignmentApplier { get; }
11 |
12 | public abstract IInstanceCreator InstanceCreator { get; }
13 | public abstract IStringSourceValueConverter StringSourceValueConverter { get; }
14 | protected abstract IValuePipeline ValuePipeline { get; }
15 |
16 | public abstract INodeToObjectBuilder Builder { get; }
17 |
18 | public object Load(string xaml, object intance = null)
19 | {
20 | var prefixAnnotator = new PrefixAnnotator();
21 | var constructionNode = Parser.Parse(xaml, prefixAnnotator).Root;
22 | var build = Builder.Build(constructionNode);
23 | if (build == null)
24 | {
25 | var unresolvedNodes = GetUnresolvedNodes(constructionNode);
26 | throw new ParseException("XAML cannot be parsed due to nodes that cannot be resolved:" + string.Join(",", unresolvedNodes));
27 | }
28 | return build;
29 | }
30 |
31 | private IEnumerable GetUnresolvedNodes(ConstructionNode constructionNode)
32 | {
33 | if (!constructionNode.IsCreated && SubNodesAreCreated(constructionNode))
34 | {
35 | yield return constructionNode;
36 | }
37 |
38 | foreach (var constructionNodeAssignment in constructionNode.Assignments)
39 | {
40 | var values = constructionNodeAssignment.Values;
41 | foreach (var value in values)
42 | {
43 | foreach (var unresolved in GetUnresolvedNodes(value))
44 | {
45 | yield return unresolved;
46 | }
47 | }
48 | }
49 | }
50 |
51 | private bool SubNodesAreCreated(ConstructionNode constructionNode)
52 | {
53 | var membersCreated = constructionNode.Assignments.All(ma => ma.Values.All(node => node.IsCreated));
54 | var childrenCreated = constructionNode.Assignments.All(ma => ma.Values.All(node => node.IsCreated));
55 |
56 | return membersCreated && childrenCreated;
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using OmniXaml.Attributes;
2 |
3 | [assembly: XmlnsDefinition("root", "OmniXaml.Tests.Model")]
--------------------------------------------------------------------------------
/OmniXaml.Tests/FuncAssignmentApplier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Tests
4 | {
5 | public class FuncAssignmentApplier : IMemberAssigmentApplier
6 | {
7 | private Action func;
8 |
9 | public FuncAssignmentApplier(Action func)
10 | {
11 | this.func = func;
12 | }
13 |
14 | public void ExecuteAssignment(NodeAssignment assignment, INodeToObjectBuilder builder, BuilderContext context)
15 | {
16 | func(assignment, builder, context);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/FuncInstanceCreator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Tests
4 | {
5 | public class FuncInstanceCreator : IInstanceCreator
6 | {
7 | private readonly Func func;
8 |
9 | public FuncInstanceCreator(Func func)
10 | {
11 | this.func = func;
12 | }
13 |
14 | public CreationResult Create(Type type, CreationHints creationHints = null)
15 | {
16 | return func(creationHints, type);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/FuncStringConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Tests
4 | {
5 | internal class FuncStringConverter : IStringSourceValueConverter
6 | {
7 | private readonly Func func;
8 |
9 | public FuncStringConverter(Func func)
10 | {
11 | this.func = func;
12 | }
13 |
14 | public (bool, object) Convert(string strValue, Type desiredTargetType, ConvertContext context)
15 | {
16 | return func(strValue);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/FuncStringConverterExtended.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Tests
4 | {
5 | public class FuncStringConverterExtended : IStringSourceValueConverter
6 | {
7 | private readonly Func func;
8 |
9 | public FuncStringConverterExtended(Func func)
10 | {
11 | this.func = func;
12 | }
13 |
14 | public (bool, object) Convert(string strValue, Type desiredTargetType, ConvertContext context)
15 | {
16 | return func(strValue, desiredTargetType);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/InstanceCreatorMock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Tests
4 | {
5 | internal class InstanceCreatorMock : IInstanceCreator
6 | {
7 | private Func createFunc = (type, hints) => new CreationResult(Activator.CreateInstance(type), new CreationHints());
8 |
9 | public void SetObjectFactory(Func factory)
10 | {
11 | this.createFunc = factory;
12 | }
13 |
14 | public CreationResult Create(Type type, CreationHints creationHints)
15 | {
16 | return createFunc(type, creationHints);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/MemberAssignmentTests.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Tests
2 | {
3 | public class MemberAssignmentTests
4 | {
5 | //[Fact]
6 | //public void AttachedPropertyAssignment()
7 | //{
8 | // ICollection groups = new List();
9 | // var instance = new Window();
10 | // var sut = new Assignment(new KeyedInstance(instance), Member.FromAttached("VisualStateGroups"), groups);
11 | // sut.ExecuteAssignment();
12 |
13 | // Assert.IsAssignableFrom>(VisualStateManager.GetVisualStateGroups(instance));
14 | //}
15 |
16 | //[Fact]
17 | //public void StandardPropertyAssignment()
18 | //{
19 | // var instance = new TextBlock();
20 | // var sut = new Assignment(new KeyedInstance(instance), Member.FromStandard(tb => tb.Text), "Some text");
21 | // sut.ExecuteAssignment();
22 |
23 | // Assert.Equal("Some text", instance.Text);
24 | //}
25 | }
26 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/Model/AttachedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Tests.Model
4 | {
5 | public class AttachedEventArgs : EventArgs
6 | {
7 | public object Event { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/OmniXaml.Tests/Model/Button.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace OmniXaml.Tests.Model
4 | {
5 | public class Button : ModelObject
6 | {
7 | public Button()
8 | {
9 |
10 | }
11 |
12 | public event EventHandler Click;
13 |
14 | public void ClickButton()
15 | {
16 | Click?.Invoke(this, EventArgs.Empty);
17 | }
18 |
19 | public object Content { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/OmniXaml.Tests/Model/Collection.cs:
--------------------------------------------------------------------------------
1 | namespace OmniXaml.Tests.Model
2 | {
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 |
6 | public class Collection : Collection