[英]Can I get a list of assemblies that are not currently loaded
我想允許使用我的產品的開發人員能夠通過實現一個接口,然后將程序集放到執行文件夾中來擴展產品。 我應該如何找到這些類型,我是否必須通過文件夾中的每個DLL運行,還是可以避免使用原始應用程序中的那些DLL?
為什么不使用Microsoft解決方案 ?
據我了解,它可以完全解決您的需求
您可以將新程序集放在另一個文件夾中(例如,調用,插件或擴展名),然后在運行時實例化它們。 或者,維護產品程序集的列表並使用Path.GetFiles並刪除列表中顯示的所有程序集。
我將其用於用戶定義的工具。
private static void getImplementedTypes(Type baseType, Assembly assembly, IList<Type> list) {
Type[] types = assembly.GetExportedTypes();
foreach (Type t in types) {
if (baseType.IsInterface) {
Type[] interfaces = t.GetInterfaces();
foreach (Type i in interfaces) {
if (i == baseType) list.Add(t);
}
}
else {
if ((!list.Contains(t)) && (t.IsSubclassOf(baseType)) && (!t.IsAbtract)) {
list.Add(t);
}
}
}
return n;
}
在一個循環中,我遍歷工具目錄中Directory.GetFiles找到的所有DLL(或EXE):
Assembly assembly = Assembly.LoadFile("toolbox.dll");
List<Type> types = new List<Type>();
getImplementedTypes(typeof(ToolBase), assembly, types);
ToolBase theTool = Activator.CreateInstance(type, true) as ToolBase;
這適用於接口以及基類。
我不知道以另一種方式查找實現的類的方法。 這可能要花點時間。 因此,如果您知道要搜索的DLL,請僅遍歷它們。
最后,我選擇簡單地加載並搜索我在垃圾箱中找到的所有dll。 這是大多數代碼。 關鍵功能是“ IsAssignableToGenericType”功能,該功能可以找到我要查找的通用接口。
我相信這是提供大多數解決方案的鏈接, 通過反射實現接口
static AssemblyLocator()
{
AllDlls = GetAllDlls();
SubscribersInBin = GetSubscribersInBin();
}
public static IEnumerable<Type> TypesImplementingInterface(Assembly[] assemblies, Type desiredType)
{
return assemblies
.SelectMany(assembly => assembly.GetTypes())
.Where(type => IsAssignableToGenericType(type, desiredType));
}
public static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
if (givenType == null) throw new ArgumentNullException("givenType");
if (genericType == null) throw new ArgumentNullException("genericType");
var interfaceTypes = givenType.GetInterfaces();
foreach (var it in interfaceTypes)
{
if (it.IsGenericType)
{
if (it.GetGenericArguments()[0].Name.Equals(genericType.GetGenericArguments()[0].Name))
return true;
}
}
Type baseType = givenType.BaseType;
if (baseType == null) return false;
return (baseType.IsGenericType &&
baseType.GetGenericTypeDefinition() == genericType) ||
IsAssignableToGenericType(baseType, genericType);
}
private static ReadOnlyCollection<string> GetAllDlls()
{
string binFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
IList<string> dllFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList();
return new ReadOnlyCollection<string>(dllFiles);
}
private static ReadOnlyCollection<Type> GetSubscribersInBin()
{
IList<Assembly> assembliesFoundInBin = new List<Assembly>();
foreach (var item in AllDlls)
{
var assembly = System.Reflection.Assembly.LoadFrom(item);
assembliesFoundInBin.Add(assembly);
}
var typesInBin = TypesImplementingInterface(assembliesFoundInBin.ToArray(), typeof(ISubscriber<T>));
return new ReadOnlyCollection<Type>(typesInBin.ToList<Type>());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.