Skip to content

Instantly share code, notes, and snippets.

@brucewilkins
Last active September 14, 2017 16:30
Show Gist options
  • Save brucewilkins/d406690b1e2196424c6439a0fd0327c0 to your computer and use it in GitHub Desktop.
Save brucewilkins/d406690b1e2196424c6439a0fd0327c0 to your computer and use it in GitHub Desktop.
Brief code snippets based on a real life project intended to show my approach to coding. The 'after' samples show some code that I re-wrote based on the 'before' code. The samples are intended to show the difference between code that is well structured, readable, testable, easily extendable, uses patterns, dependency injection, and code that is …
using ...;
namespace Company.Project.Service.Controllers.Api
{
[Route("api/[controller]")]
public class EventsController : Controller
{
private readonly IQueryDispatcher _queryDispatcher;
public EventsController(IQueryDispatcher queryDispatcher)
{
_queryDispatcher = queryDispatcher;
}
// GET api/events
[HttpGet]
public async Task<IEnumerable<Event>> Get()
{
return await _queryDispatcher.Execute<GetEventsQuery, IEnumerable<Event>>(
new GetEventsQuery(User.GetIdentifier())
{
IncludeSessions = false
});
}
// GET api/events/5
[HttpGet("{id:int}")]
public async Task<Event> Get(string id)
{
return (await _queryDispatcher.Execute<GetEventsQuery, IEnumerable<Event>>(
new GetEventsQuery(User.GetIdentifier())
{
Id = id,
IncludeSessions = true,
})).Single();
}
}
}
using ...;
namespace Company.Project.Service.Data.Queries
{
public class GetEventsQuery : IQuery<IEnumerable<Event>>
{
public string Id { get; set; }
public string UserId { get; set; }
public bool IncludeSessions { get; set; }
}
public class GetEventsQueryHandler : IQueryHandler<GetEventsQuery, IEnumerable<Event>>
{
private IMapper _mapper { get; set; }
protected ProjectDataContext _dataContext;
public GetEventsQueryHandler(IMapper mapper, ProjectDataContext dataContext)
{
_mapper = mapper;
_dataContext = dataContext;
}
public async Task<IEnumerable<Event>> Execute(GetEventsQuery query)
{
using (_dataContext)
{
var queryable = _dataContext.Events.AsQueryable();
if (query.IncludeSessions)
{
queryable = queryable
.Include(e => e.SessionGroups)
.ThenInclude(sg => sg.Sessions)
.ThenInclude(s => s.SessionsParticipants);
}
if (!string.IsNullOrEmpty(query.Id))
{
queryable = queryable.Where(e => e.Id == query.Id);
}
var userId = query.User.GetIdentifier();
var events = await queryable.ProjectTo<Event>(new { userId }).ToListAsync();
return events.AsEnumerable();
}
}
}
}
using ...;
namespace Company.Project.Service.Controllers
{
public class AboutController : Controller
{
// GET: About
public ActionResult Index()
{
var model = new AboutModel()
{
...
SessionAttendees = SessionAttendeesService.GetSessionAttendees(),
};
return View(model);
}
}
}
using ...;
namespace Company.Project.Service.Data
{
public static class SessionAttendeesService
{
private static readonly string _storageConnectionString = ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString;
public static IEnumerable<Models.SessionGroup> GetSessionAttendees()
{
// TODO: Don't manually instantiate these dependencies.
var storageAccount = CloudStorageAccount.Parse(_storageConnectionString);
var sessionsTable = storageAccount.CreateCloudTableClient().GetTableReference(AzureTable.Sessions);
var sessionAttendeesTable = storageAccount.CreateCloudTableClient().GetTableReference(AzureTable.SessionAttendees);
var attendeesTable = storageAccount.CreateCloudTableClient().GetTableReference(AzureTable.Attendees);
var groupedAttendees = sessionAttendeesTable
.GetAll<Daos.SessionAttendee>()
.GroupBy(sa => sa.SessionId)
.ToList();
var sessions = sessionsTable
.GetAll<Daos.Session>()
.Where(session => session.CanSubscribe)
.AsQueryable()
.ProjectTo<Models.SessionAttendees>()
.ToList();
foreach (var session in sessions)
{
var attendees = groupedAttendees.FirstOrDefault(a => a.Key == session.SessionId)?.DistinctBy(a => a.AttendeeId);
if (attendees != null)
{
var list = new List<Daos.Attendee>();
foreach (var attendee in attendees)
{
var operation = TableOperation.Retrieve<Daos.Attendee>(AzureTable.PartitionKey, attendee.AttendeeId);
var result = attendeesTable.Execute(operation).Result as Daos.Attendee;
if (result != null)
{
list.Add(result);
}
}
session.Attendees.AddRange(list.OrderBy(a => a.Company).ThenBy(a => a.LastName));
}
}
var grouped = sessions
.GroupBy(s => s.TimeSlot)
.Select(group => new { TimeSlot = @group.Key, Items = @group.OrderBy(s => s.Title) })
.OrderBy(group => @group.TimeSlot)
.ToList();
return
grouped.Select(
group =>
new Models.SessionGroup()
{
TimeSlot = @group.Items.First().TimeSlot,
Sessions = @group.Items.ToList()
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment