我无法找到有关此主题的信息,可能是因为我不确定如何说出问题。希望这里的智慧可以帮助或至少提供建议。这种情况可能只是让我保持心理,但它让我烦恼,所以我想我会就如何绕过它寻求帮助。
我有一个C#库,里面装有其他程序集中使用的实用程序类。我的所有扩展都驻留在这个库中,它非常方便。我需要使用这些类的任何其他库或可执行文件必须自然地引用该库。
但我在其中的扩展之一是在Control类上有一个扩展,以较少复杂的方式处理跨线程控制更新。因此,实用程序库必须引用System.Windows.Forms。
问题是任何引用实用程序库的库或可执行文件现在都必须具有对System.Windows.Forms的引用,否则我会得到缺少引用的构建错误。虽然这不是什么大不了的事情,但是如果程序集与控件或表单无关,那么只需要引用System.Windows.Forms就好了,因为实用程序库特别是因为大多数实际上并没有使用我写的InvokeAsRequired()扩展名。
我考虑过将InvokeAsRequired()扩展移动到它自己的库中,这会消除System.Windows.forms问题,因为只有需要使用InvokeAsRequired()扩展的程序集才会有对SWF的引用....但后来我有一个只有一件事的图书馆可能会让我更加困扰。
除了分离'违规'方法并创建一个几乎空的库之外,还有办法解决这个问题吗?也许是编译设置还是什么?
答案 0 :(得分:2)
如果它只是一个功能,那么将其作为源代码文件打包到NuGet包中,然后将NuGet包添加到您的项目中。然后,此代码可以轻松部署到新项目(以及可轻松更新),但您不需要创建单独的程序集。只需将其编译到您的应用程序中即可。
然后,您可以将NuGet包存储在本地NuGet存储库中,或者获取myget帐户,甚至只将其存储在网络上的某个位置。最坏的情况是,您可以将其检入您的版本控制中,但我只需检查"项目"您从中构建nuget包,因此您可以根据需要重建包。
谁知道,在某些时候,您可能会添加更多需要Windows窗体的实用程序功能,此时您可以证明单独的程序集是合理的。
答案 1 :(得分:0)
这很简单:你有来移除违规代码。现在它可能有点担心,但最后它可能是你现在做的爆炸而不是你被迫的那一刻。
即使它只是一种方法(现在),只需将方法移动到另一个程序集中即可。我没有说一个新的,它可以在使用它的程序集中,如果只有一个,或者所有其他需要那个时刻的东西都来自它。
答案 2 :(得分:0)
当涉及到System.Windows.Forms
命名空间中声明的类型时,您可以通过从early-binding pattern to the late-binding pattern切换实用程序库代码来解决您的问题。
本文将简要介绍如何执行此操作:Stack Overflow: C#.NET - Type.GetType(“System.Windows.Forms.Form”) returns null
此代码段显示了Mono Project(开源ECMA CLI,C#和.NET实现)中的monoresgen
工具如何解决System.Windows.Forms
依赖性问题。
public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089";
// ...
static Assembly swf;
static Type resxr;
static Type resxw;
/*
* We load the ResX format stuff on demand, since the classes are in
* System.Windows.Forms (!!!) and we can't depend on that assembly in mono, yet.
*/
static void LoadResX () {
if (swf != null)
return;
try {
swf = Assembly.Load(Consts.AssemblySystem_Windows_Forms);
resxr = swf.GetType("System.Resources.ResXResourceReader");
resxw = swf.GetType("System.Resources.ResXResourceWriter");
} catch (Exception e) {
throw new Exception ("Cannot load support for ResX format: " + e.Message);
}
}
// ...
static IResourceReader GetReader (Stream stream, string name, bool useSourcePath) {
string format = Path.GetExtension (name);
switch (format.ToLower (System.Globalization.CultureInfo.InvariantCulture)) {
// ...
case ".resx":
LoadResX ();
IResourceReader reader = (IResourceReader) Activator.CreateInstance (
resxr, new object[] {stream});
if (useSourcePath) { // only possible on 2.0 profile, or higher
PropertyInfo p = reader.GetType ().GetProperty ("BasePath",
BindingFlags.Public | BindingFlags.Instance);
if (p != null && p.CanWrite) {
p.SetValue (reader, Path.GetDirectoryName (name), null);
}
}
return reader;
// ...
}
}
摘录源:https://github.com/mono/mono/blob/mono-3.10.0/mcs/tools/resgen/monoresgen.cs#L30