### Run DDD Fundamentals Sample with Docker Compose
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/README.md
Commands to build and run the DDD Fundamentals sample application using Docker Compose. The build step can be run in parallel for faster execution. The up command starts all services, and troubleshooting tips for common errors like RabbitMQ or SQL Server connection issues are provided.
```powershell
docker-compose build --parallel
docker-compose up
```
--------------------------------
### Run RabbitMQ with Management Interface
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/README.md
This command starts a RabbitMQ container with the management interface enabled. It maps the management port (15672) and the AMQP port (5672) to the host machine. The container is named 'ddd-sample-rabbit' and will be automatically removed when it stops.
```powershell
docker run --rm -it --hostname ddd-sample-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
```
--------------------------------
### Initialize Kendo Scheduler with Data
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/FrontDesk/src/FrontDesk.Blazor/wwwroot/index.html
Initializes the Kendo UI Scheduler with provided start date, time, end date, appointments, resources, and groups. It sets up the data source, event templates, and various configuration options for the scheduler.
```JavaScript
$(function () { $("#kendoVersion").text(kendo.version); }); // Demo is using Kendo Scheduler until Blazor version supports Grouped Schedule View
var currentAppointment = {};
var instanceKendoCall = {};
const colorFieldName = 'key';
function lowerCasefirst(string) {
if (!string || string.length <= 0) {
return '';
}
return string.charAt(0).toLowerCase() + string.slice(1);
}
function createDataSourceResource(name, data, valueField, textField) {
var result = {};
if (data[lowerCasefirst(valueField)]) {
result['value'] = data[lowerCasefirst(valueField)];
}
if (data[lowerCasefirst(textField)]) {
result['text'] = data[lowerCasefirst(textField)];
}
if (name.toLowerCase() == 'rooms') {
result[colorFieldName] = createColor(data, valueField);
}
return result;
}
function createColorForAppointment(data) {
if (data['roomId'] == 1) {
return "#97c741";
} else if (data['roomId'] == 2) {
return "#63aeb8";
} else if (data['roomId'] == 3) {
return "#c163a2";
} else if (data['roomId'] == 4) {
return "#ed652e";
} else if (data['roomId'] == 5) {
return "#6380ba";
}
}
function getPictureBase64(data, callback) {
var url = "https://localhost:5101/api/files/";
url = url + data['patientName'] + '.jpg';
var result = '';
$.getJSON(url, '', callback);
}
function createColor(data, valueField) {
if (data[lowerCasefirst(valueField)] == 1) {
return "#97c741";
} else if (data[lowerCasefirst(valueField)] == 2) {
return "#63aeb8";
} else if (data[lowerCasefirst(valueField)] == 3) {
return "#c163a2";
} else if (data[lowerCasefirst(valueField)] == 4) {
return "#ed652e";
} else if (data[lowerCasefirst(valueField)] == 5) {
return "#6380ba";
}
return '';
}
function createResource(schedulerResource) {
var result = {};
var dataSource = [];
if (schedulerResource['name'].toLowerCase() == 'rooms') {
result['dataColorField'] = colorFieldName;
}
for (var i = 0; i < schedulerResource['data'].length; i++) {
dataSource.push(createDataSourceResource(schedulerResource['name'], schedulerResource['data'][i], schedulerResource['valueField'], schedulerResource['textField']));
}
result['dataSource'] = dataSource;
result['name'] = schedulerResource['name'].toLowerCase();
result['field'] = lowerCasefirst(schedulerResource['field']);
result['title'] = schedulerResource['title'];
return result;
}
function addListenerToFireEdit(instance) {
instanceKendoCall = instance;
}
function createGroups(schedulerGroups) {
var groups = [];
if (schedulerGroups) {
for (var i = 0; i < schedulerGroups.length; i++) {
groups.push(schedulerGroups[i].toLowerCase());
}
}
return groups;
}
function createResources(schedulerResources) {
var resources = [];
if (schedulerResources) {
for (var i = 0; i < schedulerResources.length; i++) {
resources.push(createResource(schedulerResources[i]));
}
}
return resources;
}
function scheduler(startDate, startTime, endDate, appointments, schedulerResources, schedulerGroups, height) {
var resources = createResources(schedulerResources)
var groups = createGroups(schedulerGroups);
console.log('resources', resources);
hardRefresh();
var viewModel = new kendo.observable({
schedulerData: new kendo.data.SchedulerDataSource({
data: appointments,
schema: {
model: {
id: "appointmentId",
fields: {
appointmentId: { from: "appointmentId", type: "string" },
title: { from: "title", defaultValue: "No title", validation: { required: true } },
start: { type: "date", from: "start" },
end: { type: "date", from: "end" },
description: { from: "description" },
roomId: { from: "roomId", nullable: true, type: "number" },
isAllDay: { type: "boolean", from: "isAllDay" },
ScheduleId: { type: "string", from: "ScheduleId" },
isConflict: { type: "boolean", from: "isPotentiallyConflicting" },
isConfirmed: { from: "isConfirmed" }
}
}
}
}),
});
var onDataBound = function (e) {
$("[data-is-conflicted=true]")
.parent()
.addClass("conflicted-event");
$("[data-is-confirmed=true]")
.parent()
.addClass("confirmed-event");
};
$("#scheduler").kendoScheduler({
date: startDate,
startTime: startTime,
endTime: endDate,
height: height,
resize: function (e) {
e.preventDefault();
},
resizeEnd: function (e) {
e.preventDefault();
},
moveEnd: function (e) {
//if (!checkAvailability(e.start, e.end, e.event, e.resources)) {
// e.preventDefault();
//} else {
// onMoveEnd(e);
//}
},
views: [
{ type: "day", selected: true, allDaySlot: false, minorTickCount: 4 },
{ type: "workWeek", allDaySlot: false, minorTickCount: 4 },
"agenda"
],
workWeekEnd: 6,
timezone: "America/Detroit",
//timezone: "Etc/UTC",
dataSource: viewModel.schedulerData,
dataBound: onDataBound,
eventTemplate: kendo.template($("#event-template").html()),
footer: false,
group: {
resources: groups
},
resources: resources,
edit: onEdit,
remove: onDelete,
});
}
function occurrencesInRangeByResource(start, end, resourceFieldName, event, resources) {
var scheduler = $("#scheduler").getKendoSche
```
--------------------------------
### Run Papercut Test Mail Server
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/README.md
This command launches a Papercut container, which acts as a local test mail server. It exposes the SMTP port (25) and the Papercut UI port (37408) to the host. The container is named 'papercut' and uses the 'jijiechen/papercut:latest' image.
```powershell
docker run --name=papercut -p 25:25 -p 37408:37408 jijiechen/papercut:latest
```
--------------------------------
### Blazored.LocalStorage - Blazor Local Storage Access
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/README.md
A Blazor utility that enables easy access to the browser's local storage from Blazor WebAssembly applications, facilitating client-side data persistence.
```csharp
///
/// Blazor utility for accessing browser local storage in Blazor WebAssembly apps.
///
public interface ILocalStorageService
{
Task SetItemAsync(string key, T data);
Task GetItemAsync(string key);
Task RemoveItemAsync(string key);
}
```
--------------------------------
### Ardalis.ApiEndpoints - API Endpoint Simplification
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/README.md
A library that simplifies API endpoint creation by promoting a Request-EndPoint-Response (REPR) pattern, replacing traditional MVC structures for more focused and manageable endpoints.
```csharp
///
/// A simple base class that lets you keep your API endpoints small and focused on one endpoint at a time. MVC is replaced with Request-EndPoint-Response (REPR).
///
public abstract class ApiEndpoint
{
public abstract Task> HandleAsync(TRequest request);
}
```
--------------------------------
### Ardalis.Specification.EntityFrameworkCore - EF Core Repository
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/README.md
Extends Ardalis.Specification with Entity Framework Core-specific functionalities. It includes a default generic repository implementation that seamlessly integrates with the Specification pattern.
```csharp
///
/// Adds EF Core-specific functionality, including a default implementation of a generic EF repository that supports Specifications.
///
public class EfRepository : IRepository
{
private readonly DbContext _context;
public EfRepository(DbContext context)
{
_context = context;
}
public async Task GetByIdAsync(int id)
{
return await _context.Set().FindAsync(id);
}
// ... other repository methods supporting specifications
}
```
--------------------------------
### MassTransit.RabbitMQ - RabbitMQ Communication
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/README.md
A client library for communicating with RabbitMQ message broker, enabling the implementation of robust messaging patterns in distributed systems.
```csharp
///
/// Client for communicating with RabbitMQ.
///
public interface IRabbitMqBus
{
Task Publish(T message) where T : class;
Task Send(T message) where T : class;
}
```
--------------------------------
### Using Open Iconic SVG Sprite
Source: https://github.com/ardalis/pluralsight-ddd-fundamentals/blob/main/FrontDesk/src/FrontDesk.Blazor/wwwroot/css/open-iconic/README.md
This demonstrates how to use Open Iconic's SVG sprite for displaying icons efficiently. It utilizes the `