反射:“;无法加载文件或程序集“”;双重依赖反转

本文关键字:程序集 依赖 文件 加载 反射 | 更新日期: 2024-10-20 11:16:00

你好吗??

我希望你们中的一个能帮助我!!

这些是正在发挥作用的包及其关系(我正在使用C#):

Web---->ILogic
          ^
          |
        Logic------>Ilog
                      ^
                      |
                     Log

假设在每个项目中都有一个同名的类。Logic类实现ILogic接口,Log类实现ILog接口。

所以这些将是类:

public class Web{
    internal static readonly ILogic = InitializeLogic();
    private static ILogic InitializeLogic(){
        string path = ConfigurationManager.AppSettings["LogicAssemblyPath"];
        string className = ConfigurationManager.AppSettings["LogicClass"];
        Assembly assembly = Assembly.LoadFile(path);
        Type type = assembly.GetType(className);
        return (ILogic)Activator.CreateInstance(type, null);
    }
}
public class Logic{
    internal static readonly ILog = InitializeLog();
    private static ILogic InitializeLogic(){
            string path = ConfigurationManager.AppSettings["LogAssemblyPath"];
            string className = ConfigurationManager.AppSettings["LogClass"];
            Assembly assembly = Assembly.LoadFile(path);
            Type type = assembly.GetType(className);
            return (ILog)Activator.CreateInstance(type, null);
    }
}

所以,当我打电话给时

Web.Method();

它使用反射实例化Logic类,同时再次使用反射实例化Log类。

这引发了下一个异常:

系统。IO.FileNotFoundException:无法加载文件或程序集"ILog,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"或其依赖项之一。系统找不到指定的文件。

这可以通过在Web中向ILogic或ILog添加引用来解决(如果我添加其中一个引用it WORKS,那么appsetting中的路径或类似的东西就没有问题),但很明显,我需要一个不需要添加任何引用的解决方案。

如有任何帮助/见解,我们将不胜感激!!

谢谢!

反射:“;无法加载文件或程序集“”;双重依赖反转

所以,我设法解决了它。

正如bdn02所说,ILog程序集没有加载。我试着手动将它加载到Appdomain中,但奇怪的是,它找了两次程序集:

-第一次以全名"ILog,Version=1.0.0.0等"进行搜索

-第二次仅按包名"ILog"进行搜索

显然,它没有第二次找到它,它抛出了异常。

我使用bdn02建议的AssemblyResolve事件找到了一个解决方法:

AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
private static Assembly AssemblyResolve(object sender, ResolveEventArgs args){
        if (!args.Name.Contains("ILog"))
            return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name);
        else
        {
            var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName.Contains(args.Name));
            if (assembly == null)
            {
                string rutaAssemblyILog = ConfigurationManager.AppSettings["AssemblyILog"];
                Assembly.LoadFile(rutaAssemblyILog);
            }
        }
        return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName.Contains(args.Name));
}

第一个if用于确保事件是由于ILog程序集而发生的。有了这个,它运行得很好。

谢谢你的帮助!