【问题标题】:Azure Worker Role Config File TransformationsAzure 辅助角色配置文件转换
【发布时间】:2012-11-29 11:12:19
【问题描述】:

我已经设置了一个新的工作角色,并通过 SlowCheetah 为其设置了几个新的配置转换。当我使用选择的新配置之一构建项目时,我确实看到在 \bin 文件夹下创建了 configs 文件夹,正如您所期望的那样(例如 \bin\Production)。

当我使用其中一个新配置打包云服务以进行部署时,我的 Web 项目的配置得到了适当的转换,但我的工作角色(只是一个库)没有,即使我在 \bin 文件夹下看到了更新\bin\生产。

Azure 打包工​​具似乎忽略了工作角色库的配置集。如何让它从适当的配置中选择配置文件?

【问题讨论】:

  • cspack(azure 打包工​​具)不依赖于应用程序配置(app.config),而是使用服务定义,如msdn.microsoft.com/en-us/library/gg432988.aspx 所述。如果您可以提供有关您希望在构建配置中包含哪些应用程序配置设置以及如何定义它们的更多信息,我可以提供帮助。还有你如何构建你的包、命令行或 VS UI。
  • 通过 VS UI。我正在尝试将应用程序移植到 Azure,并且不想重新编写大部分应用程序以忽略 app.config。我通常通过配置转换进行转换的 system.net.mail 配置之类的东西。
  • 我过去使用过SlowCheetah,发现它只适用于安装了它的开发者——它不适用于没有安装它的开发者。换句话说,它对您的 .csproj 所做的更改不足以使其对其他人“正常工作” - 需要额外的东西。不过,我不知道那个附加的东西是什么。 :-(
  • 现在这一切都无关紧要了。 SlowCheetah 现在支持 Azure Worker Role 配置转换。万岁!
  • @JamesAlexander SlowCheetah 在创建包为天蓝色时不会转换 app.Production.config。你是怎么做到的?

标签: azure app-config azure-worker-roles


【解决方案1】:

有一个技巧。也许有人会派上用场。 Azure 辅助角色生成器包括标记为“复制”的文件。但是 app.config 将在 WorkerRole1.dll.config (或其他一些)中进行转换,这在设计时不存在。作弊VS:

卸载角色项目.csproj。

在项目中找到包含文件的 ItemGroup 部分。我有接下来的几个:

<None Include="app.config">
  <SubType>Designer</SubType>
</None>
<None Include="app.Debug.config">
  <DependentUpon>app.config</DependentUpon>
</None>
<None Include="app.Release.config">
  <DependentUpon>app.config</DependentUpon>
  <SubType>Designer</SubType>
</None>

然后设置之前或之后:

<Content Include="bin\$(Configuration)\WorkerRole1.dll.config">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  <Link>WorkerRole1.dll.config</Link>
</Content>

这个技巧告诉构建器“WorkerRole1.dll.config”作为一个链接存在,这个将在构建(和转换)后获得并包含在 WorkerRole 包中。

【讨论】:

  • 轻微修复以解决重建问题(当 bin 被清除时)。生成器尝试复制不存在的文件并且重建失败。要解决此问题,请使用 Content\Copy Always 参数在项目根目录中插入名称为 WorkerRole1.dll.config 的虚拟文件。 Builder会先复制dummy,然后复制成功。 Azure 角色部署程序读取此文件的属性“内容”并复制新的转换文件。这无需任何额外的复制就可以工作,并且更清晰。
【解决方案2】:

我觉得@Frans 的答案太复杂了,下面是我在internet 中找到的代码。鉴于您已经设置好 app.config 转换并开始工作,请在文本编辑器中打开您的云项目 (.ccproj),找到以下行:

<Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" />

并在其后插入以下内容:

  <!-- Get worker role transform start -->
  <Target Name="CopyWorkerRoleConfigurations" AfterTargets="CopyWorkerRoleFiles">
    <Copy SourceFiles="$(WorkerTargetDir)\YOUR-PROJECT-NAME.dll.config" DestinationFolder="$(IntermediateOutputPath)YOUR-PROJECT-NAME" OverwriteReadOnlyFiles="true" />
  </Target>
  <!-- Get worker role transform end -->

并将 YOUR-PROJECT-NAME 替换为您的工作项目名称。

更新

我实际上找到了一种更好的方法(MSBuild 4+):如果您在 Azure 项目中拥有超过 1 个具有 app.config 转换的辅助角色,则上述脚本将不起作用。这是更通用的方法:

  <Target Name="CopyWorkerRoleConfigurations" AfterTargets="CopyWorkerRoleFiles">
    <PropertyGroup>
         <RootFolder>$([System.IO.Path]::GetDirectoryName($(MSBuildProjectDirectory)))</RootFolder>
    </PropertyGroup>

    <Copy SourceFiles="$(RootFolder)\%(ProjectName)\bin\$(Configuration)\%(EntryPoint).config" DestinationFolder="%(WorkerRoleReferences.OutputDir)" OverwriteReadOnlyFiles="true" />
  </Target>  

【讨论】:

  • 如果您将模板设置为 OutputLocation = SingleFolder,我发现我需要稍微调整一下以使其使用 TFS 构建服务工作。我将 SourceFiles 更改为
【解决方案3】:

是的,你可以做到这一点 - 一旦你知道如何做到这一点,它甚至非常容易。
App.config 不是设计转换的,但幸运的是,Azure 团队使构建/部署过程非常适合这些场景。您需要做的事情是相当有据可查的,尽管是以一种非常迂回的方式,并且大多数文章都假设您已经熟悉 MSBuild 脚本等。

您将在下面找到您需要在项目中添加的行,这些行将使这个 Just Work。这应该不会超过五分钟。请注意,这不是 hack - 整个 Azure 部署过程旨在支持这种事情。

如果你想了解更多,底部有一些相关文章的链接。

一些概念点

  1. 在 Azure 中实现这种事情的推荐方法是不使用 Web.config 和 App.config,而是使用 CloudConfigurationManager 并使用角色设置。然而,有时这并不是正确的答案,通常是因为需要 *.config 设置(smtp、wcf、elmah 等)的内置或第 3 方组件。
  2. Web Config 转换仅用于转换 web.config。这意味着 app.config 没有被设计转换。
  3. Web Config 转换设计为仅在发布时启动,因此当您在本地运行时,即使在 Cloud Emulator 中,您的 Web.config 也不会被转换。

我们可以解决这个问题的方法是挂钩到 Cloud 项目的构建过程。当您将项目部署到 Azure 时,将使用您可以挂钩的构建过程来构建云项目。简而言之,云项目构建了 web 和 worker 角色,并将它们放在你的云项目下的 Obj 文件夹下。然后,它运行一个基本上压缩所有内容的过程,最后将结果放入 Bin 文件夹。从那里,“zip”文件和配置文件被上传到 Azure。

解决方案

是手动编辑您的 Cloud.csproj 文件(如果您从 Visual Studio 中执行此操作,则需要先卸载项目)。 然后在结束 &lt;/project&gt; 标记上方添加这个:

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets" />
    <PropertyGroup>
      <WorkerRoleDir>$(IntermediateOutputPath)WorkerRole1\</WorkerRoleDir>
      <AppConfigOriginal>$(WorkerRoleDir)WorkerRole1.dll.config</AppConfigOriginal>
      <AppConfigTransformer>$(SolutionDir)WorkerRole1\App.$(Configuration).config</AppConfigTransformer>
      <AppConfigAfterTransformed>$(WorkerRoleDir)AfterTransformed.config</AppConfigAfterTransformed>
    </PropertyGroup>
    <Target Name="TransformAppConfig" AfterTargets="AfterPackageComputeService">
      <Message Text="Transforming $(AppConfigOriginal) via $(AppConfigTransformer) to $(AppConfigAfterTransformed)" />
      <TransformXml Source="$(AppConfigOriginal)" Transform="$(AppConfigTransformer)" Destination="$(AppConfigAfterTransformed)" />
      <Copy SourceFiles="$(AppConfigOriginal)" DestinationFiles="$(WorkerRoleDir)App.Config.Original" />
      <Copy SourceFiles="$(AppConfigAfterTransformed)" DestinationFiles="$(AppConfigOriginal)" />
    </Target>

注意事项

【讨论】:

  • 您有生产构建配置并且正在使用它构建吗?
  • 其实我有Web.Production.config (In MVC), ServiceConfiguration.Production.cscfg (In Cloud Project), app.Production.config (In Worker Role) 但只有app.Production.config 没有转换。但是app.Debug.config and app.Release.config 转换正确。所以我想删除所有生产配置并将值转移到调试和发布中。有什么建议吗?
  • 我已经删除了所有Production 配置,并在Debug and Release 配置上设置了正确的值。使用上面的配置代码一切正常。但是,如果您上面的代码也可以转换自定义配置,例如app.Production.config,那就更好了
  • 它可以——我自己就是这样用的。关键是项目构建配置和azure部署配置不一样。
  • 嗯.. 我对你的做法很感兴趣。但这是我通常的做法。当我创建要部署的包时,我右键单击 Cloud 项目 -> 包 ->(一个表单将显示两个组合框,一个用于 Service Configuration,另一个是 Build Configuration)。对于SC,我选择Production 与BC 相同,但Worker 角色中的BC config (app.Production.config) 不会转换。只有当我为BC 选择Debug or Release 时,它才会转换。但是转换 Web.Production.config 没有问题。
【解决方案4】:

确保您已设置云服务配置。右键单击云项目,您应该会看到您尝试打包的配置。例如,我重命名并使用本地、测试和生产配置。然后,您的云服务项目应包含 3 个配置文件:

  • ServiceConfiguration.Local.cscfg
  • ServiceConfiguration.PROD.cscfg
  • ServiceConfiguration.TEST.cscfg

右键单击云服务项目并选择“包”并为您的部署选择正确的服务和构建配置。

注意:app.configs 不会在构建过程中进行转换,除非您添加 MS - See this SO answer 以获得在构建过程中进行转换的技术。但是,对于云部署,最好将 ServiceConfiguration.*.cscfg 文件与 CloudConfigurationManager.GetSetting("settingsKey") 结合使用 - CloudConfigurationManager.GetSetting 已添加到 SDK 1.7 - 如果在角色中,它从 ServiceConfig 获取值,否则从 web.config/ app.config 应用设置

【讨论】:

  • 那行不通。服务配置对 app.config 没有任何影响。
  • 我建议使用 ServiceConfiguration.*.cscfg 文件而不是 appSettings。这些可以在门户中更新,而无需重新部署您的角色。答案已编辑。
猜你喜欢
  • 2011-03-17
  • 2015-04-12
  • 2015-03-25
  • 1970-01-01
  • 2011-08-22
  • 2014-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多