我正在寻找一些关于如何在每个客户的基础上轻松定制和扩展核心产品的建议。我知道这可能是一个太大的问题。然而,我们确实需要一些想法,因为如果我们设置错误,它可能会给我们带来多年的问题。我在定制和扩展现有产品方面没有太多经验。
我们有一个核心产品,通常根据每个客户进行定制。我们最近使用 MVC3 前端用 C# 4 重写了该产品。我们进行了重构,现在有 3 个项目组成了解决方案:
- 核心域项目(命名空间 - projectname.domain.*) - 由域模型(供 EF 使用)、域服务接口等(存储库接口)组成
- 域基础设施项目(命名空间-projectname.infrastruct.*)-实现域服务-EF上下文、存储库实现、文件上传/下载接口实现等。
- MVC3(命名空间-projectname.web.*)-由控制器、视图模型、CSS、内容、脚本等组成的项目。它还有 IOC (Ninject) 处理项目的 DI。
该解决方案作为独立产品运行良好。我们的问题是根据每个客户扩展和定制产品。我们的客户通常希望快速(通常在签订合同后几天内)获得带有品牌 CSS 和样式的核心产品版本。然而,70% 的客户希望通过定制来改变其运作方式。一些定制很小,例如域模型、视图模型和视图等上的附加属性。其他定制则更重要,需要全新的域模型和控制器等。
有些定制似乎对所有客户都有用,因此我们会定期更改它们的定制并将它们添加到核心中。
我们目前将源代码存储在 TFS 中。要启动项目,我们通常手动将源代码复制到新的团队项目中。更改命名空间以反映客户端名称并开始自定义基本部分,然后部署到 Azure。这显然会导致代码库完全重复,我确信这不是正确的方法。我认为我们可能应该拥有一些提供核心功能并在需要时扩展/覆盖的东西。但是我真的不知道该怎么做。
因此,我正在寻找有关最佳项目配置的任何建议,以允许:
- 快速部署代码 – 轻松启动新客户端
允许品牌/微小的改变
- 避免复制和粘贴代码的需要
- 尽可能多地使用 DI 以保持松散耦合
- 允许定制代码
每个客户基础
- 单一扩展核心产品的能力
放置并让所有客户获得该功能(如果我们获得)
最新版本的核心并重新部署
非常感谢任何帮助/建议。很高兴添加更多任何人认为有帮助的信息。
我可能无法完全回答这个问题,但这里有一些建议:
- 无论出于何种原因,永远不要复制您的代码。
- 不要重命名命名空间来标识给定的客户端版本。为此使用分支和持续集成。
- 选择如下分支模型:一个名为“Main”的根分支,然后从产品的每个主要版本的 Main 中创建一个分支,然后为每个客户端创建一个分支。当您开发某些东西时,从一开始就根据您正在做的事情确定要在哪个分支中开发(客户端特定功能将在客户端分支中,全局版本将在版本分支或客户端分支中,如果您想要原型一开始就是这样)
- 尽量依靠工作项来跟踪您开发的功能,以了解它在哪个分支中实现,以简化跨分支的合并。
为你的开发者定位正确的分支是最关键的事情,你不必定义一些“在什么情况下做什么”的硬性规则,但要尽量保持一致。
我从事过一个大项目长达 10 年,有超过 75 个版本,我们通常做的是:
- 下一个主要版本:从 Main、dev 里面创建一个新分支
- 下一个小版本:当前主分支中的 dev,使用 Labels 标记分支内的每个小版本。
- 一些复杂的功能特性是在客户要求的分支中开发的,当我们成功“去品牌”时,将其反向集成到版本分支中。
- 客户端分支中的错误修复,然后在需要时在其他分支中报告。 (您必须为此使用工作项,否则您很容易迷失方向)。
这是我的看法,其他人可能有不同的观点,我非常依赖工作项来跟踪代码,这对代码的交付和报告有很大帮助。
EDIT
好的,我添加一些关于分支的想法/反馈:
在软件配置管理 (SCM) 中,有两个功能可以帮助您进行版本控制:分支和标签。每一种都不比另一种更好或更差,这取决于您的需要:
- 标签用于使用标签来标记时间点,以便您稍后能够在需要时返回到该点。
- 分支用于“复制”您的代码以便能够工作同时有两个版本.
因此,使用分支仅取决于您想要做什么。如果您必须同时处理多个不同的版本(例如每个客户端一个):除了使用分支之外,没有其他方法可以处理它。
要限制分支数量,您必须决定什么将是新分支或将用标签标记什么:客户端特定版本、主要版本、次要版本、Service Pack 等。
使用客户端版本的分支看起来是理所当然的。
对每个主要版本使用一个分支可能是您做出的最艰难的选择。如果您选择对所有主要版本仅使用一个分支,那么您将无法灵活地同时处理不同的主要版本,但您的分支数量将尽可能少。
最后,Jemery Thompson 有一个很好的观点,他说并非所有代码都应该依赖于客户端,有一些库(通常是最低级别的库)不应该针对每个客户端进行自定义。我们通常做的是为框架、横切、低级服务库使用单独的分支树(不是每个客户端)。然后在每个客户端版本项目中引用这些项目。
我给您的建议是对这些库使用 Nuget 并为它们创建 nuget 包,因为这是定义版本化依赖项的最佳方法。定义 Nuget 包以及设置本地 Nuget 服务器非常简单。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)