我开始注意到我的谓词构建代码看起来很相似。这是重构它的标志。让我们看一下代码。
var predicate = PredicateBuilder.False<ArticleLikeInfo>();
// Under the covers it will get Guid from a cookie (one way to track a user)
Guid? key = _userKeyService.GetKey();
if (key.HasValue)
{
predicate = predicate.OrElse(x => x.UserKey == key.Value);
}
String ip = Request.UserHostAddress;
if (!String.IsNullOrEmpty(ip))
{
predicate = predicate.OrElse(x => x.UserIp == ip);
}
UserInfo user = _userSessionService.CurrentUser();
if (user != null)
{
predicate = predicate.OrElse(x => x.UserId == user.Id);
}
bool hasVoted = _articleService.GetLikes().Where(x => x.ArticleId == m.Id)
.Where(predicate)
.Any();
当我需要检查用户是否按下了文章上的“喜欢按钮”时,此代码运行。跟踪我使用的用户
- 来自 cookie 的间谍 guid 密钥
- IP地址
- UserId 如果他已经登录
当我发出 ajax 调用以在数据库中为一篇文章插入“赞投票”时,同样的代码会运行。
所以我想封装它。我的第一个想法是选择扩展方法方法,但我不喜欢它,因为我将不得不求助于 ServiceLocator 模式来获取对此类服务的引用
IUserKeyService service = ServiceLocator.Current.GetInstance<IUserKeyService>();
我觉得那将是一个糟糕的设计,因为它不可测试。我想要一个可重用的类,同时可以由 DI 容器控制。我可以将依赖项注入的类。可能吗 ?