簡體   English   中英

我可以獲取當前未加載的程序集的列表嗎

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM