/// <summary> /// Scan the folder and instance all classes that dlls contain within them /// </summary> /// <param name="TargetFolder">Load in this folder for shared libraries / dlls</param> /// <param name="SharedLibraryContains">any potential plugin to load must have this in the dll name</param> /// <param name="ClassNameContains">only instance classes with this string somewhere in the same</param> public void ScanFolder(string TargetFolder, PluginFilterCheck CheckMe, string SharedLibraryContains, TargetClassLoadName CheckClassInfo, string ClassNameContains) { var Targets = GetValidExternTargets(TargetFolder, CheckMe, SharedLibraryContains); if (Targets.Count > 0) { if (CheckClassInfo == null) { foreach (string TargetSharedLib in Targets) { LoadedFileHandliers.AddRange(LoadAllPlugins(ClassNameContains, TargetSharedLib)); } } else { foreach (string TargetShareLib in Targets) { LoadedFileHandliers.AddRange(LoadAllPlugins(CheckClassInfo, TargetShareLib)); } } } }
public List <T> LoadAllPlugins(TargetClassLoadName ClassNameFilter, string DllLocation) { string SubName = "Container for plugins contained in " + Path.GetFileNameWithoutExtension(DllLocation); T first = (LoadPlugin(ClassNameFilter, string.Empty, null, null, DllLocation, SubName, 1, out List <T> NoJunk)); NoJunk.Add(first); return(NoJunk); }
/// <summary> /// the generic load routine for the system. The exported routines lead here /// </summary> /// <param name="TargetFormatClassCheck">specific null to skip this check. Called to see if the exported type is a match <seealso cref="TargetClassLoadName"/></param> /// <param name="TargetFormatClassString">if TargetFormatClassCheck is null checked class names are compaired against it</param> /// <param name="VerifyCallback">prevent unwanted assemblys from being used. <seealso cref="AssemblyCheck"/></param> /// <param name="VerifyAssemblyString">if Verifycallback is null, this is case sensisite compared with the FullName of the loaded assembly. No match means no go</param> /// <param name="DllLocation">load the dll from here</param> /// <param name="SubDomain">name of AppDomain created from the parent subdomain</param> /// <param name="MaxOverflow">load nore than MaxOverflow if > 0. Set negative to disable cap</param> /// <param name="Overflow">on exit contained additional loaded and instanced types</param> /// <returns></returns> private T LoadPlugin(TargetClassLoadName TargetFormatClassCheck, string TargetFormatClassString, AssemblyCheck VerifyCallback, string VerifyAssemblyString, string DllLocation, string SubDomain, int MaxOverflow, out List <T> Overflow) { T Iterate = null; T ret = null; Overflow = null; if (MaxOverflow < 0) { Overflow = new List <T>(); } /* * redundant but get point accross * if (MaxOverflow == 0) * { * Overflow = null; * }*/ if (MaxOverflow >= 1) { Overflow = new List <T>(MaxOverflow); } Tool_DuplicateDomain(FormatContainer, SubDomain, out AppDomain Probe); AssemblyResolver_DynamicClassLoader tiny = new AssemblyResolver_DynamicClassLoader(); Probe.AssemblyResolve += new ResolveEventHandler(tiny.Probe_AssemblyResolve); Assembly Dll = Probe.Load(DllLocation); if (VerifyCallback != null) { if (VerifyCallback(Dll) == false) { throw new InvalidOperationException("Dll: " + Path.GetFileName(DllLocation) + " did not pass VerifyCheck"); } } else { if (VerifyAssemblyString != null) { if (Dll.FullName.Contains(VerifyAssemblyString) == false) { throw new InvalidOperationException("Dll: " + Path.GetFileName(DllLocation) + " did not pass VerifyCheck"); } } } foreach (Type DllType in Dll.GetExportedTypes()) { /* * FUTURE ME: PAST ME WAS SLEEPY. * This code is indended to check 3 scenerios for a match * * #1 * TargetFormatClassCheck delegate is not null and returns true on call * * #2 * TargetFormatClassCheck delegate is null, and the string is contained within the type's fullname if not zero * * #3 * both TargetClassCheck delegate is null and the string is null (this matches any) * * * Reason at the time is to consalodate the instance creation code on match * YOUR THANK ME LATER FOR THIS COMMENT, * PAST ME * * Follow Up: Catch Generic Routines and things man or the .net runtime was not ment to instance in a Try Catch block */ /*if (((TargetFormatClassCheck != null) && * (TargetFormatClassCheck(DllType.FullName, DllType.GetTypeInfo()) == true)) || || ((TargetFormatClassString != null)) && ((TargetFormatClassString != null) && (DllType.FullName.Contains(TargetFormatClassString) == true)) || ||(TargetFormatClassString == null) && (TargetFormatClassCheck == null)) */ if (TargetFormatClassCheck != null) { if (TargetFormatClassCheck(DllType.FullName, DllType.GetTypeInfo()) == false) { continue; } } if (TargetFormatClassString != null) { if (DllType.FullName.Contains(TargetFormatClassString) == false) { continue; } } { // it's a match Iterate = new T(); { Iterate.Domain = Probe; Iterate.Handler = Activator.CreateInstance(DllType); Iterate.HandlerType = DllType; Iterate.LoadedAssembly = Dll; }; if (ret == null) { ret = Iterate; if (MaxOverflow == 0) { break; } else { if (MaxOverflow > 0) { MaxOverflow--; } } } else { Overflow.Add(Iterate); MaxOverflow--; } } } if (ret == null) { // no matches AppDomain.Unload(Probe); Overflow.Clear(); Overflow = null; } return(ret); }
/// <summary> /// Load an instanced class that the callback routine approves /// </summary> /// <param name="CheckName">delege to examine with. </param> /// <param name="DllLocation">assembly or dll to load from</param> /// <returns></returns> public T LoadPlugin(TargetClassLoadName CheckName, string DllLocation) { string SubName = "Container for " + CheckName + " plugin"; return(LoadPlugin(CheckName, null, null, null, DllLocation, SubName, 0, out List <T> _)); }