3

我正在尝试以减少/避免代码重复的方式构造我的代码,但我遇到了一个有趣的问题。每次我的代码调用存储过程时,我都需要传递一些存储过程共有的变量:例如用户名、域、server_ip 和 client_ip。这些都来自 HttpRequest 对象或 system.environment 对象。

由于这些被传递给每个存储过程,我最初的想法是创建一个实用程序类,它是一个数据库包装器,并且每次都会初始化并传递它们,所以我不必在我的代码中这样做。问题是尽管 c# 类(在 App_Code 文件夹内)看不到 Httprequest 对象。当然,我可以将此作为参数传递给包装器,但这会破坏创建包装器的整个目的。我在这里错过了什么吗?

我意识到每次调用存储过程时重复 4 行代码并不是什么大不了的事,但我宁愿在早期阶段消除代码重复。

4

7 回答 7

4

将数据层设置为从包含这些值的 4 个属性的基类继承。使公共构造函数需要这 4 个属性。

然后在业务层做类似的事情——在构造函数中使用这 4 个属性的基类。

然后 UI 执行 new BusObj( Request["username"], ... ).method()

在数据层中,您可以有一个方法来构建具有这 4 个属性的 SQLParameter 数组,然后每个方法都可以向数组添加其他参数。

于 2009-02-26T02:02:01.087 回答
3

作为一般规则,无论编程语言如何,如果您可以眯起眼睛并且代码看起来相同,您应该从中创建一个函数/方法/消息并传递参数。

另一件事是,一旦你的方法采用大量参数(4 是一个很好的经验法则,但它肯定是逐个案例的基础),是时候让该方法接受一个对象作为参数了而不是单个参数。99.99999999999999999999% 的时间这样的对象应该是不可变的(没有可写的实例变量)。

于 2009-02-26T01:32:25.620 回答
2

HttpContext.Current 与您在 HttpRequest 中找到的信息相似,更重要的是在 App_Code 中可用。

于 2009-02-26T01:18:18.867 回答
2

这是一个你可能喜欢也可能不喜欢的奇怪想法:定义一个“配置文件”类和一个函数,该函数将配置文件扩展为采用公共参数的函数的参数。

class P {
    readonly string name;
    readonly string domain;
    public P(string name, string domain) {
        this.name = name; this.domain = domain;
    }
    public void inject(Action<string, string> f) {
        f(p.arg1, p.arg2);
    }
    public T inject<T>(Func<string, string, T> f) {
        return f(p.arg1, p.arg2);
    }
}

它可能在您拥有 AddressOf 运算符的 VB.net 中工作得更好。我会非常谨慎地使用这种类型的东西,因为你很容易破坏可读性和封装性。

于 2009-02-26T01:29:56.547 回答
1

我会按照你现在的方式保留它。它更干净,更容易扩展/修改,更容易进行单元测试。

至于像其他人建议的那样使用 HttpContext ,我会说这是一个坏主意。一旦你开始在你的域中引入对 HttpContext 的依赖,就很难将其移除。如果以后你想在没有 HttpContext 的情况下使用你的模块怎么办?那么单元测试呢?

于 2009-02-26T01:18:33.593 回答
1

尝试 System.Web.HttpContext.Current.Request 以获取当前请求。

于 2009-02-26T01:19:13.000 回答
1

你可能正在滑下一个滑坡。DRY 的要点是不要在多个地方重复业务逻辑,因为需求的变化会导致需要在多个相似的地方更改代码。如果这 4 行是上下文相关的,那么您不必仅仅因为 4 行是相同的而重构。您还通过引用 httprequest 来破坏封装,因为您使用的是全局变量。作为你类的消费者,我必须知道我只能从 Web 应用程序调用你的实现细节。

话虽如此,如果您考虑到这一点并仍想继续,这里是此类信息的另一种选择。创建包含所需属性的自定义 SecurityPrincipal(实现 IPrincipal)并将其附加到线程。在用户登录时填写它们,然后您可以在请求期间的任何地方访问它。您的调用者仍需要确保已完成此操作,但至少它不是特定于平台的。

否则,为了获得最佳封装,请将具有您需要的属性的类传递给需要使用这些属性的每个对象的构造函数。

于 2009-02-26T01:42:24.737 回答