Developer Docs

C#Bot File Structure

This article provides a summary of the client-side, server-side, and testing architecture used in C#Bot applications, along with explanations about the organisation, importance and usage of the key concepts for each framework.

Language + framework

C#Bot uses an ASP.NET Core server-side framework. ASP .NET Core is a cross platform, open-source framework for building web applications. For developing the client-side user interfaces C#Bot uses React, a javascript library, while the testing target is written in C# and uses both xUnit and Specflow 3.

Server-side directory structure

src
├───Assets                      Assets used by the server-side (eg. Email Templates)
│   └───Emails
├───AttributeValidators         Validators used to verify that incoming data is correctly formatted
├───Configuration               Classes which contain configuration options used throughout the server-side
├───Controllers                 API controllers to connect to the client-side
│   └───Entities
├───Enums                       Enum objects which were added to the model
├───Exceptions                  Common exceptions that are used
├───Graphql                     All internal GraphQL functions
│   ├───Fields
│   ├───Helpers
│   └───Types
├───Helpers                     Helper classes
├───Migrations                  Database migration scripts
├───Models                      Entities which were defined in the entity model
├───Properties                  Server launch properties
├───Security                    Rules defined in the security model
│   └───Acl
├───Services                    Services to be used in DI
│   ├───CertificateProvider     Providers for fetching pfx certs
│   └───Scheduling              Services for scheduled tasks
│       └───Tasks
└───Utility                     Utility classes, often helpers for the request pipeline

Attribute validators

Validators can be added to attributes when building your model in the Entity diagram. These validators can be used to ensure that an attribute conforms to the specified format (i.e. an integer may have a range it must be within). Some validators (such as Required) are available in C# and do not require implementation, however some of them required code to implement. This bot-written code is located in the AttributeValidators directory.

Controllers

Controllers are the HTTP/HTTPS endpoints for the application. They reside in the Controllers directory.

A controller will typically follow this structure:

/// <summary>
/// Gets the logged in user
/// </summary>
/// <returns>The current logged in user</returns>
[HttpGet]
[HttpPost]
[Produces("application/json")]
[Route("me")]
[Authorize]
public async Task<UserResult> Get()
{
    var user = await _userService.GetUser(User);
    return user;
}

The [HttpGet] and [HttpPost] attributes specify that this endpoint will take requests from both GET and POST HTTP requests.

The [Produces("application/json")] attribute specifies that any data returned by this endpoint will be serialized into JSON before returning to the client.

The [Route("me")] attribute specifies that the endpoint is located at /me in the URL. Please note that this is relative to the URL of the controller, so if the controller was specified to exist at /account, the endpoint would be at /account/me.

The [Authorize] attribute requires the endpoint to have an authorized user, with authorization being enforced by the ‘default authorization policy’ found in Startup.cs. By default, users are authenticated against either a Bearer or Cookie authentication scheme.

GraphQL

The Graphql folder contains the GraphQL queries, mutations and any helpers required to execute the various GraphQL functions. For each entity defined in the entity model there are functions created to provide the full CRUD functionality.

Server-side models

Server-side models are defined as C# classes inside of the Models directory. Each model is a plain C# class with all of the entity’s attributes, which are defined in the Entity diagram. Additionally, there is a property called Acls which implements security rules as defined in the Security diagram. These classes are coupled with both a configuration and a type file. The configuration file configures the entity in the database, whereas the type file defines type mappings for GraphQL.

Security

The security folder contains the rules defined in the Security diagram, along with the helper classes associated with those rules. It is important to note that the ACL folder contains classes which can be altered to contain custom security logic.

Services

This folder contains the services added to the server-side via dependency injection. These services make up the bulk of the application logic in a C#Bot project.

Client-side directory structure

src
├───Assets                  Static assets that are needed in React (eg. images)
├───Models
│   ├───Entities            The models that are defined in the entity diagram
│   └───Security            The rules that are defined in the security diagram
│       └───Acl
├───scss
│   ├───admin               Styles used in the admin section of the site
│   ├───frontend            Styles used in the frontend of the site (admin contains the same sub-directories)
│   │   ├───abstracts       Abstract styles (eg. colour variables)
│   │   ├───animations      Styles used for creating animations
│   │   ├───components      Styles for individual components
│   │   ├───elements        Styles for individual elements
│   │   └───pages           Styles for specific pages in the application
│   └───shared              Styles used across both the admin section and front-end
├───Services                Any services that are required in the application
├───Util                    A collection of utility functions
├───Validators              Client-side validators for validating models
└───Views
├───Components              All the components that are used by the client-side
    ├───Pages               Pages that are placed on the UI diagram
    │   └───Admin           Admin pages for the back-end
    └───Tiles               Tiles that are placed on the UI diagram

Models

The client-side models are the javascript versions of the entities which were defined in the Entity diagram. These contain observable attributes identical to those in the diagram. There are a series of helper methods on these models for fetching and persisting data to and from the server-side via the GraphQL API.

SCSS

The scss directory contains all of the styling code used in the application. Many of the files in this directory have their contents wrapped in protected regions, so you can make changes to the bot-written styles.

Validators

Similarly to the server-side, there are multiple validators which are not available by default in React, so bot-written implementations for these validators can be found in this directory. These validators are applied to attributes so that entities can be validated on the client-side before attempting to access the server.

Views

When writing a custom feature inside of a C#Bot view protected region, the first place to look at will be the src/Views/Pages directory. Any pages placed on the UI model will be output here, with routing configured to render the page. In C#Bot, all React components are class-based components by convention. This allows cleaner integration with MobX using the decorator syntax. However, there is no restriction on this and components can be function-based components if desired.

It is important when writing pages, or any other custom UI elements, that components are declared as MobX Observers. If this is not done, then there can be issues with elements not re-rendering on state changes.

Testing target directory structure

testtarget
├───API                             Includes the tests for the applications API Endpoints
│   ├───Attributes
│   │   └───Validators              Validators used to test validity of attributes
│   ├───Classes
│   ├───EntityObjects               Entities used in the tests as defined in the diagram
│   │   ├───Enums
│   │   └───Models
│   ├───Exceptions                  Common exceptions which are used in the tests
│   ├───Extensions
│   ├───Factories                   Factories for generating instances of different entity types
│   ├───Settings                    Options which are used throughout the API Testing project
│   ├───Setup                       Logic used to initialise and run the tests
│   ├───Tests
│   │   └───BotWritten              The API tests written by the bot
│   ├───TheoryData
│   │   └───BotWritten              Data generators used to create specific data sets for a test
│   ├───Utils                       Utility methods used throughout the API testing project
├───Selenium                        Includes the entirety of the Selenium testing target
│   ├───Enums                       Enumerations used in the Selenium tests (Not based on the model)
│   ├───Factories                   Selenium-based factories
│   ├───PageObjects                 Includes all page object models
│   │   ├───CRUDPageObject
│   │   │   └───PageDetails
│   │   ├───LoginPageObject
│   │   └───LogoutPageObject
│   ├───Setup                       Startup configuration for Selenium tests
│   ├───Steps
│   │   └───BotWritten              Includes any bot-written step definitions
│   ├───TestResults                 Contains images created during the previous test run
│   ├───Tests
│   │   ├───BotWritten              Includes any bot-written tests
│   └───Utils                       Selenium utils
├───Serverside                      Includes the server-side API and unit tests
│   ├───Helpers
|   |   ├───EntityFactory           Generates entities to be used in the tests
|   |   ├───FileProviders           File provider which can be used for testing purposes
|   |   └───Services                Implementations of services which can be used in tests
|   └───Tests
|       ├───Integration
|       |   └───BotWritten          Bot-written server-side integration tests
|       └───Unit                    
|           └───BotWritten          Bot-written server-side unit tests
|               └───Mocks
|                   └───BotWritten  Bot-written Mocks used to imitate other classes when required
└───TestDataLib                     Contains methods used to generate data for factories and other methods
    └───Resources                   Contains words and characters used in the data generation

API test target

The API test target contains all tests for the API endpoints in the C#Bot application, as well as additional classes and helper methods used in the tests.

Selenium test target

The Selenium test target is composed entirely of Selenium tests, helper methods and page object models of the application’s client-side.

Server-side test target

The server-side test target includes all of the integration and unit tests coupled within the C#Bot application. Any resources which are shared between the testing targets are included in this project. This includes BaseChoice, entity models, test configuration and several helper methods for creating and manipulating data.

Test data library

The test data library contains basic building blocks which are used in data factories to generate instances of different entities used in the tests.

Setup and running

C# Local Environment Setup

Build

In order to produce a production build of the application, first you must open a terminal in the serverside/src directory of the application and run dotnet publish -c Release.
This will create a release build of the server and client applications, and bundle them together. The output of the build is stored in serverside/src/bin/release/net5.0/publish, which can be then deployed on any server.

It is important to note that even though there is a file called Properties/launchSettings.json it will not configure the release build of the application, it is only used for configuration of IDE’s. When deploying a production build, any server settings must be configured using the specific tools provided by the web server of choice (eg. web.config for IIS or nginx.config NGINX).

On this page