using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;
using System.IO;
using System.Linq;
using Microsoft.Win32;
using System.Threading;
using System.Security.Permissions;
using System.Security;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
public delegate void AssemblyResolveEventHandler(object s, AssemblyResolveEventArgs e);
public class AppDomainTypeResolver : MarshalByRefObject, ITypeResolver
{
private readonly AppDomain _domain;
private string baseDir;
public event AssemblyResolveEventHandler AssemblyResolve;
public static AppDomainTypeResolver GetIntoNewAppDomain(string baseDir)
{
AppDomainSetup info = new AppDomainSetup();
info.ApplicationBase = Environment.CurrentDirectory;
AppDomain domain = AppDomain.CreateDomain("AppDomainTypeResolver", null, info, new PermissionSet(PermissionState.Unrestricted));
AppDomainTypeResolver resolver = (AppDomainTypeResolver)domain.CreateInstanceAndUnwrap(typeof(AppDomainTypeResolver).Assembly.FullName,
typeof(AppDomainTypeResolver).FullName, false, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, new object[] { domain, baseDir }, null, null, null);
return resolver;
}
Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// Cerco di risolvere automaticamente
AssemblyName name = new AssemblyName(args.Name);
string fileName = Path.Combine(this.baseDir, name.Name + ".exe");
if (!File.Exists(fileName))
fileName = Path.Combine(this.baseDir, name.Name + ".dll");
// Carico il percorso autocalcolato
if (File.Exists(fileName))
return Assembly.LoadFile(fileName);
if (AssemblyResolve != null)
{
AssemblyResolveEventArgs e = new AssemblyResolveEventArgs(args.Name, this.baseDir);
AssemblyResolve(this, e);
if (!String.IsNullOrEmpty(e.Location) && File.Exists(e.Location))
return Assembly.LoadFile(e.Location);
}
return null;
}
public static void DestroyResolver(AppDomainTypeResolver resolver)
{
if (resolver == null) throw new ArgumentNullException("resolver");
ThreadPool.QueueUserWorkItem(delegate
{
AppDomain.Unload(resolver.Domain);
});
}
protected AppDomainTypeResolver(AppDomain domain, string baseDir)
{
_domain = domain;
this.baseDir = baseDir;
domain.AssemblyResolve += new ResolveEventHandler(domain_AssemblyResolve);
}
public BamlAssembly LoadAssembly(AssemblyName asm)
{
//return new BamlAssembly(Assembly.Load(asm));
return new BamlAssembly(_domain.Load(asm));
}
public BamlAssembly LoadAssembly(string location)
{
Assembly asm = Assembly.LoadFile(location);
return new BamlAssembly(asm);
//return _domain.Load(System.IO.File.ReadAllBytes(location));
//return Assembly.LoadFrom(location);
}
public BamlAssembly[] GetReferencedAssemblies(BamlAssembly asm)
{
AssemblyName[] list = asm.Assembly.GetReferencedAssemblies();
return (from an in list
select this.LoadAssembly(an)).ToArray();
}
public AppDomain Domain
{
get { return _domain; }
}
#region ITypeResolver Members
public IType GetTypeByAssemblyQualifiedName(string name)
{
return new DotNetType(name);
}
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType)
{
if (name == null) throw new ArgumentNullException("name");
if (ownerType == null) throw new ArgumentNullException("ownerType");
if (targetType == null) throw new ArgumentNullException("targetType");
Type dOwnerType = ((DotNetType)ownerType).Type;
Type dTargetType = ((DotNetType)targetType).Type;
try
{
DependencyPropertyDescriptor propertyDescriptor = DependencyPropertyDescriptor.FromName(name, dOwnerType, dTargetType);
if (propertyDescriptor != null)
return new WpfDependencyPropertyDescriptor(propertyDescriptor);
return null;
}
catch (Exception)
{
return null;
}
}
#endregion
public override object InitializeLifetimeService()
{
return null;
}
}
public class AssemblyResolveEventArgs : MarshalByRefObject
{
private string _location;
private string _name;
private string _baseDir;
public AssemblyResolveEventArgs(string name, string baseDir)
{
_name = name;
_baseDir = baseDir;
}
public string Location
{
get { return _location; }
set { _location = value; }
}
public string Name
{
get { return _name; }
}
public string BaseDir
{
get { return _baseDir; }
}
}
}