e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
169 lines
5.8 KiB
C#
169 lines
5.8 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
|
|
namespace System.Xaml.Hosting
|
|
{
|
|
using System;
|
|
using System.CodeDom.Compiler;
|
|
using System.Collections.Generic;
|
|
using System.Configuration;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Runtime;
|
|
using System.Text;
|
|
using System.Web;
|
|
using System.Web.Compilation;
|
|
using System.Web.Hosting;
|
|
using System.Xaml;
|
|
using System.Xaml.Hosting.Configuration;
|
|
using System.Xml;
|
|
|
|
[BuildProviderAppliesTo(BuildProviderAppliesTo.Web)]
|
|
public class XamlBuildProvider : BuildProvider
|
|
{
|
|
IXamlBuildProviderExtension xamlBuildProviderExtension;
|
|
static volatile IXamlBuildProviderExtensionFactory xamlBuildProviderExtensionFactory;
|
|
|
|
internal new string VirtualPath
|
|
{
|
|
get { return base.VirtualPath; }
|
|
}
|
|
|
|
public override void GenerateCode(AssemblyBuilder assemblyBuilder)
|
|
{
|
|
XamlType rootXamlType = GetRootXamlType();
|
|
|
|
this.GetXamlBuildProviderExtension(rootXamlType);
|
|
|
|
if (this.xamlBuildProviderExtension != null)
|
|
{
|
|
using (Stream xamlStream = base.OpenStream())
|
|
{
|
|
this.xamlBuildProviderExtension.GenerateCode(assemblyBuilder, xamlStream, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fx.Tag.Throws(typeof(TypeLoadException), "The type resolution of the root element failed.")]
|
|
public override Type GetGeneratedType(CompilerResults results)
|
|
{
|
|
if (this.xamlBuildProviderExtension != null)
|
|
{
|
|
Type result = this.xamlBuildProviderExtension.GetGeneratedType(results);
|
|
if (result != null)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
XamlType rootXamlType = GetRootXamlType();
|
|
if (rootXamlType.IsUnknown)
|
|
{
|
|
StringBuilder typeName = new StringBuilder();
|
|
AppendTypeName(rootXamlType, typeName);
|
|
throw FxTrace.Exception.AsError(new TypeLoadException(SR.CouldNotResolveType(typeName)));
|
|
}
|
|
return rootXamlType.UnderlyingType;
|
|
}
|
|
catch (XamlParseException ex)
|
|
{
|
|
throw FxTrace.Exception.AsError(new HttpCompileException(ex.Message, ex));
|
|
}
|
|
}
|
|
|
|
public override BuildProviderResultFlags GetResultFlags(CompilerResults results)
|
|
{
|
|
return BuildProviderResultFlags.ShutdownAppDomainOnChange;
|
|
}
|
|
|
|
private void AppendTypeName(XamlType xamlType, StringBuilder sb)
|
|
{
|
|
if (!string.IsNullOrEmpty(xamlType.PreferredXamlNamespace))
|
|
{
|
|
sb.Append("{");
|
|
sb.Append(xamlType.PreferredXamlNamespace);
|
|
sb.Append("}");
|
|
}
|
|
sb.Append(xamlType.Name);
|
|
if (xamlType.IsGeneric)
|
|
{
|
|
sb.Append("(");
|
|
for (int i = 0; i < xamlType.TypeArguments.Count; i++)
|
|
{
|
|
AppendTypeName(xamlType.TypeArguments[i], sb);
|
|
if (i < xamlType.TypeArguments.Count - 1)
|
|
{
|
|
sb.Append(", ");
|
|
}
|
|
}
|
|
sb.Append(")");
|
|
}
|
|
}
|
|
|
|
XamlType GetRootXamlType()
|
|
{
|
|
try
|
|
{
|
|
using (Stream xamlStream = base.OpenStream())
|
|
{
|
|
XmlReader xmlReader = XmlReader.Create(xamlStream);
|
|
XamlXmlReader xamlReader = new XamlXmlReader(xmlReader);
|
|
|
|
// Read to the root object
|
|
while (xamlReader.Read())
|
|
{
|
|
if (xamlReader.NodeType == XamlNodeType.StartObject)
|
|
{
|
|
return xamlReader.Type;
|
|
}
|
|
}
|
|
throw FxTrace.Exception.AsError(new HttpCompileException(SR.UnexpectedEof));
|
|
}
|
|
}
|
|
catch (XamlParseException ex)
|
|
{
|
|
throw FxTrace.Exception.AsError(new HttpCompileException(ex.Message, ex));
|
|
}
|
|
}
|
|
|
|
void GetXamlBuildProviderExtension(XamlType rootXamlType)
|
|
{
|
|
if (rootXamlType.UnderlyingType == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.GetXamlBuildProviderExtensionFactory(rootXamlType);
|
|
|
|
if (xamlBuildProviderExtensionFactory != null)
|
|
{
|
|
this.xamlBuildProviderExtension = xamlBuildProviderExtensionFactory.GetXamlBuildProviderExtension();
|
|
}
|
|
}
|
|
|
|
void GetXamlBuildProviderExtensionFactory(XamlType rootXamlType)
|
|
{
|
|
if (xamlBuildProviderExtensionFactory != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the HttpHandler type
|
|
Type httpHandlerType;
|
|
XamlHostingConfiguration.TryGetHttpHandlerType(this.VirtualPath, rootXamlType.UnderlyingType, out httpHandlerType);
|
|
|
|
if (httpHandlerType != null && typeof(IXamlBuildProviderExtensionFactory).IsAssignableFrom(httpHandlerType))
|
|
{
|
|
xamlBuildProviderExtensionFactory = (IXamlBuildProviderExtensionFactory)Activator.CreateInstance(httpHandlerType,
|
|
BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
|
null, null, null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|