using System;
using System.Collections;
using System.Reflection;
using System.IO;
using RevolutionaryStuff.JBT;
namespace RevolutionaryStuff.P2P.Basics
{
///
/// If an assembly has this attribute, it contains plug-ins
///
[AttributeUsage(AttributeTargets.Assembly)]
public class PlugInsAvailableAttribute : Attribute
{
///
/// Does the given assembly contain any plugins?
///
/// The assembly in question
/// True if it contains plugins
public static bool HasPlugins(Assembly a)
{
if (null==a) throw new ArgumentNullException("a");
return a.IsDefined(typeof(PlugInsAvailableAttribute), true);
}
}
///
/// If a class has this attribute, it is a plug in for the GFS
///
[AttributeUsage(AttributeTargets.Class)]
public class PlugInAttribute : Attribute
{
///
/// Gets the set of plugins contained in the given assembly
///
/// The assembly in question
/// A dictionary. The key is the Type, The value is the PlugInAttribute
public static IDictionary GetPlugInAttributesByType(Assembly a)
{
if (null==a) throw new ArgumentNullException("a");
IDictionary plugInAttributeByType = new System.Collections.Specialized.ListDictionary();
foreach (Type t in a.GetExportedTypes())
{
object[] attrs = t.GetCustomAttributes(typeof(PlugInAttribute), true);
if (attrs.Length!=1) continue;
plugInAttributeByType[t] = attrs[0];
}
return plugInAttributeByType;
}
///
/// Gets the set of plugins contained in the specified assemblies
///
/// List of loaded assemblies to test
/// List of assembly names that may contain a plug-in but are not already loaded
/// Whether to test this unloaded set of plugins in a separate AppDomain or not
/// A dictionary. The key is the Type, The value is the PlugInAttribute
public static IDictionary GetPlugInAttributesByType(Assembly[] assemblies, string[] dllNames, bool testDllsInSeparateAppDomain)
{
IDictionary setOfTestedAssemblyFullNames = System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable();
IDictionary dAll = new System.Collections.Specialized.ListDictionary();
IList assembliesWithPlugIns = new ArrayList();
if (assemblies!=null)
{
foreach (Assembly a in assemblies)
{
setOfTestedAssemblyFullNames[a.FullName] = true;
try
{
setOfTestedAssemblyFullNames[a.Location] = true;
}
catch (NotSupportedException){}
if (!PlugInsAvailableAttribute.HasPlugins(a)) continue;
assembliesWithPlugIns.Add(a);
}
}
if (dllNames!=null&&dllNames.Length>0)
{
AppDomain appDomain = testDllsInSeparateAppDomain ? AppDomain.CreateDomain("PlugIn Tester Domain", null) : AppDomain.CurrentDomain;
try
{
foreach (string fn in dllNames)
{
if (!File.Exists(fn)) continue;
if (setOfTestedAssemblyFullNames.Contains(fn)) continue;
Assembly a = null;
try
{
AssemblyName an = AssemblyName.GetAssemblyName(fn);
string assemblyName = an.FullName;
if (setOfTestedAssemblyFullNames.Contains(assemblyName)) continue;
setOfTestedAssemblyFullNames[assemblyName] = true;
a = appDomain.Load(assemblyName);
if (!PlugInsAvailableAttribute.HasPlugins(a)) continue;
if (testDllsInSeparateAppDomain)
{
a = AppDomain.CurrentDomain.Load(assemblyName);
}
assembliesWithPlugIns.Add(a);
}
catch (Exception ex)
{
Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManager.Publish(ex);
}
}
}
finally
{
if (testDllsInSeparateAppDomain)
{
AppDomain.Unload(appDomain);
}
}
}
//Get the dictionary
foreach (Assembly a in assembliesWithPlugIns)
{
foreach (DictionaryEntry de in GetPlugInAttributesByType(a))
{
dAll[de.Key] = de.Value;
}
}
return dAll;
}
public int Order;
#region Constructors
public PlugInAttribute() : this(0)
{}
public PlugInAttribute(int order)
{
this.Order = order;
}
#endregion
}
}
|