using System; using System.Collections.Generic; using System.Text; using System.Xaml; using System.Reflection; using System.Runtime; using XamlBuildTask; namespace Microsoft.Build.Tasks.Xaml { class XamlNsReplacingContext : XamlSchemaContext { string localAssemblyName; string realAssemblyName; IDictionary MasterTypeList; public XamlNsReplacingContext(IEnumerable referenceAssemblies, string localAssemblyName, string realAssemblyName) : base(referenceAssemblies) { this.localAssemblyName = localAssemblyName; this.realAssemblyName = realAssemblyName; MasterTypeList = new Dictionary(); } public override XamlType GetXamlType(Type type) { if (type == null) { throw FxTrace.Exception.AsError(new ArgumentNullException("type")); } XamlNsReplacingType xamlType = null; if (!MasterTypeList.TryGetValue(type, out xamlType)) { xamlType = new XamlNsReplacingType(type, this, localAssemblyName, realAssemblyName); MasterTypeList.Add(type, xamlType); } return xamlType; } protected override XamlType GetXamlType(string xamlNamespace, string name, params XamlType[] typeArguments) { XamlType xamlType = base.GetXamlType(xamlNamespace, name, typeArguments); if (xamlType == null || xamlType.IsUnknown) { xamlNamespace = XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(xamlNamespace, this.localAssemblyName, this.realAssemblyName); xamlType = base.GetXamlType(xamlNamespace, name, typeArguments); } else if (!xamlType.UnderlyingType.Assembly.ReflectionOnly && xamlType.UnderlyingType.Assembly != typeof(object).Assembly) { // Types from XamlLanguage are live; but we want the ROL equivalent, so that we can validate // against expected member types. We do this by looking it up via its clr-namespace form. // Note this means that the resulting XamlType will only have its clr-namespace, not the XAML2006 namespace. IList namespaces = xamlType.GetXamlNamespaces(); Fx.Assert(namespaces.Contains(XamlLanguage.Xaml2006Namespace) && xamlType.TypeArguments == null, "This should only happen for XamlLanguage types, none of which are generic"); string clrNamespace = namespaces[namespaces.Count - 1]; XamlType rolType = base.GetXamlType(clrNamespace, xamlType.UnderlyingType.Name); if (rolType != null) { xamlType = rolType; } } return xamlType; } } class XamlNsReplacingType : XamlType { string localAssemblyName; string realAssemblyName; List namespaces; public XamlNsReplacingType(Type underlyingType, XamlSchemaContext context, string localAssemblyName, string realAssemblyName) : base(underlyingType, context) { this.localAssemblyName = localAssemblyName; this.realAssemblyName = realAssemblyName; namespaces = null; } public override IList GetXamlNamespaces() { if (namespaces == null) { namespaces = new List(); IList originalNamespaces = base.GetXamlNamespaces(); foreach (var ns in originalNamespaces) { namespaces.Add(XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(ns, this.localAssemblyName, this.realAssemblyName)); } } return namespaces; } } }