将公共项目与.NET MVC中的构建变体合并

fil*_*lur 25 c# asp.net-mvc

我有一个.net mvc网站,应该发布给很多不同的客户,因此根据目标略有不同.

有没有办法建立核心项目结构,例如(简化):

  • 意见
  • 楷模
  • 控制器
  • 资产
  • 箱子

并在构建时使用当前目标可能具有的任何变化进行合并.例如:

核心项目:

  • 意见
    • view1.cshtml
    • view2.cshtml

(为简洁起见,删除了其余的文件夹)

客户1目标:

  • 意见
    • view2.cshtml
    • view3.cshtml

期望的合并结果:

  • 意见
    • view1.cshtml(来自核心项目)
    • view2.cshtml(来自客户1目标)
    • view3.cshtml(来自客户1目标)

同样的规则应适用于控制器,二进制文件等.

Twi*_*tem 8

我会使用多个项目,nuget或使用源代码控制.我将在下面讨论这些想法,但没有特别的顺序.最后,我可以包括对一个或另一个的偏好.

我要谈的第一个想法是使用多个项目.创建您的基础项目,我们称之为WebBase.创建您谈过的核心网站.接下来创建Customer1网站,如果您将Customer1创建为空网站,则需要在WebBase中重新创建文件夹结构,或者您可以像创建WebBase一样创建它并删除所有文件(从Visual Studio中执行此操作); 无论哪种方式,你最终得到没有文件的文件夹结构.我建议使用AssemblyInfo.cs保留web.config,packages.config,Properties文件夹.然后,您将从WebBase添加文件,但不要只是正常添加它们.为了说明的目的,让我们做主页索引视图:展开Customer1中的Views文件夹,右键单击home,选择add,选择Exising Item,浏览Customer1然后进入WebBase/Views/Home并单击index.cshtml,现在注意按钮上的下拉?单击它并选择"添加为链接".现在对WebBase中的所有文件执行此操作!每次选择"添加为链接"似乎很麻烦,但如果您只是单击添加,它将复制文件并且更新不会从WebBase传播到Customer1!此外,您将看到诸如从项目删除和删除之类的内容(带有关于永久删除的提示).

第二个想法是为WebBase创建一个nuget包,你可以将它作为一个包安装,这种方法的好处是版本化,并且它不需要你用每个小的更改来更新每个项目.它会使每个项目完全孤立.缺点是您需要单独更新每个项目以在全球范围内传播更改.您需要了解nuget的nuspec文件以及如何包含文件等.它不是那么糟糕,它只是XML.但是,您可以指定在安装/更新软件包时要包含的文件.

第三个是源代码控制,我知道使用git你可以使用子模块来包含一个单独的项目(甚至来自外部存储库).这可能是一个选项,或者您可以创建WebBase分支,设置WebBase,然后将其分支到每个客户的网站.因此,创建一个名为Customer1的分支,开始添加自定义客户的东西.切换回WebBase,创建一个名为Customer2的新分支......您将参加比赛.切换回WebBase,进行全局更改,然后将这些更改合并到Customer1和Customer2分支中.

好的,我会承认,我可能会选择第三种选择.它给你带来很多好处,但有点缺点.它甚至可以给你历史!如果你目前没有使用源代码控制......你应该!你可以在你的机器上安装git,并且能够在本地检查代码,你不必担心外部存储库(虽然我建议你有一个,因为它给你DR).

无论哪种方式,都有可用的选项.但是没有什么比具有可配置文件的单个项目包括.

祝好运!


And*_*nov 6

首先想到的是(并且可能最简单,因为它不需要任何额外的工具)是创建具有核心功能,视图和控制器的核心项目.并为每个客户创建具有自定义视图和控制器的单独项目.然后,对于客户特定项目,只需链接核心项目中的所有必需文件.根据数量链接文件可能有点乏味,但似乎可行.

另一种方法可能是使用像CAKEFAKE这样的工具,借助它们可以按照自己的方式编写整个构建过程的脚本,但我自己从未尝试过这样的自定义脚本.

我可以使用的第三个选项是有条件地包含基于已定义常量的文件,但这需要编辑*.csproj文件.代码可以是这样的:

<Content Include="Views\View1.cshtml" />
<Content Include="Views\View2.cshtml" Condition="$(DefineConstants.Contains('CORE'))" />
<Content Include="Views\View2.cshtml" Condition="$(DefineConstants.Contains('CUSTOMER1'))" />
<Content Include="Views\View3.cshtml" Condition="$(DefineConstants.Contains('CORE'))" />
<Content Include="Views\View3.cshtml" Condition="$(DefineConstants.Contains('CUSTOMER1'))" />
Run Code Online (Sandbox Code Playgroud)

不知道维护它有多容易.

我可能会考虑将应用程序拆分为独立的组件/项目,其中包含与组件相关的所有功能.在构建期间,基于特定客户端所需的组件,使用FAKE组成组件.


Boz*_*eff 6

您的需求是自定义Visual Studio项目模板的理想选择.

我正在考虑准备一个大型项目,其中包含您为任何客户部署的所有功能.当需要新功能或修复时,此项目也可能是您可能更新的主干.然后,将trunk-solution导出到模板中.然后继续使用VSIX项目模板并将向导合并到其中,以收集项目创建的用户输入.根据输入采取适当的操作,并根据需要添加/删除必要的文件或启用/禁用功能.

或者您可以将源文件保留在文件系统上并将其组织到模板中 - 即,由于向导期间的用户输入.在向导结束时,模板已部署并且......瞧.