使用静态方法创建Web应用程序助手类是否安全?

时间:2014-11-06 19:13:14

标签: c#

我不喜欢Entity FrameworkLINQ,而且我是一名通过帮助班使用旧方法的老学程序员。

以下是我将数据插入数据库的一种方法示例。

private class Database
{
    public static void DbInsert(string table, string[] columnNames,
        string[] dataToAdd)
    {
        string tblValues = "";
        string tblRaw = "";
        string tblValuesCN = "";
        string test = "";
        string sql = "";
        SqlConnection sqlConn = new SqlConnection();
        SqlCommand sqlCmd = new SqlCommand();

        sqlCmd.CommandType = CommandType.Text;
        sqlConn.ConnectionString = ConnectionString();

        for (int i = 0; i < dataToAdd.Length; i++)
        {
            sqlCmd.Parameters.Add(new SqlParameter("@" + i.ToString(),
                dataToAdd[i].ToString()));

            test += dataToAdd[i].ToString() + " --- ";
            tblValues = tblValues + "@" + i.ToString();
            tblRaw = tblRaw + dataToAdd[i].ToString();

            if (i != dataToAdd.Length - 1)
            {
                tblValues = tblValues + ",";
                tblRaw = tblRaw + ",";
            }
        }

        for (int i = 0; i < columnNames.Length; i++)
        {
            tblValuesCN = tblValuesCN + columnNames[i].ToString();

            if (i != columnNames.Length - 1)
            {
                tblValuesCN = tblValuesCN + ",";
            }
        }

        sqlCmd.CommandTimeout = 0;
        sqlCmd.CommandText = "Insert Into " + table + "(" + tblValuesCN +
            ") Values (" + tblValues + ")";

        sql = "Insert Into " + table + "(" + tblValuesCN +
            ") Values (" + tblRaw + ")";

        sqlConn.Open();
        sqlCmd.Connection = sqlConn;
        sqlCmd.ExecuteNonQuery();

        sqlConn.Close();
        sqlConn.Dispose();
        sqlCmd.Dispose();

        string[] tlCn = {"TableName", "PatientID", "StaffID", "SQL", "DateTime"};
        string[] tlCv =
            {
                table, HttpContext.Current.Session["PatientID"].ToString(),
                HttpContext.Current.User.Identity.Name.ToString(),
                sql, DateTime.Now.ToString()
            };

        DbInsertTL("TransactionLog", tlCn, tlCv);
    }
}

现在我开始怀疑,这是安全的,因为该方法是静态的吗?我开始怀疑是因为一次投诉,他们没有添加的内容是来自其他用户的数据库。

我讨厌使用这个类的静态方法从网页后面的代码中实例化所有内容,但是我会尽我所能来保持完整性。

1 个答案:

答案 0 :(得分:4)

有些东西是安全的,直到一些资源可能被一个以上的线程访问,或者一个或多个线程正在访问应该明确处理的非托管资源,或者它们可以保持锁定以死锁结束

现在假设您将SqlConnection声明为静态字段,并且方法处理它,而其他HTTP请求中的其他要求即将执行命令... CRASH !! 。您需要同步对SqlConnection实例的访问权限。您甚至可以实现连接池或其他任何东西(好吧,SQL Server已经有连接池,这只是一个例子)。

在您的情况下,最可能的不安全代码之一,但与它包含在静态方法中的事实无关,是您创建SqlConnection并且不使用using语句的地方,这提供了更多的安全性,因为您完全保证在结束using块之后将其处理:

// Equivalent to try/finally where finally 
// block will implicitly call SqlConnection.Dispose() for you
// even if some exception is thrown within the using block
using(SqlConnection conn = ...) 
{

}

您可能会创建非公开的SQL连接,并且您可能最终会过度使用SQL Server连接池,或者只是因为没有更多连接可用而导致应用程序崩溃...

无论如何,我怀疑你的论点“我喜欢静态方法,因为我讨厌实例化类”正在推动你朝着正确的方向发展。

C#是一种完整的面向对象编程语言,您应该创建对象图,并以面向对象的方式分离您的关注点 - 也就是说,您应该避免使用类作为函数模块 - 。

也许你应该看看façade设计模式。这种模式可以创建一个可以简化复杂事物的类。

例如,您需要注册用户,这意味着实例化一些域类。由于注册用户是一个用例,您可以简化它实现可能具有UserFacade方法的RegisterUser,这将执行该域操作,因此赢得更高级别的层我们需要重复相同的代码,他们将对低级域名详细信息保持不可知......

更新

OP说:

  

你会实例化console.write吗?它以类似的方式使用

是的,对,有一些辅助类,它们是作为静态类实现的。

你的情况对于静态类来说听起来不好,因为每个方法都在重复代码来创建SQL连接和其他可以封装并在任何地方使用的细节,以避免代码重复(复制粘贴编程......)。 p>

您可能每次都打开和关闭连接,并且您失去了分批连接或发送命令的机会。

如果你尝试使用静态类来实现上述建议,你会以一堆不可维护的方法和spaguetti代码结束,因为缺乏关注点分离...或者,至少,我们不会谈论一个面向对象的解决方案......

您可能会使用静态类。例子:

  • 帮助程序类(不是你的情况......你的情况是一个低级数据访问层,如果你坚持使用C#,应该使用面向对象的方法实现)。

  • 扩展方法。

  • 工厂方法。

  • ...