Skip to content
This repository was archived by the owner on Jul 10, 2024. It is now read-only.

Commit 6a41dee

Browse files
committed
Changes to snapshot and session2
1 parent 77f086f commit 6a41dee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+536
-11238
lines changed

docs/2. Build out BackEnd and Refactor.md

Lines changed: 98 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,25 @@ In this session, we'll add the rest of our models and controllers that expose th
1616
### Adding the ConferenceDTO project via the Command Line
1717
1. Open a command prompt and navigate to the root `ConferencePlanner` directory.
1818
1. Run the following command:
19-
```
19+
```console
2020
dotnet new classlib -o ConferenceDTO -f netstandard2.0
2121
```
2222
1. Next we'll need to add a reference to the ConferenceDTO project from the BackEnd project. From the command line, navigate to the BackEnd project directory and execute the following command:
23-
```
24-
dotnet add reference ../ConferenceDTO/ConferenceDTO.csproj
23+
```console
24+
dotnet add reference ../ConferenceDTO
2525
```
2626
1. Add the ConferenceDTO project to the solution:
27-
```
28-
dotnet sln add ConferenceDTO\ConferenceDTO.csproj
27+
```console
28+
dotnet sln add ConferenceDTO
2929
```
3030

3131
## Refactoring the Speaker model into the ConferenceDTO project
3232
1. Copy the `Speaker.cs` class from the *BackEnd* application into the root of the new ConferenceDTO project, and change the namespace to `ConferenceDTO`.
33-
1. The data annotations references can't be resolved to a missing NuGet package. Add a reference to `System.ComponentModel.Annotations` version `4.5.0`. When the package restore completes, you should see that your data annotations are now resolved.
33+
1. The data annotations references should be broken at this point, to resovle it, we need to add a nuget the missing NuGet package into the `ConferenceDTO` project.
34+
1. Add a reference to the NuGet package `System.ComponentModel.Annotations` version `4.5.0`.
35+
> This can be done from the command line using `dotnet add package System.ComponentModel.Annotations --version 4.5.0`
36+
37+
1. When the package restore completes, you should see that your data annotations are now resolved.
3438
1. Go back to the *BackEnd* application and modify the code in `Speaker.cs` as shown:
3539
```csharp
3640
public class Speaker : ConferenceDTO.Speaker
@@ -123,10 +127,11 @@ We've got several more models to add, and unfortunately it's a little mechanical
123127
```
124128

125129
## Creating Derived Models in the BackEnd project
126-
We're not going to create our EF models directly from the *ConferenceDTO* classes. Instead, we'll create some composite classes such as *SessionSpeaker*, since these will map more closely to what our application will be working with.
130+
We're not going to create our EF models directly from the `ConferenceDTO` classes. Instead, we'll create some composite classes such as `SessionSpeaker`, since these will map more closely to what our application will be working with.
127131

128132
We're also going to take this opportunity to rename the `Models` directory in the *BackEnd* project to `Data` since it no longer just contains models.
129133
1. Right-click the `Models` directory and select `Rename`, changing the name to `Data`.
134+
> Note: If you are using Visual Studio, you can use refactoring to rename the namespace.
130135
1. Add a `SessionSpeaker.cs` class to the `Data` directory with the following code:
131136
```csharp
132137
using System;
@@ -148,9 +153,10 @@ We're also going to take this opportunity to rename the `Models` directory in th
148153
}
149154
}
150155
```
151-
1. Add an `SessionAttendee.cs` class with the following code:
156+
1. Add an `SessionAttendee.cs` class with the following code:
157+
152158
```csharp
153-
using System;
159+
using System;
154160
using System.Collections.Generic;
155161
using System.Linq;
156162
using System.Threading.Tasks;
@@ -200,31 +206,30 @@ We're also going to take this opportunity to rename the `Models` directory in th
200206
}
201207
}
202208
```
203-
1. Modify the `Speaker.cs` class we wrote previously to make the following two changes: update to the namespace to match our directory rename, and add a referece to the `SessionSpeaker` composite class:
209+
1. Add a `Track.cs` class with the following code:
204210
```csharp
205211
using System;
206212
using System.Collections.Generic;
207-
213+
using System.ComponentModel.DataAnnotations;
214+
208215
namespace BackEnd.Data
209216
{
210-
public class Speaker : ConferenceDTO.Speaker
217+
public class Track : ConferenceDTO.Track
211218
{
212-
public virtual ICollection<SessionSpeaker> SessionSpeakers { get; set; } = new List<SessionSpeaker>();
219+
public virtual ICollection<Session> Sessions { get; set; }
213220
}
214221
}
215222
```
216-
217-
1. Add a `Track.cs` class with the following code:
223+
1. Modify the `Speaker.cs` class we wrote previously to make the following two changes: update to the namespace to match our directory rename, and add a referece to the `SessionSpeaker` composite class:
218224
```csharp
219225
using System;
220226
using System.Collections.Generic;
221-
using System.ComponentModel.DataAnnotations;
222-
227+
223228
namespace BackEnd.Data
224229
{
225-
public class Track : ConferenceDTO.Track
230+
public class Speaker : ConferenceDTO.Speaker
226231
{
227-
public virtual ICollection<Session> Sessions { get; set; }
232+
public virtual ICollection<SessionSpeaker> SessionSpeakers { get; set; } = new List<SessionSpeaker>();
228233
}
229234
}
230235
```
@@ -277,7 +282,7 @@ Okay, now we need to update our `ApplicationDbContext` so Entity Framework knows
277282
## Add a new database migration
278283

279284
### Visual Studio: Package Manager Console
280-
1. Run the following commands in the Package Manager Console
285+
1. Run the following commands in the Package Manager Console (specify the `BackEnd` project)
281286
```console
282287
Add-Migration Refactor
283288
Update-Database
@@ -291,100 +296,99 @@ Okay, now we need to update our `ApplicationDbContext` so Entity Framework knows
291296
```
292297
1. Now take a deep breath and run the application and navigate to `/swagger`. You should see the Swagger UI.
293298

294-
>Save point for above code changes is [here](/save-points/2a-Refactor-to-ConferenceDTO/ConferencePlanner)
295-
296299
## Updating the Speakers API controller
297300

298301
1. Modify the query for the `GetSpeakers()` method as shown below:
299302
```csharp
300-
var speakers = await _context.Speakers.AsNoTracking()
301-
.Include(s => s.SessionSpeakers)
302-
.ThenInclude(ss => ss.Session)
303-
.ToListAsync();
304-
return speakers;
303+
var speakers = await _context.Speakers.AsNoTracking()
304+
.Include(s => s.SessionSpeakers)
305+
.ThenInclude(ss => ss.Session)
306+
.ToListAsync();
307+
return speakers;
305308
```
306-
1. While the above will work, this is directly returning our model class. A better practice is to return an output model class. Create a `SpeakerResponse.cs` class in the *ConferenceDTO* project with the following code:
309+
1. While the above will work, this is directly returning our model class. A better practice is to return an output model class. Create a `SpeakerResponse.cs` class in the `ConferenceDTO` project with the following code:
307310
```csharp
308-
using System;
309-
using System.Collections.Generic;
310-
using System.Text;
311+
using System;
312+
using System.Collections.Generic;
313+
using System.Text;
311314

312-
namespace ConferenceDTO
313-
{
314-
public class SpeakerResponse : Speaker
315-
{
316-
public ICollection<Session> Sessions { get; set; } = new List<Session>();
317-
}
318-
}
315+
namespace ConferenceDTO
316+
{
317+
public class SpeakerResponse : Speaker
318+
{
319+
public ICollection<Session> Sessions { get; set; } = new List<Session>();
320+
}
321+
}
319322
```
320323
1. Now we'll add a utility method to map between these classes. In the *BackEnd* project, create an `Infrastructure` directory. Add a class named `EntityExtensions.cs` with the following mapping code:
321324
```csharp
322-
using BackEnd.Data;
323-
using System;
324-
using System.Collections.Generic;
325-
using System.Linq;
326-
using System.Threading.Tasks;
325+
using BackEnd.Data;
326+
using System;
327+
using System.Collections.Generic;
328+
using System.Linq;
329+
using System.Threading.Tasks;
327330

328-
namespace BackEnd.Data
329-
{
330-
public static class EntityExtensions
331-
{
332-
public static ConferenceDTO.SpeakerResponse MapSpeakerResponse(this Speaker speaker) =>
333-
new ConferenceDTO.SpeakerResponse
334-
{
335-
Id = speaker.Id,
336-
Name = speaker.Name,
337-
Bio = speaker.Bio,
338-
WebSite = speaker.WebSite,
339-
Sessions = speaker.SessionSpeakers?
340-
.Select(ss =>
341-
new ConferenceDTO.Session
342-
{
343-
Id = ss.SessionId,
344-
Title = ss.Session.Title
345-
})
346-
.ToList()
347-
};
348-
}
349-
}
331+
namespace BackEnd.Data
332+
{
333+
public static class EntityExtensions
334+
{
335+
public static ConferenceDTO.SpeakerResponse MapSpeakerResponse(this Speaker speaker) =>
336+
new ConferenceDTO.SpeakerResponse
337+
{
338+
Id = speaker.Id,
339+
Name = speaker.Name,
340+
Bio = speaker.Bio,
341+
WebSite = speaker.WebSite,
342+
Sessions = speaker.SessionSpeakers?
343+
.Select(ss =>
344+
new ConferenceDTO.Session
345+
{
346+
Id = ss.SessionId,
347+
Title = ss.Session.Title
348+
})
349+
.ToList()
350+
};
351+
}
352+
}
350353
```
351354
1. Now we can update the `GetSpeakers()` method of the *SpeakersController* so that it returns our response model. Update the last few lines so that the method reads as follows:
352355
```csharp
353-
[HttpGet]
354-
public async Task<ActionResult<List<ConferenceDTO.SpeakerResponse>>> GetSpeakers()
355-
{
356-
var speakers = await _context.Speakers.AsNoTracking()
357-
.Include(s => s.SessionSpeakers)
358-
.ThenInclude(ss => ss.Session)
359-
.Select(s => s.MapSpeakerResponse())
360-
.ToListAsync();
361-
return speakers;
362-
}
356+
[HttpGet]
357+
public async Task<ActionResult<List<ConferenceDTO.SpeakerResponse>>> GetSpeakers()
358+
{
359+
var speakers = await _context.Speakers.AsNoTracking()
360+
.Include(s => s.SessionSpeakers)
361+
.ThenInclude(ss => ss.Session)
362+
.Select(s => s.MapSpeakerResponse())
363+
.ToListAsync();
364+
return speakers;
365+
}
363366
```
364367
1. Update the `GetSpeaker()` method to use our mapped response models as follows:
365368
```csharp
366-
[HttpGet("{id}")]
367-
public async Task<ActionResult<ConferenceDTO.SpeakerResponse>> GetSpeaker(int id)
368-
{
369-
var speaker = await _context.Speakers.AsNoTracking()
370-
.Include(s => s.SessionSpeakers)
371-
.ThenInclude(ss => ss.Session)
372-
.SingleOrDefaultAsync(s => s.Id == id);
373-
if (speaker == null)
374-
{
375-
return NotFound();
376-
}
377-
return speaker.MapSpeakerResponse();
378-
}
369+
[HttpGet("{id}")]
370+
public async Task<ActionResult<ConferenceDTO.SpeakerResponse>> GetSpeaker(int id)
371+
{
372+
var speaker = await _context.Speakers.AsNoTracking()
373+
.Include(s => s.SessionSpeakers)
374+
.ThenInclude(ss => ss.Session)
375+
.SingleOrDefaultAsync(s => s.Id == id);
376+
if (speaker == null)
377+
{
378+
return NotFound();
379+
}
380+
return speaker.MapSpeakerResponse();
381+
}
379382
```
380-
1. Remove the other actions.
383+
1. Remove the other actions (`PutSpeaker`, `PostSpeaker`, `DeleteSpeaker`), on the `SpeakersController`.
384+
385+
## Adding the remaining API Controllers and DTOs
381386

382-
## Adding the remaining API Controllers
383-
1. Add the following response DTO classes from [the save point folder](/save-points/2b-BackEnd-completed/ConferencePlanner/ConferenceDTO)
387+
1. Add the following response DTO classes from [the save point folder](/save-points/2-BackEnd-completed/ConferencePlanner/ConferenceDTO)
384388
- `AttendeeResponse`
385389
- `SessionResponse`
386-
1. Update the `EntityExtensions` class with the extra mapping methods from [the save point folder](/save-points/2b-BackEnd-completed/ConferencePlanner/BackEnd/Infrastructure)
387-
1. Copy the following controllers from [the save point folder](/save-points/2b-BackEnd-completed/ConferencePlanner/BackEnd/Controllers) into the current project's `BackEnd/Controllers` directory:
390+
1. Update the `EntityExtensions` class with the extra mapping methods from [the save point folder](/save-points/2-BackEnd-completed/ConferencePlanner/BackEnd/Infrastructure)
391+
1. Copy the following controllers from [the save point folder](/save-points/2-BackEnd-completed/ConferencePlanner/BackEnd/Controllers) into the current project's `BackEnd/Controllers` directory:
388392
- `SessionsController`
389393
- `AttendeesController`
390394

@@ -466,7 +470,7 @@ Okay, now we need to update our `ApplicationDbContext` so Entity Framework knows
466470
## Adding Conference Upload support
467471
1. Copy the `DataLoader.cs` class from [here](/src/BackEnd/Data/DataLoader.cs) into the `Data` directory of the `BackEnd` project.
468472
1. Copy the `SessionizeLoader.cs` and `DevIntersectionLoader.cs` classes from [here](/src/BackEnd/Data/) into the current project's `/src/BackEnd/Data/` directory.
469-
> Note: We have data loaders from the two conference series where this workshop has been presented most; you can update this to plug in your own conference file format.
473+
> Note: We have data loaders from the two conference series where this workshop has been presented most; you can update this to plug in your own conference file format.
470474
1. To improve the UI for upload, turn on the option to display enums as strings by changing `AddSwaggerGen` in `Startup.cs` to the following:
471475
```c#
472476
services.AddSwaggerGen(options =>

save-points/2-BackEnd-completed/ConferencePlanner/BackEnd/BackEnd.csproj

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp2.2</TargetFramework>
5-
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
6-
</PropertyGroup>
7-
4+
<TargetFramework>netcoreapp3.0</TargetFramework>
5+
</PropertyGroup>
86
<ItemGroup>
9-
<PackageReference Include="Microsoft.AspNetCore.App" />
10-
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
11-
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
12-
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" />
13-
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
7+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.4" />
8+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
9+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.4">
10+
<PrivateAssets>all</PrivateAssets>
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
</PackageReference>
13+
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0-preview5-19264-04">
14+
<PrivateAssets>all</PrivateAssets>
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
16+
</PackageReference>
17+
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc2" />
1418
</ItemGroup>
15-
19+
1620
<ItemGroup>
1721
<ProjectReference Include="..\ConferenceDTO\ConferenceDTO.csproj" />
1822
</ItemGroup>

0 commit comments

Comments
 (0)