包括来自类库的服务引用
Posted
技术标签:
【中文标题】包括来自类库的服务引用【英文标题】:Including a service reference from a class library 【发布时间】:2010-10-06 11:38:33 【问题描述】:我有一个 C# 类库和一个启动项目(一个控制台应用程序)。类库包括对 Web 服务的服务引用。当我尝试运行该项目时,我得到一个 InvalidOperationException,因为启动项目没有读取类库的 app.config,并且它忽略了服务引用。为了让它工作,我不得不向启动项目添加相同的服务引用。有什么办法可以避免这种情况吗?是否可以让启动项目识别类库的服务引用和app.config,而不必将其复制到启动项目中?
我尝试从类库中添加指向 app.config 的链接,但这不起作用。如果类库需要使用它的任何人将服务引用添加到启动项目中,那么类库的可移植性就不是很好。
【问题讨论】:
+1:嘿 Zarjay,我也想问同样的问题。虽然我同意 Andrew Hare 的观点,并且理解为什么这是不可能的,但我也同意该解决方案并没有真正使库非常便携。我想知道,可以以编程方式应用配置设置吗? 我不确定,但我对此表示怀疑。不过,很棒的想法。我知道可以写入配置文件,但我敢打赌,当您的代码能够写入时,添加服务引用可能为时已晚。 【参考方案1】:在类库中使用服务引用然后复制配置的替代方法是使用调用 svcutil.exe 的构建事件。我喜欢这一点的是,当服务更改时,您不必进行“更新服务参考”。它将自动更新。
在类库中,使用只生成代理代码的构建事件:
svcutil.exe net.tcp://localhost:3315/MyService/mex /noConfig
在应用程序中,使用生成配置的构建事件。您可以使用 /mergeConfig 选项将其合并到现有的 app.config 中。
svcutil.exe net.tcp://localhost:3315/MyService/mex
/config:App.config /mergeConfig
如果您不想在服务未运行时出现构建错误,请将其放入您的项目文件中,您将收到警告而不是错误:
<Target
Name="PreBuildEvent"
Condition="'$(PreBuildEvent)'!=''"
DependsOnTargets="$(PreBuildEventDependsOn)">
<Exec WorkingDirectory="$(OutDir)"
Command="$(PreBuildEvent)"
ContinueOnError="true" />
</Target>
【讨论】:
【参考方案2】:想想你想要做什么 - 你有两个正在构建的程序集:
Library
ConsoleApp
这两个程序集都有配置文件 - 我想它们看起来像这样:
Library
app.config
ConsoleApp
ConsoleApp.exe.config
当您运行ConsoleApp
时,它无法从您的Library
程序集中读取或了解app.config
。它唯一知道或关心的配置文件是ConsoleApp.exe.config
。现在可以让配置文件相互引用,但这不是您尝试做的正确解决方案。
由于您的Library
程序集没有入口点,它永远不会被加载到 AppDomain 中。因为它永远不会被加载到 AppDomain 中,所以它的应用程序配置文件永远不会被使用。
您应该做的是通过项目引用在ConsoleApp
中引用Library
。然后将所有相关配置数据从app.config
移动到ConsoleApp.exe.config
,因为这是您的应用程序将使用的配置文件。
这将允许您在 Web 服务上调用方法所需的两件事
Library
中可以发送和接收 SOAP 消息的代码。
Library
运行所需的配置元数据。
【讨论】:
感谢您的解释;现在有道理了,为什么它不起作用。我还是 .NET 的新手,虽然我更喜欢类库是一个独立的模块,其内部实现与使用它的代码无关,但我现在明白为什么它在这种情况下不起作用了。跨度> 值得一提的是,配置数据不是内部实现——它是应该由库用户(您的控制台应用程序)提供的库配置数据。我的一般做法是在需要配置文件时将 app.config 中的示例配置文本与库项目一起提供,然后假设库的用户将该配置数据复制到他们自己的配置文件中,并将更改为合适的。如果不需要配置文件,这些选项将成为库上的编程配置旋钮。 格雷格,我不同意。库配置数据相当于开发人员知道的 Web 服务 URL,而不是用户。用户不必关心那个 URL 是什么;它是库的内部实现,作为接口(库)的用户,我不应该关心实现的细节(它正在使用的 Web 服务)。感谢上帝,我可以使用 Google 的 Java 客户端库,而无需关心它使用什么 URL 来执行其功能。不幸的是,如果有 .NET 版本,我将不得不关心。在我看来,没有这个选项是 .NET 的一大缺陷。 出色的解释帮助我解决了这个烦人的问题 - 谢谢【参考方案3】:您可以将 app.config 的相关部分从类库的配置复制到控制台应用程序的 app.config 中。
或者,如果您真的想使其真正可移植,则需要考虑另一种方法来从类库中引用特定服务引用的地址。
【讨论】:
我尝试过复制 app.config,但除非我也添加服务引用,否则控制台应用程序将无法运行。可移植性确实不是优先事项。我只是觉得在项目中多余地包含一些东西很烦人。类库应该是自包含的。 作为 WCF 客户端的类库故意不是自包含的。它们通常不用于重新分配。它们应该可以在客户端进行配置,这就是为什么 app.config 对这些来说是典型的。您始终可以对值进行硬编码,但那是......好吧......硬编码。 :)【参考方案4】:如果您有多个配置文件在运行,我会认为这会更令人困惑。
如果库具有可配置项,我完全希望必须将该配置放入我的配置文件中才能正确使用该库。
【讨论】:
【参考方案5】:您只需将指向服务的配置键从您的类库配置文件复制到控制台应用程序的配置文件。
【讨论】:
我的 app.config 没有配置键。如何指定一个? 引用 Web 服务时,您可以选择使用静态或动态引用,请参阅属性。选择 dynamic 会使 IDE 在您的 Web 服务代理类中生成代码,以从配置文件中读取 url。将库配置中生成的值复制到控制台应用程序的配置中。以上是关于包括来自类库的服务引用的主要内容,如果未能解决你的问题,请参考以下文章
无法在引用类库的 azure 函数中加载文件或程序集“System.Data.Entity 4.0.0.0”
Visual Studio/MSBuild 将引用的类库的 app.config 作为 *.dll.config 复制到当前项目的 bin 文件夹