简体   繁体   English

包括类库中的服务引用

[英]Including a service reference from a class library

I have a C# class library and a startup project (a console app). 我有一个C#类库和一个启动项目(一个控制台应用程序)。 The class library includes a service reference to a web service. 类库包括对Web服务的服务引用。 When I try to run the project, I get an InvalidOperationException because the startup project isn't reading the class library's app.config, and it's ignoring the service reference. 当我尝试运行项目时,我得到一个InvalidOperationException,因为启动项目没有读取类库的app.config,而是忽略了服务引用。 To get it working, I'm forced to add the same service reference to the startup project. 为了使它工作,我被迫为启动项目添加相同的服务引用。 Is there any way I can avoid this? 有什么方法可以避免这种情况吗? Can I make the startup project recognize the class library's service reference and app.config without having to copy it to the startup project? 我是否可以使启动项目识别类库的服务引用和app.config而无需将其复制到启动项目?

I've tried adding a link to the app.config from the class library, but that doesn't work. 我已经尝试从类库中添加指向app.config的链接,但这不起作用。 The class library isn't very portable if it requires anyone who uses it to add that service reference to the startup project. 如果类库需要使用它来将该服务引用添加到启动项目中,则该类库不是非常便携。

Think about what you are trying to do - you have two assemblies that you are building: 想想你想要做什么 - 你有两个正在构建的程序集:

Library
ConsoleApp

Both of these assemblies have configuration files - I would imagine they look something like this: 这两个程序集都有配置文件 - 我想它们看起来像这样:

Library
    app.config
ConsoleApp
    ConsoleApp.exe.config

When you run ConsoleApp it has no way of reading from or knowing aboout app.config from your Library assembly. 当您运行ConsoleApp它无法从您的Library程序集中读取或了解aboout app.config The only configuration file that it knows or cares about is ConsoleApp.exe.config . 它知道或关心的唯一配置文件是ConsoleApp.exe.config Now it is possible to have configuration files reference each other but this is not the proper solution for what you are trying to do. 现在可以让配置文件相互引用,但这不是您正在尝试执行的操作的正确解决方案。

Since your Library assembly has no entry point, it will never be loaded into an AppDomain. 由于您的Library程序集没有入口点,因此永远不会将其加载到AppDomain中。 Since it will never be loaded into an AppDomain its application configuration file will never be used. 由于永远不会将其加载到AppDomain中,因此永远不会使用其应用程序配置文件。

What you ought to do is reference Library in ConsoleApp via a project reference. 你应该做的是通过项目参考引用ConsoleApp Library Then move all the relevant configuration data from app.config into ConsoleApp.exe.config as this is the configuration file that will be used by your application. 然后将所有相关配置数据从app.configConsoleApp.exe.config因为这是您的应用程序将使用的配置文件。

This will allow you to have to two things you need to invoke methods on your web service 这将允许您在Web服务上调用方法时需要两件事

  1. The code in Library that can send and receive SOAP messages. Library中可以发送和接收SOAP消息的代码。
  2. The configuration metadata that is required by Library to function. Library要运行所需的配置元数据。

An alternative to using a service reference in the class library and then copying the config would be to use build events that call svcutil.exe. 在类库中使用服务引用然后复制配置的替代方法是使用调用svcutil.exe的构建事件。 The thing I like about this is that you don't have to make "update service reference" when the service changes. 我喜欢的是,当服务发生变化时,您不必进行“更新服务引用”。 It will be updated automatically. 它会自动更新。

In the class library, use a build event that only generates the proxy code: 在类库中,使用仅生成代理代码的构建事件:

svcutil.exe net.tcp://localhost:3315/MyService/mex /noConfig

In the application, use a build event that generates the config. 在应用程序中,使用生成配置的构建事件。 You can use the /mergeConfig option to merge it into an existing app.config. 您可以使用/ mergeConfig选项将其合并到现有的app.config中。

svcutil.exe net.tcp://localhost:3315/MyService/mex 
            /config:App.config /mergeConfig

If you don't want to get a build error if the service is not running, put this in your project file and you will get a warning instead of an error: 如果您不希望在服务未运行时出现构建错误,请将其放在项目文件中,您将收到警告而不是错误:

<Target
    Name="PreBuildEvent"
    Condition="'$(PreBuildEvent)'!=''"
    DependsOnTargets="$(PreBuildEventDependsOn)">
  <Exec WorkingDirectory="$(OutDir)"
        Command="$(PreBuildEvent)"
        ContinueOnError="true" />
</Target>

You can copy the relevant portions of the app.config from the class library's configuration into the app.config for the console application. 您可以将app.config的相关部分从类库的配置复制到控制台应用程序的app.config中。

Alternatively, if you're really trying to make this truly portable, you'll need to think about another way of referencing the address for the specific service reference from within the class library. 或者,如果您真的想要使其真正可移植,那么您需要考虑从类库中引用特定服务引用的地址的另一种方法。

您只需将指向服务的配置密钥从类库配置文件复制到控制台应用程序的配置文件即可。

I'd think it more confusing if you had multiple configuration files running around. 如果你有多个配置文件在运行,我认为这更令人困惑。

If a library has configurable items, I would fully expect to have to put that configuration in my config file to properly consume the library. 如果一个库有可配置的项目,我完全希望必须将该配置放在我的配置文件中以正确使用该库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM