库需要引用System.Windows.Forms

时间:2014-12-31 18:05:28

标签: c# .net reference .net-assembly

我无法找到有关此主题的信息,可能是因为我不确定如何说出问题。希望这里的智慧可以帮助或至少提供建议。这种情况可能只是让我保持心理,但它让我烦恼,所以我想我会就如何绕过它寻求帮助。

我有一个C#库,里面装有其他程序集中使用的实用程序类。我的所有扩展都驻留在这个库中,它非常方便。我需要使用这些类的任何其他库或可执行文件必须自然地引用该库。

但我在其中的扩展之一是在Control类上有一个扩展,以较少复杂的方式处理跨线程控制更新。因此,实用程序库必须引用System.Windows.Forms。

问题是任何引用实用程序库的库或可执行文件现在都必须具有对System.Windows.Forms的引用,否则我会得到缺少引用的构建错误。虽然这不是什么大不了的事情,但是如果程序集与控件或表单无关,那么只需要引用System.Windows.Forms就好了,因为实用程序库特别是因为大多数实际上并没有使用我写的InvokeAsRequired()扩展名。

我考虑过将InvokeAsRequired()扩展移动到它自己的库中,这会消除Sys​​tem.Windows.forms问题,因为只有需要使用InvokeAsRequired()扩展的程序集才会有对SWF的引用....但后来我有一个只有一件事的图书馆可能会让我更加困扰。

除了分离'违规'方法并创建一个几乎空的库之外,还有办法解决这个问题吗?也许是编译设置还是什么?

  • 应该注意的是,'违规方法'实际上是在具有UI的多个项目中使用的。我做的很多UI更新是由于事件进入并尝试从另一个线程更新Windows窗体控件导致各种UI线程问题。因此,在需要时处理Invoke的方法。 (虽然我个人认为整个InvokeRequired模式应该包含在控件本身中,而不是首先在外部进行线程对齐)。

3 个答案:

答案 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