Last active
September 14, 2017 16:30
-
-
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 …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Gist name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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