Below is the code to a Message Service. Does anyone have any ideas on how to improve the methods. It doesn't feel clean to me.
public enum MessagesType
{
Standard,
LocationTargeted,
Scheduled,
Expired
}
public class MessageService : GenericService<PushMessage>
{
public MessageService(IGenericRepository<PushMessage> messages)
: base(messages)
{
}
public IQueryable<PushMessage> Get(AuthenticatedUser user, MessagesType type)
{
var messages = this.Get();
switch (type)
{
case MessagesType.Standard:
messages = messages.Where(_ => string.IsNullOrEmpty(_.LocationLatitude) && _.ReleaseDate == null).IsNotExpired();
break;
case MessagesType.LocationTargeted:
messages = messages.Where(_ => !string.IsNullOrEmpty(_.LocationLatitude)).IsNotExpired();
break;
case MessagesType.Scheduled:
messages = messages.Where(_ => _.ReleaseDate > DateTime.MinValue);
break;
case MessagesType.Expired:
messages = messages.Where(_ => _.ReleaseDate > DateTime.MinValue && _.ExpireDate < DateTime.Today);
break;
default:
throw new NotSupportedException();
}
return this.FilterMessagesForUser(user, messages);
}
private IQueryable<PushMessage> FilterMessagesForUser(AuthenticatedUser user, IQueryable<PushMessage> messages)
{
if (user.Role == Role.Administrator)
return messages;
if (user.Apps.Length > 0)
{
if (user.Locations.Length > 0)
messages = messages.Where(_ => _.Locations.Select(l => l.Id).Intersect(user.Locations).Any());
else
messages = messages.Where(_ => user.Apps.Contains(_.AppId));
}
else
{
messages = messages.Where(_ => _.App.ClientId == user.ClientId);
}
return messages;
}
}
public static class MessageExtensions
{
public static IQueryable<PushMessage> IsNotExpired(this IQueryable<PushMessage> query)
{
return query.Where(_ => _.ExpireDate == null || _.ExpireDate == DateTime.MinValue || _.ExpireDate < DateTime.Today);
}
}
FilterMessagesForUser
from the perspective of "Tell, Don't Ask" - you are asking User a lot about its state. \$\endgroup\$