Custom Development

HomeServicesCustom Development

Custom Development

A group of people sitting at a table in front of a blackboard

Build cross-platform APIs and other services that run on desktops, laptops, and servers. We like to use C++, C#, and Node.js to build custom software.

macOS

Linux

Windows

C++

C#

Node.js

APIs

We typically write APIs so that applications can communicate with one another. An API surfaces business functions such as the addition, search, update, and deletion of data. Using Node.js, C#, and C++ helps us create increasingly performant and scalable APIs complete with authentication, authorization, documentation, logging, and rate limiting.

 

Other Services

Some services run behind the scenes to automate frequent or mundane tasks. Relieve team members from repetitive and time-consuming chores so they can focus on moving the business forward. Using C# and C++ helps us create increasingly performant and scalable services complete with installers (when applicable), logging, and uninstallers (when applicable).

Example of a C# Data Layer

namespace Model {
  public enum TableName {
    Account
  }
}

namespace Model.Account {
  public class Account : Base {
    public Account()
      : base(TableName.Account) {
    }

    public string Name { get; set; }
  }
}

This NoSQL data layer interfaces with tables in an Azure storage account.

  • Add a member to the Model.TableName enum (e.g., Account)
  • Add a class that derives from Base to the Model namespace (e.g., Account)
  • Assuming _data is an instance of Data.AzureTableData, and model is an instance of Model.Account, invoke the data operations...
    await _data.Add(model);
    await _data.Delete(model);
    ...

View on GitHub

Example of a C# Business Layer

namespace Business {
  public class Account : Base, IAccount {
    public Account(IConfiguration configuration, IData data)
      : base(configuration, data) {
    }

    public override async Task<T> Add<T>(T model) {
      Model.Account.Account account = model as Model.Account.Account;

      if (string.IsNullOrWhiteSpace(account.Name)) {
        model.Message = "Name is required.";
      }
      else {
        model = await base.Add(model);
      }

      return model;
    }
  }
}

This business layer interfaces with the data layer described above.

  • If business logic is needed, such as validating that the Account Name is not empty, override the appropriate methods defined in Base
  • Otherwise, let Base handle the data operation
  • Assuming _business is an instance of Business.Account, and model is an instance of Model.Account, invoke the business operations...
    await _business.Add(model);
    await _business.Delete(model);
    ...

View on GitHub

Example of a C# API Layer

namespace API.Controllers {
  [Route("account")]
  public class AccountController : Controller {
    private readonly ILogger<AccountController> _logger;
    private readonly Business.IAccount _accountBusiness;

    public AccountController(ILogger<AccountController> logger, Business.IAccount accountBusiness) {
      _logger = logger;
      _accountBusiness = accountBusiness;
    }

    [HttpPost]
    public async Task<IActionResult> Add([FromBody] ViewModel.Request.AddAccount viewModel) {
      ...
      return Json(new { });
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> Delete(string id) {
      ...
      return Json(new { });
    }
  }
}

This API layer interfaces with the business layer described above.

  • Add a POST route to add an account
  • Add a DELETE route to delete an account
  • Invoke the business operations...
    Add:
    Model.Account.Account model = new Model.Account.Account() {
      RowKey = Guid.NewGuid().ToString(),
      Name = viewModel.Name
    };

    model = await _accountBusiness.Add(model);
    Delete:
    Model.Account.Account model = await _accountBusiness.Get<Model.Account.Account>(id);

    bool success = await _accountBusiness.Delete(model);

View on GitHub

Latest Projects

October 2024
Created ASP.NET Core REST APIs with a business layer and a NoSQL data layer that interfaces with tables in an Azure Storage account, SendGrid for sending emails, and Stripe for collecting payments.

August 2024
Added ASP.NET Core REST APIs to an existing Sitefinity DX project to leverage Okta's IAM, provide self-service features such as changing username / email address / password, and provide admin features such as impersonation.

February 2024
Created ASP.NET Core Web APIs with a business layer and an Azure SQL data layer that interfaces with Canvas and SafeSport for learning, Ping for IAM, Sisense for reporting, and Stripe for collecting payments.

Let's Talk

Contact us today to discuss the custom software you need to build.