Nikita Tsukanov 6 years ago
parent
commit
f14aac365b
31 changed files with 827 additions and 34 deletions
  1. 3 0
      .gitmodules
  2. 1 1
      samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs
  3. 10 0
      src/Avalonia.Base/Metadata/UsableDuringInitializationAttribute.cs
  4. 2 1
      src/Avalonia.Styling/Controls/NameScopeExtensions.cs
  5. 2 0
      src/Avalonia.Visuals/Visual.cs
  6. 18 0
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  7. 1 0
      src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs
  8. 12 3
      src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
  9. 2 2
      src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
  10. 2 2
      src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs
  11. 1 1
      src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs
  12. 1 1
      src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs
  13. 47 0
      src/Markup/Avalonia.Markup.Xaml/Extensions.cs
  14. 8 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs
  15. 2 14
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs
  16. 1 1
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
  17. 2 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs
  18. 2 2
      src/Markup/Avalonia.Markup.Xaml/PortableXaml/TypeDescriptorExtensions.cs
  19. 160 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs
  20. 21 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaPropertyDescriptorEmitter.cs
  21. 61 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs
  22. 153 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  23. 4 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/README.md
  24. 79 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs
  25. 27 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs
  26. 26 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/KnownPseudoMarkupExtensionsTransformer.cs
  27. 33 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/XNameTransformer.cs
  28. 9 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/IAvaloniaXamlIlParentStackProvider.cs
  29. 15 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/IAvaloniaXamlIlXmlNamespaceInfoProviderV1.cs
  30. 121 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs
  31. 1 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github

+ 3 - 0
.gitmodules

@@ -4,3 +4,6 @@
 [submodule "nukebuild/Numerge"]
 	path = nukebuild/Numerge
 	url = https://github.com/kekekeks/Numerge.git
+[submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"]
+	path = src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github
+	url = https://github.com/kekekeks/XamlIl.git

+ 1 - 1
samples/ControlCatalog/Pages/ButtonSpinnerPage.xaml.cs

@@ -18,7 +18,7 @@ namespace ControlCatalog.Pages
             AvaloniaXamlLoader.Load(this);
         }
 
-        private void OnSpin(object sender, SpinEventArgs e)
+        public void OnSpin(object sender, SpinEventArgs e)
         {
             var spinner = (ButtonSpinner)sender;
             var txtBox = (TextBlock)spinner.Content;

+ 10 - 0
src/Avalonia.Base/Metadata/UsableDuringInitializationAttribute.cs

@@ -0,0 +1,10 @@
+using System;
+
+namespace Avalonia.Metadata
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class UsableDuringInitializationAttribute : Attribute
+    {
+        
+    }
+}

+ 2 - 1
src/Avalonia.Styling/Controls/NameScopeExtensions.cs

@@ -71,10 +71,11 @@ namespace Avalonia.Controls
         {
             Contract.Requires<ArgumentNullException>(control != null);
 
-            return control.GetSelfAndLogicalAncestors()
+            var scope = control.GetSelfAndLogicalAncestors()
                 .OfType<StyledElement>()
                 .Select(x => (x as INameScope) ?? NameScope.GetNameScope(x))
                 .FirstOrDefault(x => x != null);
+            return scope;
         }
     }
 }

+ 2 - 0
src/Avalonia.Visuals/Visual.cs

@@ -9,6 +9,7 @@ using Avalonia.Collections;
 using Avalonia.Data;
 using Avalonia.Logging;
 using Avalonia.Media;
+using Avalonia.Metadata;
 using Avalonia.Rendering;
 using Avalonia.VisualTree;
 
@@ -23,6 +24,7 @@ namespace Avalonia
     /// <see cref="IRenderer"/> to render the control. To traverse the visual tree, use the
     /// extension methods defined in <see cref="VisualExtensions"/>.
     /// </remarks>
+    [UsableDuringInitialization]
     public class Visual : StyledElement, IVisual
     {
         /// <summary>

+ 18 - 0
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@@ -15,6 +15,7 @@
         <Compile Include="Converters\ParseTypeConverter.cs" />
         <Compile Include="Converters\SetterValueTypeConverter.cs" />
         <Compile Include="Converters\TimeSpanTypeConverter.cs" />
+        <Compile Include="Extensions.cs" />
         <Compile Include="MarkupExtensions\DynamicResourceExtension.cs" />
         <Compile Include="MarkupExtensions\ResourceInclude.cs" />
         <Compile Include="MarkupExtensions\StaticResourceExtension.cs" />
@@ -50,8 +51,21 @@
         <Compile Include="Templates\TemplateContent.cs" />
         <Compile Include="Templates\TemplateLoader.cs" />
         <Compile Include="Templates\TreeDataTemplate.cs" />
+        <Compile Include="XamlIl\AvaloniaXamlIlRuntimeCompiler.cs" />
+        <Compile Include="XamlIl\CompilerExtensions\AvaloniaPropertyDescriptorEmitter.cs" />
+        <Compile Include="XamlIl\CompilerExtensions\AvaloniaXamlIlCompiler.cs" />
+        <Compile Include="XamlIl\CompilerExtensions\AvaloniaXamlIlLanguage.cs" />
+        <Compile Include="XamlIl\CompilerExtensions\Transformers\AddNameScopeRegistration.cs" />
+        <Compile Include="XamlIl\CompilerExtensions\Transformers\IgnoredDirectivesTransformer.cs" />
+        <Compile Include="XamlIl\CompilerExtensions\Transformers\KnownPseudoMarkupExtensionsTransformer.cs" />
+        <Compile Include="XamlIl\CompilerExtensions\Transformers\XNameTransformer.cs" />
+        <Compile Include="XamlIl\Runtime\IAvaloniaXamlIlParentStackProvider.cs" />
+        <Compile Include="XamlIl\Runtime\IAvaloniaXamlIlXmlNamespaceInfoProviderV1.cs" />
+        <Compile Include="XamlIl\Runtime\XamlIlRuntimeHelpers.cs" />
         <Compile Include="XamlLoadException.cs" />
         <Compile Include="PortableXaml\portable.xaml.github\src\Portable.Xaml\**\*.cs" Exclude="PortableXaml\portable.xaml.github\src\Portable.Xaml\Assembly\**\*.cs" />
+        <Compile Include="XamlIl\xamlil.github\src\XamlIl\**\*.cs" />
+        <Compile Remove="XamlIl\xamlil.github\**\obj\**\*.cs" />
     </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\Avalonia.Animation\Avalonia.Animation.csproj" />
@@ -63,6 +77,10 @@
     <ProjectReference Include="..\..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
     <ProjectReference Include="..\..\Avalonia.Styling\Avalonia.Styling.csproj" />
     <ProjectReference Include="..\Avalonia.Markup\Avalonia.Markup.csproj" />
+    <PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="XamlIl\CompilerExtensions\README.md" />
   </ItemGroup>
   <Import Project="..\..\..\build\Rx.props" />
 </Project>

+ 1 - 0
src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs

@@ -29,6 +29,7 @@ namespace Avalonia.Markup.Xaml
     /// </remarks>
     public static class AvaloniaTypeConverters
     {
+        // When adding item to that list make sure to modify AvaloniaXamlIlLanguage
         private static Dictionary<Type, Type> _converters = new Dictionary<Type, Type>()
         {
             { typeof(AvaloniaList<>), typeof(AvaloniaListConverter<>) },

+ 12 - 3
src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs

@@ -13,6 +13,7 @@ using System.Reflection;
 using System.Runtime.Serialization;
 using System.Runtime.Serialization.Json;
 using System.Text;
+using Avalonia.Markup.Xaml.XamlIl;
 
 namespace Avalonia.Markup.Xaml
 {
@@ -23,6 +24,8 @@ namespace Avalonia.Markup.Xaml
     {
         private readonly AvaloniaXamlSchemaContext _context = GetContext();
 
+        public bool EnforceCompilerForRuntimeXaml { get; set; } = true;
+        
         public bool IsDesignMode
         {
             get => _context.IsDesignMode;
@@ -137,13 +140,13 @@ namespace Avalonia.Markup.Xaml
             using (var stream = asset.stream)
             {
                 var absoluteUri = uri.IsAbsoluteUri ? uri : new Uri(baseUri, uri);
-                try
+                //try
                 {
                     return Load(stream, asset.assembly, rootInstance, absoluteUri);
                 }
-                catch (Exception e)
+                //catch (Exception e)
                 {
-                    throw new XamlLoadException("Error loading xaml at " + absoluteUri + ": " + e.Message, e);
+                    //throw new XamlLoadException("Error loading xaml at " + absoluteUri + ": " + e.Message, e);
                 }
             }
         }
@@ -179,6 +182,12 @@ namespace Avalonia.Markup.Xaml
         /// <returns>The loaded object.</returns>
         public object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null)
         {
+            if (EnforceCompilerForRuntimeXaml)
+            {
+                return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri);
+            }
+            
+            
             var readerSettings = new XamlXmlReaderSettings()
             {
                 BaseUri = uri,

+ 2 - 2
src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs

@@ -28,8 +28,8 @@ namespace Avalonia.Markup.Xaml.Converters
             var parser = new PropertyParser();
             var (ns, owner, propertyName) = parser.Parse(new CharacterReader(((string)value).AsSpan()));
             var ownerType = TryResolveOwnerByName(context, ns, owner);
-            var targetType = context.GetFirstAmbientValue<ControlTemplate>()?.TargetType ??
-                context.GetFirstAmbientValue<Style>()?.Selector?.TargetType ??
+            var targetType = context.GetFirstParent<ControlTemplate>()?.TargetType ??
+                context.GetFirstParent<Style>()?.Selector?.TargetType ??
                 typeof(Control);
             var effectiveOwner = ownerType ?? targetType;
             var property = registry.FindRegistered(effectiveOwner, propertyName);

+ 2 - 2
src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs

@@ -29,7 +29,7 @@ namespace Avalonia.Markup.Xaml.Converters
                 return new Bitmap(uri.LocalPath);
 
             var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
-            return new Bitmap(assets.Open(uri, context.GetBaseUri()));
+            return new Bitmap(assets.Open(uri, context.GetContextBaseUri()));
         }
     }
-}
+}

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs

@@ -22,7 +22,7 @@ namespace Avalonia.Markup.Xaml.Converters
         {
             var s = (string)value;
 
-            return FontFamily.Parse(s, context.GetBaseUri());
+            return FontFamily.Parse(s, context.GetContextBaseUri());
         }
     }
 }

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs

@@ -45,7 +45,7 @@ namespace Avalonia.Markup.Xaml.Converters
             if(uri.IsAbsoluteUri && uri.IsFile)
                 return new WindowIcon(uri.LocalPath);
             var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
-            return new WindowIcon(assets.Open(uri, context.GetBaseUri()));
+            return new WindowIcon(assets.Open(uri, context.GetContextBaseUri()));
         }
     }
 }

+ 47 - 0
src/Markup/Avalonia.Markup.Xaml/Extensions.cs

@@ -0,0 +1,47 @@
+using System;
+using System.ComponentModel;
+using System.Linq;
+using Avalonia.Markup.Xaml.XamlIl.Runtime;
+using Portable.Xaml.Markup;
+
+namespace Avalonia.Markup.Xaml
+{
+    internal static class Extensions
+    {
+        public static T GetService<T>(this IServiceProvider sp) => (T)sp.GetService(typeof(T));
+        
+        
+        public static Uri GetContextBaseUri(this IServiceProvider ctx)
+        {
+            var properService = ctx.GetService<IUriContext>();
+            if (properService != null)
+                return properService.BaseUri;
+            // Ugly hack with casts
+            return Portable.Xaml.ComponentModel.TypeDescriptorExtensions.GetBaseUri((ITypeDescriptorContext)ctx);
+        }
+
+        public static T GetFirstParent<T>(this IServiceProvider ctx) where T : class
+        {
+            var parentStack = ctx.GetService<IAvaloniaXamlIlParentStackProvider>();
+            if (parentStack != null)
+                return parentStack.Parents.OfType<T>().FirstOrDefault();
+            return Portable.Xaml.ComponentModel.TypeDescriptorExtensions.GetFirstAmbientValue<T>((ITypeDescriptorContext)ctx);
+        }
+        
+        public static T GetLastParent<T>(this IServiceProvider ctx) where T : class
+        {
+            var parentStack = ctx.GetService<IAvaloniaXamlIlParentStackProvider>();
+            if (parentStack != null)
+                return parentStack.Parents.OfType<T>().LastOrDefault();
+            return Portable.Xaml.ComponentModel.TypeDescriptorExtensions.GetLastOrDefaultAmbientValue<T>(
+                (ITypeDescriptorContext)ctx);
+        }
+
+        public static Type ResolveType(this IServiceProvider ctx, string namespacePrefix, string type)
+        {
+            var tr = ctx.GetService<IXamlTypeResolver>();
+            string name = string.IsNullOrEmpty(namespacePrefix) ? type : $"{namespacePrefix}:{type}";
+            return tr?.Resolve(name);
+        }
+    }
+}

+ 8 - 3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs

@@ -29,6 +29,11 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
         }
 
         public override object ProvideValue(IServiceProvider serviceProvider)
+        {
+            return ProvideTypedValue(serviceProvider);
+        }
+        
+        public IBinding ProvideTypedValue(IServiceProvider serviceProvider)
         {
             var descriptorContext = (ITypeDescriptorContext)serviceProvider;
 
@@ -49,18 +54,18 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
             };
         }
 
-        private static object GetDefaultAnchor(ITypeDescriptorContext context)
+        private static object GetDefaultAnchor(IServiceProvider context)
         {
             // If the target is not a control, so we need to find an anchor that will let us look
             // up named controls and style resources. First look for the closest IControl in
             // the context.
-            object anchor = context.GetFirstAmbientValue<IControl>();
+            object anchor = context.GetFirstParent<IControl>();
 
             // If a control was not found, then try to find the highest-level style as the XAML
             // file could be a XAML file containing only styles.
             return anchor ??
                     context.GetService<IRootObjectProvider>()?.RootObject as IStyle ??
-                    context.GetLastOrDefaultAmbientValue<IStyle>();
+                    context.GetLastParent<IStyle>();
         }
 
         public IValueConverter Converter { get; set; }

+ 2 - 14
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs

@@ -30,12 +30,11 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
 
         public override object ProvideValue(IServiceProvider serviceProvider)
         {
-            var context = (ITypeDescriptorContext)serviceProvider;
-            var provideTarget = context.GetService<IProvideValueTarget>();
+            var provideTarget = serviceProvider.GetService<IProvideValueTarget>();
 
             if (!(provideTarget.TargetObject is IResourceNode))
             {
-                _anchor = GetAnchor<IResourceNode>(context);
+                _anchor = serviceProvider.GetFirstParent<IResourceNode>();
             }
 
             return this;
@@ -56,16 +55,5 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
 
             return null;
         }
-
-        private T GetAnchor<T>(ITypeDescriptorContext context) where T : class
-        {
-            var schemaContext = context.GetService<IXamlSchemaContextProvider>().SchemaContext;
-            var ambientProvider = context.GetService<IAmbientProvider>();
-            var xamlType = schemaContext.GetXamlType(typeof(T));
-
-            // We override XamlType.CanAssignTo in BindingXamlType so the results we get back
-            // from GetAllAmbientValues aren't necessarily of the correct type.
-            return ambientProvider.GetAllAmbientValues(xamlType).OfType<T>().FirstOrDefault();
-        }
     }
 }

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs

@@ -56,7 +56,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
         public override object ProvideValue(IServiceProvider serviceProvider)
         {
             var tdc = (ITypeDescriptorContext)serviceProvider;
-            _baseUri = tdc?.GetBaseUri();
+            _baseUri = tdc?.GetContextBaseUri();
             return this;
         }
     }

+ 2 - 3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs

@@ -20,11 +20,10 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
 
         public override object ProvideValue(IServiceProvider serviceProvider)
         {
-            var tdc = (ITypeDescriptorContext)serviceProvider;
-            return new StyleInclude(tdc.GetBaseUri()) { Source = Source };
+            return new StyleInclude(serviceProvider.GetContextBaseUri()) { Source = Source };
         }
 
         public Uri Source { get; set; }
 
     }
-}
+}

+ 2 - 2
src/Markup/Avalonia.Markup.Xaml/PortableXaml/TypeDescriptorExtensions.cs

@@ -44,7 +44,7 @@ namespace Portable.Xaml.ComponentModel
             var amb = ctx.GetService<IAmbientProvider>();
             var sc = ctx.GetService<IXamlSchemaContextProvider>().SchemaContext;
 
-            // Because GetFirstAmbientValue uses XamlType.CanAssignTo it returns values that
+            // Because GetFirstParent uses XamlType.CanAssignTo it returns values that
             // aren't actually of the correct type. Use GetAllAmbientValues instead.
             return amb.GetAllAmbientValues(sc.GetXamlType(typeof(T))).OfType<T>().FirstOrDefault();
         }
@@ -98,4 +98,4 @@ namespace Portable.Xaml.ComponentModel
             public AvaloniaXamlContext Context { get; }
         }
     }
-}
+}

+ 160 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs

@@ -0,0 +1,160 @@
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions;
+using Avalonia.Platform;
+using XamlIl.Ast;
+using XamlIl.Transform;
+using XamlIl.TypeSystem;
+
+namespace Avalonia.Markup.Xaml.XamlIl
+{
+    public static class AvaloniaXamlIlRuntimeCompiler
+    {
+        private static SreTypeSystem _typeSystem;
+        private static ModuleBuilder _builder;
+        private static XamlIlLanguageTypeMappings _mappings;
+        private static XamlIlXmlnsMappings _xmlns;
+        private static AssemblyBuilder _asm;
+        private static bool _canSave;
+
+        public static void DumpRuntimeCompilationResults()
+        {
+            var saveMethod = _asm.GetType().GetMethods()
+                .FirstOrDefault(m => m.Name == "Save" && m.GetParameters().Length == 1);
+            if (saveMethod == null)
+                throw new PlatformNotSupportedException();
+            try
+            {
+                _builder.CreateGlobalFunctions();
+                saveMethod.Invoke(_asm, new Object[] {"XamlIlLoader.ildump"});
+            }
+            catch
+            {
+                //Ignore
+            }
+        }
+        
+        static void Initialize()
+        {
+            if (_typeSystem == null)
+                _typeSystem = new SreTypeSystem();
+            if (_builder == null)
+            {
+                _canSave = !AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetRuntimeInfo().IsCoreClr;
+                var name = new AssemblyName(Guid.NewGuid().ToString("N"));
+                if (_canSave)
+                {
+                    var define = AppDomain.CurrentDomain.GetType().GetMethods()
+                        .FirstOrDefault(m => m.Name == "DefineDynamicAssembly"
+                                    && m.GetParameters().Length == 3 &&
+                                    m.GetParameters()[2].ParameterType == typeof(string));
+                    if (define != null)
+                        _asm = (AssemblyBuilder)define.Invoke(AppDomain.CurrentDomain, new object[]
+                        {
+                            name, (AssemblyBuilderAccess)3,
+                            Path.GetDirectoryName(typeof(AvaloniaXamlIlRuntimeCompiler).Assembly.GetModules()[0]
+                                .FullyQualifiedName)
+                        });
+                    else
+                        _canSave = false;
+                }
+                
+                if(_asm == null)
+                    _asm = AssemblyBuilder.DefineDynamicAssembly(name,
+                        AssemblyBuilderAccess.RunAndCollect);
+                
+                _builder = _asm.DefineDynamicModule("XamlIlLoader.ildump");
+                
+            }
+
+            if (_mappings == null)
+                _mappings = AvaloniaXamlIlLanguage.Configure(_typeSystem);
+            if (_xmlns == null)
+                _xmlns = XamlIlXmlnsMappings.Resolve(_typeSystem, _mappings);
+        }
+
+        public static object Load(Stream stream, Assembly localAssembly, object rootInstance, Uri uri)
+        {
+            var success = false;
+            try
+            {
+                var rv = LoadCore(stream, localAssembly, rootInstance, uri);
+                success = true;
+                return rv;
+            }
+            finally
+            {
+                if(!success && _canSave)
+                    DumpRuntimeCompilationResults();
+            }
+        }
+        
+        static object LoadCore(Stream stream, Assembly localAssembly, object rootInstance, Uri uri)
+        {
+            string xaml;
+            using (var sr = new StreamReader(stream))
+                xaml = sr.ReadToEnd();
+            Initialize();
+            var asm = localAssembly == null ? null : _typeSystem.GetAssembly(localAssembly);
+            var compiler = new AvaloniaXamlIlCompiler(new XamlIlTransformerConfiguration(_typeSystem, asm,
+                _mappings, _xmlns, CustomValueConverter));
+            var tb = _builder.DefineType("Builder_" + Guid.NewGuid().ToString("N") + "_" + uri);
+
+            IXamlIlType overrideType = null;
+            if (rootInstance != null)
+            {
+                overrideType = _typeSystem.GetType(rootInstance.GetType());
+            }
+
+            compiler.ParseAndCompile(xaml, uri?.ToString(), _typeSystem.CreateTypeBuilder(tb), overrideType);
+            var created = tb.CreateTypeInfo();
+
+            var isp = Expression.Parameter(typeof(IServiceProvider));
+            if (rootInstance == null)
+            {
+                var createCb = Expression.Lambda<Func<IServiceProvider, object>>(
+                    Expression.Convert(Expression.Call(
+                        created.GetMethod(AvaloniaXamlIlCompiler.BuildName), isp), typeof(object)), isp).Compile();
+                return createCb(null);
+            }
+            else
+            {
+                var epar = Expression.Parameter(typeof(object));
+                var populate = created.GetMethod(AvaloniaXamlIlCompiler.PopulateName);
+                isp = Expression.Parameter(typeof(IServiceProvider));
+                var populateCb = Expression.Lambda<Action<IServiceProvider, object>>(
+                    Expression.Call(populate, isp, Expression.Convert(epar, populate.GetParameters()[1].ParameterType)),
+                    isp, epar).Compile();
+                populateCb(null, rootInstance);
+                return rootInstance;
+            }
+        }
+
+        private static bool CustomValueConverter(XamlIlAstTransformationContext context,
+            IXamlIlAstValueNode node, IXamlIlType type, out IXamlIlAstValueNode result)
+        {
+            if (type.FullName == "System.TimeSpan" 
+                && node is XamlIlAstTextNode tn
+                && !tn.Text.Contains(":"))
+            {
+                var seconds = double.Parse(tn.Text, CultureInfo.InvariantCulture);
+                result = new XamlIlStaticOrTargetedReturnMethodCallNode(tn,
+                    type.FindMethod("FromSeconds", type, false, context.Configuration.WellKnownTypes.Double),
+                    new[]
+                    {
+                        new XamlIlConstantNode(tn, context.Configuration.WellKnownTypes.Double, seconds)
+                    });
+                return true;
+            }
+
+            result = null;
+            return false;
+        }
+    }
+}

+ 21 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaPropertyDescriptorEmitter.cs

@@ -0,0 +1,21 @@
+using System.Linq;
+using XamlIl.Transform;
+using XamlIl.TypeSystem;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
+{
+    public class AvaloniaPropertyDescriptorEmitter
+    {
+        public static bool Emit(XamlIlEmitContext context, IXamlIlEmitter emitter, IXamlIlProperty property)
+        {
+            var type = (property.Getter ?? property.Setter).DeclaringType;
+            var name = property.Name + "Property";
+            var found = type.Fields.FirstOrDefault(f => f.IsStatic && f.Name == name);
+            if (found == null)
+                return false;
+
+            emitter.Ldsfld(found);
+            return true;
+        }
+    }
+}

+ 61 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs

@@ -0,0 +1,61 @@
+using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;
+using XamlIl;
+using XamlIl.Ast;
+using XamlIl.Parsers;
+using XamlIl.Transform;
+using XamlIl.Transform.Transformers;
+using XamlIl.TypeSystem;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
+{
+    public class AvaloniaXamlIlCompiler : XamlIlCompiler
+    {
+        public AvaloniaXamlIlCompiler(XamlIlTransformerConfiguration configuration) : base(configuration, true)
+        {
+            
+            // Before everything else
+            
+            Transformers.Insert(0, new XNameTransformer());
+            Transformers.Insert(1, new IgnoredDirectivesTransformer());
+            
+            
+            // Targeted
+            
+            Transformers.Insert(Transformers.FindIndex(x => x is XamlIlXamlPropertyValueTransformer),
+                new KnownPseudoMarkupExtensionsTransformer());
+            
+            // After everything else
+            
+            Transformers.Add(new AddNameScopeRegistration());
+
+        }
+
+        public const string PopulateName = "__AvaloniaXamlIlPopulate";
+        public const string BuildName = "__AvaloniaXamlIlBuild";
+        
+        public void ParseAndCompile(string xaml, string baseUri, IXamlIlTypeBuilder tb, IXamlIlType overrideRootType)
+        {
+            var parsed = XDocumentXamlIlParser.Parse(xaml);
+            
+            if (overrideRootType != null)
+            {
+                var rootObject = (XamlIlAstObjectNode)parsed.Root;
+
+                var originalType = XamlIlTypeReferenceResolver.ResolveType(CreateTransformationContext(parsed, true),
+                    (XamlIlAstXmlTypeReference)rootObject.Type, true);
+
+                if (!originalType.IsAssignableFrom(overrideRootType))
+                    throw new XamlIlLoadException(
+                        $"Unable to substitute {originalType.GetFqn()} with {overrideRootType.GetFqn()}", rootObject);
+                rootObject.Type = new XamlIlAstClrTypeReference(rootObject, overrideRootType);
+            }
+
+            Transform(parsed);
+            Compile(parsed, tb, PopulateName, BuildName,
+                "__AvaloniaXamlIlContext", "__AvaloniaXamlIlNsInfo", baseUri);
+            
+        }
+        
+        
+    }
+}

+ 153 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@@ -0,0 +1,153 @@
+using System.Collections.Generic;
+using System.Linq;
+using XamlIl.Transform;
+using XamlIl.TypeSystem;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
+{
+    /*
+        This file is used in the build task.
+        ONLY use types from netstandard and XamlIl. NO dependencies on Avalonia are allowed. Only strings.
+        No, nameof isn't welcome here either
+     */
+    
+    class AvaloniaXamlIlLanguage
+    {
+        public static XamlIlLanguageTypeMappings Configure(IXamlIlTypeSystem typeSystem)
+        {
+            var runtimeHelpers = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers");
+            var assignBindingAttribute = typeSystem.GetType("Avalonia.Data.AssignBindingAttribute");
+            var bindingType = typeSystem.GetType("Avalonia.Data.IBinding");
+            var rv = new XamlIlLanguageTypeMappings(typeSystem)
+            {
+                SupportInitialize = typeSystem.GetType("Avalonia.ISupportInitialize"),
+                XmlnsAttributes =
+                {
+                    typeSystem.GetType("Avalonia.Metadata.XmlnsDefinitionAttribute"),
+                    typeSystem.FindType("Portable.Xaml.Markup.XmlnsDefinitionAttribute")
+                },
+                ContentAttributes =
+                {
+                    typeSystem.GetType("Avalonia.Metadata.ContentAttribute")
+                },
+                ProvideValueTarget = typeSystem.GetType("Portable.Xaml.Markup.IProvideValueTarget"),
+                RootObjectProvider = typeSystem.GetType("Portable.Xaml.IRootObjectProvider"),
+                UriContextProvider = typeSystem.GetType("Portable.Xaml.Markup.IUriContext"),
+                ParentStackProvider =
+                    typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlParentStackProvider"),
+
+                XmlNamespaceInfoProvider =
+                    typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlXmlNamespaceInfoProvider"),
+                DeferredContentPropertyAttributes = {typeSystem.GetType("Avalonia.Metadata.TemplateContentAttribute")},
+                DeferredContentExecutorCustomization =
+                    runtimeHelpers.FindMethod(m => m.Name == "DeferredTransformationFactoryV1"),
+                UsableDuringInitializationAttributes =
+                {
+                    typeSystem.GetType("Portable.Xaml.Markup.UsableDuringInitializationAttribute"),
+                    typeSystem.GetType("Avalonia.Metadata.UsableDuringInitializationAttribute"),
+                },
+                MarkupExtensionCustomResultTypes =
+                {
+                    bindingType
+                },
+                MarkupExtensionCustomResultHandler =
+                    runtimeHelpers.FindMethod(m => m.Name == "ApplyNonMatchingMarkupExtensionV1"),
+                InnerServiceProviderFactoryMethod =
+                    runtimeHelpers.FindMethod(m => m.Name == "CreateInnerServiceProviderV1"),
+                ShouldIgnoreMarkupExtensionCustomResultForProperty = (prop, customType) =>
+                {
+                    if (customType.Equals(bindingType) &&
+                        prop.CustomAttributes.Any(a => a.Type.Equals(assignBindingAttribute)))
+                        return true;
+                    return false;
+                },
+                ProvideValueTargetPropertyEmitter = AvaloniaPropertyDescriptorEmitter.Emit,
+            };
+            rv.CustomAttributeResolver = new AttributeResolver(typeSystem, rv);
+            return rv;
+        }
+
+        class AttributeResolver : IXamlIlCustomAttributeResolver
+        {
+            private readonly IXamlIlType _typeConverterAttribute;
+
+            private readonly List<KeyValuePair<IXamlIlType, IXamlIlType>> _converters =
+                new List<KeyValuePair<IXamlIlType, IXamlIlType>>();
+
+            private readonly IXamlIlType _avaloniaList;
+            private readonly IXamlIlType _avaloniaListConverter;
+
+
+            public AttributeResolver(IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings)
+            {
+                _typeConverterAttribute = mappings.TypeConverterAttributes.First();
+
+                void AddType(IXamlIlType type, IXamlIlType conv) 
+                    => _converters.Add(new KeyValuePair<IXamlIlType, IXamlIlType>(type, conv));
+
+                void Add(string type, string conv)
+                    => AddType(typeSystem.GetType(type), typeSystem.GetType(conv));
+                
+                
+                Add("Avalonia.AvaloniaProperty","Avalonia.Markup.Xaml.Converters.AvaloniaPropertyTypeConverter");
+                Add("Avalonia.Media.Imaging.IBitmap","Avalonia.Markup.Xaml.Converters.BitmapTypeConverter");
+                var ilist = typeSystem.GetType("System.Collections.Generic.IList`1");
+                AddType(ilist.MakeGenericType(typeSystem.GetType("Avalonia.Point")),
+                    typeSystem.GetType("Avalonia.Markup.Xaml.Converters.PointsListTypeConverter"));
+                Add("Avalonia.Controls.Templates.IMemberSelector",
+                    "Avalonia.Markup.Xaml.Converters.MemberSelectorTypeConverter");
+                Add("Avalonia.Styling.Selector","Avalonia.Markup.Xaml.Converters.SelectorTypeConverter");
+                Add("Avalonia.Controls.WindowIcon","Avalonia.Markup.Xaml.Converters.IconTypeConverter");
+                Add("System.Globalization.CultureInfo", "System.ComponentModel.CultureInfoConverter");
+                Add("System.Uri", "Avalonia.Markup.Xaml.Converters.AvaloniaUriTypeConverter");
+                Add("System.TimeSpan", "Avalonia.Markup.Xaml.Converters.TimeSpanTypeConverter");
+                Add("Avalonia.Media.FontFamily","Avalonia.Markup.Xaml.Converters.FontFamilyTypeConverter");
+                _avaloniaList = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
+                _avaloniaListConverter = typeSystem.GetType("Avalonia.Collections.AvaloniaListConverter`1");
+            }
+
+            IXamlIlType LookupConverter(IXamlIlType type)
+            {
+                foreach(var p in _converters)
+                    if (p.Key.Equals(type))
+                        return p.Value;
+                if (type.GenericTypeDefinition?.Equals(_avaloniaList) == true)
+                    return _avaloniaListConverter.MakeGenericType(type.GenericArguments[0]);
+                return null;
+            }
+
+            class ConstructedAttribute : IXamlIlCustomAttribute
+            {
+                public bool Equals(IXamlIlCustomAttribute other) => false;
+                
+                public IXamlIlType Type { get; }
+                public List<object> Parameters { get; }
+                public Dictionary<string, object> Properties { get; }
+
+                public ConstructedAttribute(IXamlIlType type, List<object> parameters, Dictionary<string, object> properties)
+                {
+                    Type = type;
+                    Parameters = parameters ?? new List<object>();
+                    Properties = properties ?? new Dictionary<string, object>();
+                }
+            }
+            
+            public IXamlIlCustomAttribute GetCustomAttribute(IXamlIlType type, IXamlIlType attributeType)
+            {
+                if (attributeType.Equals(_typeConverterAttribute))
+                {
+                    var conv = LookupConverter(type);
+                    if (conv != null)
+                        return new ConstructedAttribute(_typeConverterAttribute, new List<object>() {conv}, null);
+                }
+
+                return null;
+            }
+
+            public IXamlIlCustomAttribute GetCustomAttribute(IXamlIlProperty property, IXamlIlType attributeType)
+            {
+                return null;
+            }
+        }
+    }
+}

+ 4 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/README.md

@@ -0,0 +1,4 @@
+### Important
+
+Only use XamlIl and netstandard types here since these sources will be later
+used by MSBuild task

+ 79 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs

@@ -0,0 +1,79 @@
+using XamlIl.Ast;
+using XamlIl.Transform;
+using XamlIl.TypeSystem;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
+{
+    public class AddNameScopeRegistration : IXamlIlAstTransformer
+    {
+        public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node)
+        {
+            if (node is XamlIlPropertyAssignmentNode pa
+                && pa.Property.Name == "Name"
+                && pa.Property.Setter.DeclaringType.FullName == "Avalonia.StyledElement")
+            {
+                return new ScopeRegistrationNode(pa);
+
+            }
+
+            return node;
+        }
+
+        class ScopeRegistrationNode : XamlIlAstNode, IXamlIlAstManipulationNode, IXamlIlAstEmitableNode
+        {
+            public IXamlIlAstValueNode Value { get; set; }
+            private IXamlIlProperty _property;
+
+            public ScopeRegistrationNode(XamlIlPropertyAssignmentNode pa) : base(pa)
+            {
+                _property = pa.Property;
+                Value = pa.Value;
+            }
+
+            public override void VisitChildren(XamlIlAstVisitorDelegate visitor)
+                => Value = (IXamlIlAstValueNode)Value.Visit(visitor);
+
+            public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
+            {
+                using (var nameLoc = context.GetLocal(context.Configuration.WellKnownTypes.String))
+                using (var targetLoc = context.GetLocal(context.Configuration.WellKnownTypes.Object))
+
+                {
+                    var exts = context.Configuration.TypeSystem.GetType("Avalonia.Controls.NameScopeExtensions");
+                    var findNameScope = exts.FindMethod(m => m.Name == "FindNameScope");
+                    var registerMethod = findNameScope.ReturnType.FindMethod(m => m.Name == "Register");
+                    var exit = codeGen.DefineLabel();
+                    var call = codeGen.DefineLabel();
+                    
+                    context.Emit(Value, codeGen, _property.PropertyType);
+                    
+                    codeGen
+                        // var name = {EmitName()}
+                        .Stloc(nameLoc.Local)
+                        // var target = {target}
+                        .Dup()
+                        .Stloc(targetLoc.Local)
+                        // {target}.Name = name
+                        .Dup()
+                        .Ldloc(nameLoc.Local)
+                        .EmitCall(_property.Setter)
+                        // var scope = {target}.FindNameScope()
+                        .EmitCall(findNameScope)
+                        // if({scope} != null) goto call;
+                        .Dup()
+                        .Brtrue(call)
+                        // goto: exit
+                        .Pop()
+                        .Br(exit)
+                        // call: {scope}.Register(name, target);
+                        .MarkLabel(call)
+                        .Ldloc(nameLoc.Local)
+                        .Ldloc(targetLoc.Local)
+                        .EmitCall(registerMethod)
+                        .MarkLabel(exit);
+                }
+                return XamlIlNodeEmitResult.Void;
+            }
+        }
+    }
+}

+ 27 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/IgnoredDirectivesTransformer.cs

@@ -0,0 +1,27 @@
+using System.Linq;
+using XamlIl;
+using XamlIl.Ast;
+using XamlIl.Transform;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
+{
+    public class IgnoredDirectivesTransformer : IXamlIlAstTransformer
+    {
+        public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node)
+        {
+            if (node is XamlIlAstObjectNode no)
+            {
+                foreach (var d in no.Children.OfType<XamlIlAstXmlDirective>().ToList())
+                {
+                    if (d.Namespace == XamlNamespaces.Xaml2006)
+                    {
+                        if (d.Name == "Class")
+                            no.Children.Remove(d);
+                    }
+                }
+            }
+
+            return node;
+        }
+    }
+}

+ 26 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/KnownPseudoMarkupExtensionsTransformer.cs

@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using XamlIl.Ast;
+using XamlIl.Transform;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
+{
+    public class KnownPseudoMarkupExtensionsTransformer : IXamlIlAstTransformer
+    {
+        private static readonly List<string> s_knownPseudoExtensions = new List<string>
+        {
+            "Avalonia.Data.TemplateBinding",
+            "Avalonia.Data.MultiBinding",
+        };
+        
+        public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node)
+        {
+            if (node is XamlIlAstXamlPropertyValueNode pn
+                && pn.Values.Count == 1
+                && s_knownPseudoExtensions.Contains(pn.Values[0].Type.GetClrType().FullName))
+                return new XamlIlMarkupExtensionNode(node, pn.Property.GetClrProperty(),
+                    null, pn.Values[0], null);
+            else
+                return node;
+        }
+    }
+}

+ 33 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/XNameTransformer.cs

@@ -0,0 +1,33 @@
+using XamlIl;
+using XamlIl.Ast;
+using XamlIl.Transform;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
+{
+    public class XNameTransformer : IXamlIlAstTransformer
+    {
+        
+        /// <summary>
+        /// Converts x:Name directives to regular Name assignments
+        /// </summary>
+        /// <returns></returns>
+        public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node)
+        {
+            if (node is XamlIlAstObjectNode on)
+            {
+                foreach (var ch in on.Children)
+                {
+                    if (ch is XamlIlAstXmlDirective d
+                        && d.Namespace == XamlNamespaces.Xaml2006
+                        && d.Name == "Name")
+                        return new XamlIlAstXamlPropertyValueNode(d,
+                            new XamlIlAstNamePropertyReference(d, on.Type, "Name", on.Type),
+                            d.Values);
+                }
+            }
+
+            return node;
+            
+        }
+    }
+}

+ 9 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/IAvaloniaXamlIlParentStackProvider.cs

@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace Avalonia.Markup.Xaml.XamlIl.Runtime
+{
+    public interface IAvaloniaXamlIlParentStackProvider
+    {
+        IEnumerable<object> Parents { get; }
+    }
+}

+ 15 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/IAvaloniaXamlIlXmlNamespaceInfoProviderV1.cs

@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace Avalonia.Markup.Xaml.XamlIl.Runtime
+{
+    public interface IAvaloniaXamlIlXmlNamespaceInfoProvider
+    {
+        IReadOnlyDictionary<string, IReadOnlyList<AvaloniaXamlIlXmlNamespaceInfo>> XmlNamespaces { get; }
+    }
+    
+    public class AvaloniaXamlIlXmlNamespaceInfo
+    {
+        public string ClrNamespace { get; set; }
+        public string ClrAssemblyName { get; set; }
+    }
+}

+ 121 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Avalonia.Controls;
+using Avalonia.Data;
+using Portable.Xaml.Markup;
+// ReSharper disable UnusedMember.Global
+// ReSharper disable UnusedParameter.Global
+
+namespace Avalonia.Markup.Xaml.XamlIl.Runtime
+{
+    public static class XamlIlRuntimeHelpers
+    {
+        public static Func<IServiceProvider, object> DeferredTransformationFactoryV1(Func<IServiceProvider, object> builder,
+            IServiceProvider provider)
+        {
+            // We need to preserve the first IResourceNode from the parent XAML,
+            // so Static/DynamicResource extensions can get it
+            var resourceNode = provider.GetService<IAvaloniaXamlIlParentStackProvider>().Parents.OfType<IResourceNode>()
+                .FirstOrDefault();
+
+            return sp => builder(new DeferredParentServiceProvider(sp, resourceNode));
+        }
+
+        class DeferredParentServiceProvider : IAvaloniaXamlIlParentStackProvider, IServiceProvider
+        {
+            private readonly IServiceProvider _parentProvider;
+            private readonly IResourceNode _parentResourceNode;
+
+            public DeferredParentServiceProvider(IServiceProvider parentProvider, IResourceNode parentResourceNode)
+            {
+                _parentProvider = parentProvider;
+                _parentResourceNode = parentResourceNode;
+            }
+
+            public IEnumerable<object> Parents => GetParents();
+
+            IEnumerable<object> GetParents()
+            {
+                if(_parentResourceNode == null)
+                    yield break;
+                yield return _parentResourceNode;
+            }
+
+            public object GetService(Type serviceType)
+            {
+                if (serviceType == typeof(IAvaloniaXamlIlParentStackProvider))
+                    return this;
+                return _parentProvider?.GetService(serviceType);
+            }
+        }
+
+
+        public static void ApplyNonMatchingMarkupExtensionV1(object target, object property, IServiceProvider prov,
+            object value)
+        {
+            if (value is IBinding b)
+            {
+                if (property is AvaloniaProperty p)
+                    ((AvaloniaObject)target).Bind(p, b);
+                else
+                    throw new ArgumentException("Attempt to apply binding to non-avalonia property " + property);
+            }
+            else
+                throw new ArgumentException("Don't know what to do with " + value.GetType());
+        }
+
+        public static IServiceProvider CreateInnerServiceProviderV1(IServiceProvider compiled) 
+            => new InnerServiceProvider(compiled);
+       
+        class InnerServiceProvider : IServiceProvider
+        {
+            private readonly IServiceProvider _compiledProvider;
+            private XamlTypeResolver _resolver;
+
+            public InnerServiceProvider(IServiceProvider compiledProvider)
+            {
+                _compiledProvider = compiledProvider;
+            }
+            public object GetService(Type serviceType)
+            {
+                if (serviceType == typeof(IXamlTypeResolver))
+                    return _resolver ?? (_resolver = new XamlTypeResolver(
+                               _compiledProvider.GetService<IAvaloniaXamlIlXmlNamespaceInfoProvider>()));
+                return null;
+            }
+        }
+
+        class XamlTypeResolver : IXamlTypeResolver
+        {
+            private readonly IAvaloniaXamlIlXmlNamespaceInfoProvider _nsInfo;
+
+            public XamlTypeResolver(IAvaloniaXamlIlXmlNamespaceInfoProvider nsInfo)
+            {
+                _nsInfo = nsInfo;
+            }
+            
+            public Type Resolve(string qualifiedTypeName)
+            {
+                var sp = qualifiedTypeName.Split(new[] {':'}, 2);
+                var (ns, name) = sp.Length == 1 ? ("", qualifiedTypeName) : (sp[0], sp[1]);
+                var namespaces = _nsInfo.XmlNamespaces;
+                var dic = (Dictionary<string, IReadOnlyList<AvaloniaXamlIlXmlNamespaceInfo>>)namespaces;
+                if (!namespaces.TryGetValue(ns, out var lst))
+                    throw new ArgumentException("Unable to resolve namespace for type " + qualifiedTypeName);
+                foreach (var entry in lst)
+                {
+                    var asm = Assembly.Load(new AssemblyName(entry.ClrAssemblyName));
+                    var resolved = asm.GetType(entry.ClrNamespace + "." + name);
+                    if (resolved != null)
+                        return resolved;
+                }
+
+                throw new ArgumentException(
+                    $"Unable to resolve type {qualifiedTypeName} from any of the following locations: " +
+                    string.Join(",", lst.Select(e => $"`{e.ClrAssemblyName}:{e.ClrNamespace}.{name}`")));
+            }
+        }
+    }
+}

+ 1 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github

@@ -0,0 +1 @@
+Subproject commit 89bc4d268d7ee48d0907cec24175a99759d0bc4a