.net 如何为每个客户管理同一软件的多个版本?

.net 如何为每个客户管理同一软件的多个版本?,.net,version-control,visualsvn,svn,visualsvn-server,.net,Version Control,Visualsvn,Svn,Visualsvn Server,我的源代码对所有客户来说都是95%相同的。然而,有些客户要求一些特定的东西。我如何管理它,是否可以使用VisualSVN/Subversion 更新: 关于这个应用程序的一些细节,它是一个带有NHibernate的web ASP.NET MVC 该应用程序有几个项目:web部件、repo部件(我们使用NHibernate访问数据库的地方)和一个服务项目 服务项目使用回购项目,服务项目是具有业务规则的项目。将特定于客户的代码放在单独的项目/程序集中。类似于策略模式或插件的东西可能是一条出路 另一个

我的源代码对所有客户来说都是95%相同的。然而,有些客户要求一些特定的东西。我如何管理它,是否可以使用VisualSVN/Subversion

更新: 关于这个应用程序的一些细节,它是一个带有NHibernate的web ASP.NET MVC

该应用程序有几个项目:web部件、repo部件(我们使用NHibernate访问数据库的地方)和一个服务项目


服务项目使用回购项目,服务项目是具有业务规则的项目。

将特定于客户的代码放在单独的项目/程序集中。类似于策略模式或插件的东西可能是一条出路


另一个不太吸引人的方法(IMO)是为每个客户创建单独的分支机构,但这很快就会变得难以维护。

我可以想出两种可能有效的方法

第一个涉及为每个客户分支代码。在主线中进行的任何编辑都可以在需要时集成到特定客户的分支中。类似地,如果核心产品中的某些内容在分支中固定,则可以将其合并回主线,以便随后传播到其他客户的分支。虽然这似乎是最好的方法,但很难维护和跟踪哪个分支进行了哪些编辑,哪些编辑会令人担忧


第二种可能更好的方法是重构代码,使特定于客户的代码位于单个程序集中—每个客户一个。然后,在安装产品时,可能通过使用依赖项注入来配置此功能。这样,您只有一个代码行,分支之间没有合并。虽然它确实依赖于客户特定的代码很容易分离出来。

如果没有什么大不了的,我会选择appp设置和工厂模式。或每个客户的特定组件

但从标签上看,你似乎想通过版本控制来解决这个问题。但这将给合并等带来巨大冲击。
您必须为每个客户创建分支,并将更改从主干合并到它们。

5%的区别在于仅基于UI还是同时基于业务逻辑? 如果基于UI,则应指定UI层,并随应用程序一起发送/编译相应的UI文件。
如果是业务逻辑,则更为复杂。也许分支(通过SVN)可以提供帮助。但当前应用程序的开发仍存在问题,因此不建议使用。

我们采取的方法是:

  • 在应用程序中插入钩子,允许自定义默认行为(例如,当调用
    保存
    操作时,内部发生的第一件事是调用
    OnSaveHandler
  • 默认处理程序不执行任何操作,它只返回“continueWithNormalExecution”。所有处理程序都位于与原始应用程序(不同程序集)不同的模块中,我们称之为
    behavior模块
  • 对于基于客户端的请求,我们通过覆盖默认的“不做任何事情行为”来修改此
    行为模块。此修改处理程序的返回代码可以是:
    ContinueNormalExecution
    SkipNormalExecution
    TerminateExecution
    ,等等
  • 在其他情况下,我们根据接口插入钩子。在
    行为模块
    中,我们将有更多的处理程序实现此接口,例如
    DoStuffInterface
    ,在加载时使用反射解析
    行为模块
    ,所有实现
    DoStuffInterface
    的处理程序将在系统中注册。 然后,在原始应用程序中,我们将有如下内容:如果
    getdostuffiterfacehandler(handlerID)不是空的
    ,那么
    getdostuffiterfacehandler(handlerID).DoStuff()
    。定义要使用的handlerId是可配置的(可以通过db表、xml文件等)

    我们最终会有多个处理程序使用不同的ID实现
    DoStuffInterface
    ,并在不同的时间调用它们

通过这种方法,我们有:

  • 具有默认行为的基本应用程序
  • 一个可配置的模块(组件)定制了应用程序的工作方式
这种方法面临的挑战是找到客户可能想要定制的“甜点”-行为,并在其中插入挂钩


希望我的描述清楚,如果不是。。。请留下评论:)

使用版本控制解决此问题可能会导致比解决问题更多的问题

其他人建议将特定于客户端的代码分离为单独的程序集和/或使用依赖项注入是一种方法

另一个选择是使用

您需要调整构建脚本以构建特定的客户二进制文件。例如:

msbuild mysolution.sln /property:DefineConstants="CustomerA"

msbuild mysolution.sln /property:DefineConstants="CustomerB"

#ifdef ACME/#endif等的一个有用的附加功能是为ACME_ONLY()、NON#ACME()、FROBOZCO#ONLY()、NON#FROBOZCO()等宏定义宏。如果新版本投入使用(在这种情况下,新版本的行为应该像Acme、FrobozCo等),东西仍然会变得混乱,但是如果Acme和非Acme版本之间只有一行不同,这种方法避免了两行指令围绕这一行。

好问题。当然,我很期待收到大家的来信。第一句话,是的,但是我更喜欢把公共代码放在库项目中,而不是插件。当然,这完全取决于具体的项目。我想建议ig你从subversion切换,分支的痛苦基本上消失了。尽管如此,我仍然会尝试将应用程序中客户最想定制的部分分开。但是,我会推荐多个分支。这个解决方案不能很好地扩展,如果你有5个或10个客户呢。如果不知道5%是什么,就不可能说出正确的方法是什么
msbuild mysolution.sln /property:DefineConstants="CustomerA"

msbuild mysolution.sln /property:DefineConstants="CustomerB"