Class 库在使用时丢失引用 (dll)
Class library loses references (dlls) when being used
对不起标题。我不知道如何简短地描述这个问题。
我的问题是我有一个 class-library
,它有 references to other (third party) DLLs
。
我需要在另一个项目中使用这个 class-library,所以我显然将我的 class-library 的 .dll 添加到我的 main-project.
当我启动我的 main-project 时,总是出现一个错误,提示无法找到我的 class-library 中的引用 (dll)。
如果我在 visual studio 中将整个 class-library 作为一个项目添加到我的项目图中,然后引用整个项目,则不会发生此错误。
我真的不想将整个 class-library 作为一个项目添加到我制作的每个 "host" 项目中。
有没有人知道为什么在添加 class-library 的 .dll 时会出现此错误,但在添加 class-library 的整个项目作为参考时不会出现此错误?
即使我不添加整个 library-project 作为参考,也必须有一个解决方案才能使它正常工作。否则制作一个 class 库没有任何意义,对吧?
顺便说一下:我的 class-library 包含 third-party dll 并且 third-party dll 的本地副本 属性 是设置为真。
提前致谢!
编辑:
我的目标是真正使 class-library 可移植,即使它包含 third-party 库。我只想将 .dll 提供给另一台电脑并使用它而无需每次都添加整个 class-library 项目。
错误是因为你没有在第二个项目上复制 dll,你添加了对你的 dll 的引用所以它被复制了,但不是你的 dll 引用的 dll,所以缺少库。
或者您使用 dll 重新分发依赖项,或者您可以将 dll 作为资源嵌入到您的 dll 中,然后拦截程序集加载并通过资源提供它:http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
编辑:为了在 dll 中执行此操作,您需要使用静态 class 并在使用任何依赖于其他库的 classes 之前调用静态初始化程序。
这是一个示例设置:
-一个名为 LibraryB 的库,它提供了一个简单的 class,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryB
{
public class ReferencedClass
{
public int GetIt()
{
return 5;
}
}
}
-一个名为 LibraryA 的库,它引用 LibraryB 并提供两个 classes,初始值设定项和实际 class:
初始化程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace LibraryA
{
public static class Initializer
{
public static void Init()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
if (!args.Name.StartsWith("LibraryB"))
return null;
return Assembly.Load(LibraryA.Properties.Resources.LibraryB);
};
}
}
}
Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryA
{
public class RealClass
{
public int DoIt()
{
LibraryB.ReferencedClass cl = new LibraryB.ReferencedClass();
return cl.GetIt();
}
}
}
LibraryA 还嵌入了 LibraryB.dll 已编译的库作为资源。
-名为 Test 的项目仅引用 LibraryA:
using LibraryA;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Initializer.Init();
RealClass c = new RealClass();
Console.WriteLine("From LibraryA: " + c.DoIt());
Console.ReadKey();
}
}
}
如果你设置正确并执行它,它就会工作,请记住,如果你正在通过 visual studio,vs 将复制 dll,以便在编译所有复制 exe 后进行真正的测试和 LibraryA 并执行,它将在没有 LibraryB 的情况下工作,并且 LibraryB 正在从 LibraryA 使用。
对不起标题。我不知道如何简短地描述这个问题。
我的问题是我有一个 class-library
,它有 references to other (third party) DLLs
。
我需要在另一个项目中使用这个 class-library,所以我显然将我的 class-library 的 .dll 添加到我的 main-project.
当我启动我的 main-project 时,总是出现一个错误,提示无法找到我的 class-library 中的引用 (dll)。
如果我在 visual studio 中将整个 class-library 作为一个项目添加到我的项目图中,然后引用整个项目,则不会发生此错误。
我真的不想将整个 class-library 作为一个项目添加到我制作的每个 "host" 项目中。
有没有人知道为什么在添加 class-library 的 .dll 时会出现此错误,但在添加 class-library 的整个项目作为参考时不会出现此错误?
即使我不添加整个 library-project 作为参考,也必须有一个解决方案才能使它正常工作。否则制作一个 class 库没有任何意义,对吧?
顺便说一下:我的 class-library 包含 third-party dll 并且 third-party dll 的本地副本 属性 是设置为真。
提前致谢!
编辑: 我的目标是真正使 class-library 可移植,即使它包含 third-party 库。我只想将 .dll 提供给另一台电脑并使用它而无需每次都添加整个 class-library 项目。
错误是因为你没有在第二个项目上复制 dll,你添加了对你的 dll 的引用所以它被复制了,但不是你的 dll 引用的 dll,所以缺少库。
或者您使用 dll 重新分发依赖项,或者您可以将 dll 作为资源嵌入到您的 dll 中,然后拦截程序集加载并通过资源提供它:http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
编辑:为了在 dll 中执行此操作,您需要使用静态 class 并在使用任何依赖于其他库的 classes 之前调用静态初始化程序。
这是一个示例设置:
-一个名为 LibraryB 的库,它提供了一个简单的 class,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryB
{
public class ReferencedClass
{
public int GetIt()
{
return 5;
}
}
}
-一个名为 LibraryA 的库,它引用 LibraryB 并提供两个 classes,初始值设定项和实际 class:
初始化程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace LibraryA
{
public static class Initializer
{
public static void Init()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
if (!args.Name.StartsWith("LibraryB"))
return null;
return Assembly.Load(LibraryA.Properties.Resources.LibraryB);
};
}
}
}
Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryA
{
public class RealClass
{
public int DoIt()
{
LibraryB.ReferencedClass cl = new LibraryB.ReferencedClass();
return cl.GetIt();
}
}
}
LibraryA 还嵌入了 LibraryB.dll 已编译的库作为资源。
-名为 Test 的项目仅引用 LibraryA:
using LibraryA;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Initializer.Init();
RealClass c = new RealClass();
Console.WriteLine("From LibraryA: " + c.DoIt());
Console.ReadKey();
}
}
}
如果你设置正确并执行它,它就会工作,请记住,如果你正在通过 visual studio,vs 将复制 dll,以便在编译所有复制 exe 后进行真正的测试和 LibraryA 并执行,它将在没有 LibraryB 的情况下工作,并且 LibraryB 正在从 LibraryA 使用。