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
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).
Was this article helpful?