×
Back to book

C#Bot File Structure

The file structure which is used in C#Bot applications

This article provides a summary of the client-side, server-side, and test target architecture, and briefly explains the organization, importance and usage of the key concepts for each framework.

Language + Framework

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

Server-Side Directory Structure

src
├───Controllers                 API controllers to connect to the client-side
│   └───Entities
├───Exceptions                  Common exceptions that are used
├───Graphql                     All internal GraphQL functions
│   ├───Fields
│   ├───Helpers
│   └───Types
├───Helpers                     Helper classes
├───Migrations                  Database migration scripts
├───Models                      Entities as 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

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.

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 entities attributes, which are defined in the entity model. In addition, there is also a property called Acls which implements security rules which are defined by the security model. 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.

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.

Security

The security folder contains the rules defined in the security model and helper classes associated with these security 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 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 model
│   └───Security     The rules that are defined in the security model
│       └───Acl
├───scss
│   ├───abstracts    Abstract styles (eg. colour variables)
│   ├───components   Styles for individual components
│   ├───elements     Styles for individual elements
│   └───pages        Styles for specific pages in the application
├───Services         Any services that are required in the application
├───Util             A collection of utility functions
├───Validators       Client-Side validators for validating models against
└───Views
    ├───Components   All the components that are used by the client-side
    ├───Pages        Pages that are placed on the UI model
    │   └───Admin    Admin pages for the backend views
    └───Tiles        Tiles that are placed on the UI model

Views

When writing a custom feature inside of a ReactBot 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 ReactBot, 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.

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 entity 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.

Test Target Directory Structure

testtarget
├───Selenium                        Includes the entirety of the selenium testing target
│   ├───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
│   ├───Tests
│   │   ├───BotWritten              Includes any bot written tests
│   │   │   ├───Admin
│   │   │   ├───BulkOptions
│   │   │   ├───Checkbox
│   │   │   ├───Crud
│   │   │   │   ├───CreateTests
│   │   │   │   └───DeleteTests
│   │   │   ├───Login
│   │   │   ├───Navigation
│   │   │   ├───Pagination
│   │   │   ├───Search
│   │   │   ├───UnauthorizedLoginRedirect
│   │   │   └───Validator
│   └───Utils                       Selenium Utils
└───Serverside                      Includes the server-side API and unit tests
    ├───EntityObjects
    │   ├───BaseChoice              Includes all base choice invalid/valid helper methods
    │   └───Models                  Includes entities for the test target
    ├───Properties
    ├───Settings
    ├───Setup                       Startup methods for server-side tests
    ├───Tests
    │   └───botwritten              Bot written server-side tests
    └───Utils                       Helper methods for server-side tests

Selenium Test Target

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

Server-Side Test Target

The server-side test target includes all of the API and unit tests coupled with 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.

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/netcoreapp2.2/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).