C# 在ASP.NET中遵循DRY原则
我最近刚刚参与了一个经典的ASP.NET项目,其中包含大量存储和读取会话和查询字符串中的值。这可能类似于以下内容:C# 在ASP.NET中遵循DRY原则,c#,asp.net,dry,C#,Asp.net,Dry,我最近刚刚参与了一个经典的ASP.NET项目,其中包含大量存储和读取会话和查询字符串中的值。这可能类似于以下内容: Session["someKey"]=someValue; 在代码的其他地方,会话中的值被读取。显然,这违反了DRY原则,因为文字字符串键将分布在整个代码中。避免这种情况的一种方法是将所有键存储为常量,在需要读写会话的任何地方都可以引用这些常量。但我不确定这是最好的方法。你会建议我如何最好地处理这个问题,这样我就不会违反干燥原则了 我觉得你读得太多了。我更多地关注可以封装在函数中
Session["someKey"]=someValue;
在代码的其他地方,会话中的值被读取。显然,这违反了DRY原则,因为文字字符串键将分布在整个代码中。避免这种情况的一种方法是将所有键存储为常量,在需要读写会话的任何地方都可以引用这些常量。但我不确定这是最好的方法。你会建议我如何最好地处理这个问题,这样我就不会违反干燥原则了 我觉得你读得太多了。我更多地关注可以封装在函数中的东西。也就是说,不要到处重复相同的五行代码,而是将这五行代码封装在一个函数中,并在需要的地方调用该函数
例如,您只需在字典(本例中为会话对象)中设置一个值,这是在字典中存储和检索对象的最简单方法。创建一个单独的公共类,您可以在其中定义常量,例如
public class SessionVars
{
public const string SOME_KEY = "someKey";
public const string SOME_OTHER_KEY = "someOtherKey";
}
然后,您可以在代码中的任何位置访问如下会话变量:
Session[SessionVars.SOME_KEY]=someValue;
通过这种方式,您可以获得IntelliSence和其他功能。您还可以选择将对该会话对象的访问权放在一个基本页中,并将其包装在一个属性中:
class BasePage : Page
{
...
public string MySessionObject
{
get
{
if(Session["myKey"] == null)
return string.Empty;
return Session["myKey"].ToString();
}
set
{
Session["myKey"] = value;
}
}
...
}
这里重复的是
myKey
字符串,但它被封装到属性中。如果您想避免这种情况,请使用键创建一个常量并替换字符串。我一辈子都记不起这段代码是从哪里来的,但它非常好:
using System;
using System.Web;
namespace Project.Web.UI.Domain
{
public abstract class SessionBase<T> where T : class, new()
{
private static readonly Object _padlock = new Object();
private static string Key
{
get { return typeof(SessionBase<T>).FullName; }
}
public static T Current
{
get
{
var instance = HttpContext.Current.Session[Key] as T;
lock (SessionBase<T>._padlock)
{
if (instance == null)
{
HttpContext.Current.Session[Key]
= instance
= new T();
}
}
return instance;
}
}
public static void Clear()
{
var instance = HttpContext.Current.Session[Key] as T;
if (instance != null)
{
lock (SessionBase<T>._padlock)
{
HttpContext.Current.Session[Key] = null;
}
}
}
}
}
然后沿着这条路扩展MyClass
,您不需要记住所有的键值,将它们存储在AppSettings或静态类中的Const变量中。您只需定义要存储的内容:
public class MyClassSession : SessionBase<MyClass>
{
}
+1这是我倾向于遵循的模式-它确实有助于消除那些讨厌的打字错误。在这种情况下,你不应该使用
const
<代码>静态只读更合适(也更安全)。这如何减轻“不要重复”的原则?您仍然在到处编写相同的1行程序,您只是在使用常量变量而不是键的实例字符串?这与我之前所做的类似,可能是我将要做的,结合在属性中包装会话。它消除了记住字符串并正确键入的需要,您获得了intellisense,并且只有一个地方可以更改密钥。至于这不符合干燥原则的问题,至少这是向前迈出的一步。如果你认为编写一行SessionVars.SOME_KEY违反了DRY,那么我认为这是对DRY的一种解读,正如在另一篇文章中所回答的那样。我希望你永远不要继承一个充满需要维护的神奇字符串的项目……感谢@Erik Philips提供了结构良好的代码。我真的很喜欢。“能给我们举个更清楚的例子吗?@JohnNate我不知道怎么才能更清楚。”。是的,我想看一个在ASP.NET Web中应用代码的例子Forms@JohnNateAFAIK它可以在webforms中工作,无需修改。创建您的MyClass
以存储结构化数据,从SessionBase
派生您自己的MyClassSession
类,然后在Web表单中使用MyClassSession
。
public class MyClassSession : SessionBase<MyClass>
{
}
// Any Asp.Net method (webforms or mvc)
public void SetValueMethod()
{
MyClassSesssion.Current.Blah1 = "asdf";
}
public string GetValueMethod()
{
return MyClassSession.Current.Blah1;
}