【问题标题】:Website Architecture - Control/Object Loading Based on Config?网站架构 - 基于配置的控制/对象加载?
【发布时间】:2013-05-21 15:44:54
【问题描述】:

我正在构建一个网站,在某些市场上需要稍作改动。例如,在英国市场,注册表单需要执行地址验证(已经可以使用),而在比利时站点上,我们需要使用 Web 服务验证人员(已经可以使用)。否则,注册功能基本相同。我们有这两个站点独立工作,但我们希望将它们合并到一个代码库中,该代码库可以支持基于配置的任一选项。

我最初的想法是使用配置值来表示“这是一个英国站点”或“这是一个比利时站点”,并根据此设置显示页面。

想法:

  • 依赖注入根据配置动态加载控件
  • 使用反射/激活器并根据配置动态加载的工厂模式
  • 通过设置标记名/标记前缀配置转换以加载不同的用户控件
  • 其他?

有没有人对我在哪里可以找到此类设计灵感的建议有任何初步想法?

【问题讨论】:

    标签: c# asp.net .net design-patterns configuration


    【解决方案1】:

    我建议尽量保持简单和最小化。

    只需创建类似IPersonValidator 的东西,它有一个.Validate(PersonDetails) 方法并返回一个错误数组。

    编辑:

    在配置方面,您可以创建以下结构的自定义配置部分:

    <DomainSpecificSettings>
     <Key name="validator">
      <Value domain="www.yoursite.co.uk" value="firstValidator" />
      <Value domain="www.yoursite.de" value="secondsValidator" />
     </Key>
    </DomainSpecificSettings> 
    

    还有一件事 - 您不需要使用 Activator。你可以有一个单独的验证器存储,它为每个验证器类型保存一个实例,并且知道如何根据当前查看的市场的数据库配置设置找到正确的验证器:

    ValidatorsStore.GetValidator(string configValue).Validate(PersonDetails).
    

    这种情况下的设计很容易成为这样一个简单任务的过度杀伤力。我的方法是首先让它工作得足够好,然后才检查你是否需要让它更健壮。大多数情况下你不会。

    【讨论】:

    • 感谢您的回复!这对我来说很有意义。只是几个问题: - 每个“市场”都必然需要新的部署。我把它放在 Config 中的想法是,一旦它被设置为部署,它就永远不会改变。该站点仍然是该特定实现(英国或比利时,或其他) - 对于 configValue,您是否看到将 URL 作为值的好处?例如“sitename.co.uk”与“sitename.be”?这是主观的,但只是在寻找想法。 :)
    • 您是否打算使用完全相同的代码但将其部署到两个不同的位置?如果是这样,那么我误解了您的问题:) 无论如何,如果是这种情况,那么将其存储在配置中会更有意义。你可以在这里使用策略设计模式。每个“策略”都将是一个类或实现相同接口的类的集合——与我提供的示例完全相同。听起来您将在流程中拥有更多“拆分”,因此您可以在某种 StrategyProvider 类中为所有这些拆分保留不同的策略。是不是太含糊了,还是你明白我的意思?
    • 这绝对有帮助。是的,相同的代码库可以精确部署到所有生产环境,但是有一个配置标志来表示要使用的站点版本(也对此提出建议,但它似乎是这里其他人的首选方法。)我'我对策略模式有些熟悉,但并不特定于这个例子。我将不得不审查更多。真的只是想从哪里开始。
    • 策略我的意思是根据域加载不同的策略。您是否考虑过完全访问相同的代码(仅一次部署)但使用不同的域名?我的另一个想法是将配置键实现为自定义配置部分部分。请查看我的更新答案
    • 再次感谢您。由于监管限制,我们的部署必须在其所在国家/地区托管。所以英国和BE网站没有以任何方式链接。域名不一定会改变,但不确定是否基于 URL 是最好的主意(这在 IP、localhost 或内部主机名的测试场景中如何工作?)设置一个或如果更容易实现,则为每个环境提供更多配置值(希望我们很快就会使用 Puppet 自动部署!)
    【解决方案2】:

    首先,当您提到“加载用户控件”时,认为将实现的表示部分与逻辑/验证本身分开会更好。您可以创建(或细化)适用于所有国家/地区的通用用户控件,但调用逻辑以在英国的情况下进行地址验证,或者在 BE 的情况下不进行任何操作。 MVC 世界中的单一职责原则或关注点分离。

    还使用相同的原则将不同用户控件中的页面的不同组件与其逻辑分开。在调用最终注册/注册之前,每个组件都有自己的验证。通过这种方式,您可以通知玩家输入数据中的验证错误,而无需提供完整的玩家信息来进行注册。提供并验证玩家的完整信息后,您可以调用将玩家保存在数据库中的注册。

    关于决定调用哪个逻辑的 StrategyProvider 类,同意 Uri,我们将有很多地方的逻辑在国家之间有所不同。但这不是我们可以用 IoC 容器设置的东西吗?对 IoC 容器了解不多,但如果逻辑是“静态的”(当您在网站上时,它不会根据请求而改变)可以在应用程序启动时设置它。

    另一种可能性是使用 SOA 模式并根据您所在的网站调用不同的服务。(可以在配置中设置相同的服务端点)。不同国家的服务可以有不同的逻辑,但返回一个遵循通用接口的类(使用适配器模式)。

    【讨论】:

    • 非常好的信息。同意位置特定的逻辑可以在实际的用户控件中进行相当多的排序。我(还)不太确定的是如何确定要加载哪个用户控件。从技术上讲,因为这将在 Umbraco 中进行,所以可以在那里做出决定,但理想情况下从配置中删除对 CMS 的依赖。我认为您提到的通用用户控制理念解决了这个问题。这么多要考虑! :)
    • 用户控件应粘贴在母版页上。最有可能的是,不同国家的母版页会有所不同。在这种情况下,您可以粘贴不同的用户控件或使用参数来确定查看模式。如果母版页相同,但用户控件(例如地址输入)不同,则母版页中可能有一些逻辑决定(取决于 Url、配置...)动态加载哪个控件(策略模式 LoadControl("~/xxxxControl. ascx")) 或提供参数查看模式。
    • 也许第一个复杂性是尝试在 ASP.NET 表单中使用依赖注入模式,但正如 herehere 所解释的那样。如果将 Umbraco 6 与 MVC 一起使用应该会更容易,因为这是 MVC 存在的原因之一。 An MVC example
    猜你喜欢
    • 1970-01-01
    • 2013-03-10
    • 2023-03-07
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 2023-01-11
    • 1970-01-01
    相关资源
    最近更新 更多