在软件开发中,硬编码字符串(即“魔法字符串”)通常被认为是一种代码异味,应该尽量避免使用。在配置WCFDataServiceConfiguration对象时,经常需要传递实体集的字符串名称给配置方法,但这种做法存在缺陷。因此,在今天的文章中,将展示如何扩展DataServiceConfiguration对象,以便支持Lambda表达式而不是字符串参数。
创建了一个简单的静态类,其中包含两个新的扩展方法:SetEntitySetAccessRule和SetEntitySetPageSize。这两个方法扩展了DataServiceConfiguration对象,并增加了接收Lambda表达式的功能,该表达式将包含实体集名称。以下是类实现的代码:
public static class DataServiceConfigurationExtensions
{
public static void SetEntitySetAccessRule<DataSource>(
this DataServiceConfiguration config,
Expression<Func<DataSource, object>> expression,
EntitySetRights rights)
where DataSource : class
{
string entitySetName = GetEntitySetName(expression);
config.SetEntitySetAccessRule(entitySetName, rights);
}
public static void SetEntitySetPageSize<DataSource>(
this DataServiceConfiguration config,
Expression<Func<DataSource, object>> expression,
int pageSize)
where DataSource : class
{
string entitySetName = GetEntitySetName(expression);
config.SetEntitySetPageSize(entitySetName, pageSize);
}
private static string GetEntitySetName<DataSource>(
Expression<Func<DataSource, object>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("Must be a member expression");
}
return memberExpression.Member.Name;
}
}
以下是在配置数据服务时如何使用这个实现的示例:
public class SchoolDataService : DataService<SchoolEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule<SchoolEntities>(c => c.Courses, EntitySetRights.All);
config.SetEntitySetPageSize<SchoolEntities>(c => c.Courses, 10);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
如果实体集的名称发生变化,将得到编译错误而不是运行时错误。这种方法更不容易出错,代码也更清晰。由于InitializeService方法只被调用一次,对性能的影响可以忽略不计。
使用“魔法字符串”是一个坏习惯。在这篇文章中,展示了一个简单的解决方案,即使用Lambda扩展而不是字符串来配置WCF数据服务。
通过这种方式,可以提高代码的健壮性和可维护性。当实体集的名称需要更改时,可以立即得到编译时的错误提示,而不是在运行时出现问题。此外,使用Lambda表达式可以使代码更加清晰和易于理解。