|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using Microsoft.Web.XmlTransform.Properties;
namespace Microsoft.Web.XmlTransform
{
internal class NamedTypeFactory
{
private string relativePathRoot;
private List<Registration> registrations = new List<Registration>();
internal NamedTypeFactory(string relativePathRoot) {
this.relativePathRoot = relativePathRoot;
CreateDefaultRegistrations();
}
private void CreateDefaultRegistrations() {
AddAssemblyRegistration(GetType().Assembly, GetType().Namespace);
}
internal void AddAssemblyRegistration(Assembly assembly, string nameSpace) {
registrations.Add(new Registration(assembly, nameSpace));
}
internal void AddAssemblyRegistration(string assemblyName, string nameSpace) {
registrations.Add(new AssemblyNameRegistration(assemblyName, nameSpace));
}
internal void AddPathRegistration(string path, string nameSpace) {
if (!Path.IsPathRooted(path)) {
// Resolve a relative path
path = Path.Combine(Path.GetDirectoryName(relativePathRoot), path);
}
registrations.Add(new PathRegistration(path, nameSpace));
}
internal ObjectType Construct<ObjectType>(string typeName) where ObjectType : class {
if (!String.IsNullOrEmpty(typeName)) {
Type type = GetType(typeName);
if (type == null) {
throw new XmlTransformationException(string.Format(System.Globalization.CultureInfo.CurrentCulture,Resources.XMLTRANSFORMATION_UnknownTypeName, typeName, typeof(ObjectType).Name));
}
else if (!type.IsSubclassOf(typeof(ObjectType))) {
throw new XmlTransformationException(string.Format(System.Globalization.CultureInfo.CurrentCulture,Resources.XMLTRANSFORMATION_IncorrectBaseType, type.FullName, typeof(ObjectType).Name));
}
else {
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor == null) {
throw new XmlTransformationException(string.Format(System.Globalization.CultureInfo.CurrentCulture,Resources.XMLTRANSFORMATION_NoValidConstructor, type.FullName));
}
else {
return constructor.Invoke(new object[] { }) as ObjectType;
}
}
}
return null;
}
private Type GetType(string typeName) {
Type foundType = null;
foreach (Registration registration in registrations) {
if (registration.IsValid) {
Type regType = registration.Assembly.GetType(String.Concat(registration.NameSpace, ".", typeName));
if (regType != null) {
if (foundType == null) {
foundType = regType;
}
else {
throw new XmlTransformationException(string.Format(System.Globalization.CultureInfo.CurrentCulture,Resources.XMLTRANSFORMATION_AmbiguousTypeMatch, typeName));
}
}
}
}
return foundType;
}
private class Registration
{
private Assembly assembly = null;
private string nameSpace;
public Registration(Assembly assembly, string nameSpace) {
this.assembly = assembly;
this.nameSpace = nameSpace;
}
public bool IsValid {
get {
return assembly != null;
}
}
public string NameSpace {
get {
return nameSpace;
}
}
public Assembly Assembly {
get {
return assembly;
}
}
}
private class AssemblyNameRegistration : Registration
{
public AssemblyNameRegistration(string assemblyName, string nameSpace)
: base(Assembly.Load(assemblyName), nameSpace) {
}
}
private class PathRegistration : Registration
{
public PathRegistration(string path, string nameSpace)
: base(Assembly.LoadFrom(path), nameSpace) {
}
}
}
}
|