Setup

Here you will learn how to setup your .NET solution to use Gazel.

Create a solution

In this document, you will learn how to setup a solution from scratch.

Create a blank solution

Create a solution folder for your application. Name it in the <Company>.<Component> convention (see .NET Naming Conventions). Under this folder create an empty solution.

mkdir Inventiv.Todo; cd Inventiv.Todo
dotnet new sln

We well use Inventiv as a company, and Todo as a component throughout this document.

Create a service application

To create a service application, first create a new web project by typing below commands;

dotnet new web --output src/Inventiv.Todo.App.Service
dotnet sln add src/Inventiv.Todo.App.Service --solution-folder src

Now Inventiv.Todo.sln should have below structure;

Inventiv.Todo
└── src
    └── Inventiv.Todo.App.Service
        ├── Properties
        │   └── launchSettings.json
        ├── appsettings.json
        │   └── appsettings.Development.json
        └── Program.cs

Now add Gazel.Configuration package to the App.Service project from nuget.org.

dotnet add src/Inventiv.Todo.App.Service package Gazel.Configuration

To configure this project to use Gazel, modify Program.cs file in src/Inventiv.Todo.App.Service as below;

Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Inventiv.Todo.App.Service
{
    public class Program
    {
        public static void Main(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseGazelServiceProvider()
                .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
                .Build()
                .Run();
    }
}

.UseGazelServiceProvider() configures .NET to use Gazel's IoC preference which is currently Castle.Windsor.

After this create a Startup.cs file with below code;

Startup.cs
using Gazel.Logging;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Inventiv.Todo.App.Service
{
    public class Startup
    {
        private readonly IConfiguration cfg;

        public Startup(IConfiguration cfg)
        {
            this.cfg = cfg;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGazelServiceApplication(cfg,
                database: c => c.Sqlite("gazel.tutorial.db"),
                service: c => c.Routine("http://localhost:5000/service"),
                logging: c => c.Log4Net(LogLevel.Info, l => l.DefaultConsoleAppenders()),
                authentication: c => c.AllowAnonymous(),
                authorization: c => c.AllowAll()
            );
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseGazel();
        }
    }
}

As you can see there are 5 configurations;

  • database: c => c.Sqlite("gazel.tutorial.db") tells Gazel to use a local SQLite database with a file named gazel.tutorial.db. This file will be located in default user documents folder.
  • service: c => c.Routine("http://localhost:5000/service") tells Gazel the service url base to itself to be able to make internal calls.
  • logging: c => c.Log4Net(LogLevel.Info, l => l.DefaultConsoleAppenders()) tells Gazel to use console appenders in info level
  • authentication: c => c.AllowAnonymous() disables authentication feature.
  • authorization: c => c.AllowAll() disables authorization feature.

You need to configure your application port correctly. You can go to Properties/launchSettings.json and set it to 5000;

launchSettings.json
{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:5000",
      "sslPort": 5001
    }
  },
  "profiles": {
    "Inventiv.Todo.App.Service": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Gazel scans bin directory to configure your classes automatically. To understand which assembly is yours, Gazel uses assembly name of your app project. If your host project is named Foo.Bar.Host.Service then it will only scan assemblies with a name that starts with Foo.

Create a Rest API application

Now create another web project and name it after <Company>.<Component>.App.Rest format;

dotnet new web --output src/Inventiv.Todo.App.Rest
dotnet sln add src/Inventiv.Todo.App.Rest --solution-folder src

Now your solution explorer should look like this;

Inventiv.Todo
└── src
    ├── Inventiv.Todo.App.Rest
    │   ├── Properties
    │   │   └── launchSettings.json
    │   ├── appsettings.json
    │   │   └── appsettings.Development.json
    │   └── Program.cs
    └── Inventiv.Todo.App.Service
        ├── Properties
        │   └── launchSettings.json
        ├── appsettings.json
        │   └── appsettings.Development.json
        ├── Program.cs
        └── Startup.cs

Now add Gazel.Configuration package to the App.Rest project from nuget.org.

dotnet add src/Inventiv.Todo.App.Rest package Gazel.Configuration

To configure this project to use Gazel, modify Program.cs file in src/Inventiv.Todo.App.Rest as below;

Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Inventiv.Todo.App.Rest
{
    public class Program
    {
        public static void Main(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseGazelServiceProvider()
                .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
                .Build()
                .Run();
    }
}

Up to this point it is exactly the same as creating a service application. This time Startup.cs exposes a different configuration;

Startup.cs
using Gazel.Logging;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Inventiv.Todo.App.Rest
{
    public class Startup
    {
        private readonly IConfiguration configuration;

        public Startup(IConfiguration configuration) => this.configuration = configuration;

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGazelApiApplication(configuration,
                serviceClient: c => c.Routine("http://localhost:5000/service"),
                restApi: c => c.Standard(),
                logging: c => c.Log4Net(LogLevel.Info, l => l.DefaultConsoleAppenders())
            );
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseGazel();
            app.UseCors();
        }
    }
}

As you can see there are 3 main configurations.

  • serviceClient: c => c.Routine("http://localhost:5000/service")) tells Gazel to use previously created service application as a backend service.
  • restApi: c => c.Standard() tells Gazel to use standard rest configuration which uses AspNetCore.Mvc template.
  • logging: c => c.Log4Net(LogLevel.Info, l => l.DefaultConsoleAppenders()) tells Gazel to use console appenders in info level

Now you've set up your environment to start developing a new backend. To add a new business module to your project, check out next section.

Add a module

In this document you will learn to create a new business module to your existing solution.

Create a new module

A module is a project that contains the domain logic of a specficic subset of your backend, so choose a name accordingly. Naming convention for module projects is <Company>.<Component>.Module.<ModuleName>.

Now create a class library project under src and add it to solution.

dotnet new classlib --output src/Inventiv.Todo.Module.TaskManagement
dotnet sln add src/Inventiv.Todo.Module.TaskManagement --solution-folder src

Check if your solution has new module under src folder;

Inventiv.Todo
└── src
    ├── Inventiv.Todo.App.Rest
    ├── Inventiv.Todo.App.Service
    └── Inventiv.Todo.Module.TaskManagement

Add Gazel to your new module;

dotnet add src/Inventiv.Todo.Module.TaskManagement package Gazel

Modules only use Gazel. Do NOT add Gazel.Configuration package to a module project.

Finally you need to add your module project reference to App.Service so that it renders and exposes business services in your new module.

dotnet add src/Inventiv.Todo.App.Service reference src/Inventiv.Todo.Module.TaskManagement

Create a test project

To test your business services you need to create a test project. Naming convention for test projects is <Company>.<Component>.Test.<ModuleName>.

Add a new class library project under test folder. Add Gazel.Configuration package and module reference to the new project;

dotnet new nunit --output test/Inventiv.Todo.Test.TaskManagement
dotnet sln add test/Inventiv.Todo.Test.TaskManagement --solution-folder test
dotnet add test/Inventiv.Todo.Test.TaskManagement package Gazel.Configuration
dotnet add test/Inventiv.Todo.Test.TaskManagement reference src/Inventiv.Todo.Module.TaskManagement

Your directory structure should look like this;

Inventiv.Todo
├── src
│   ├── Inventiv.Todo.App.Rest
│   ├── Inventiv.Todo.App.Service
│   └── Inventiv.Todo.Module.TaskManagement
└── test
    └── Inventiv.Todo.Test.TaskManagement

Congrats 🥳! You've just learned to create a new project using Gazel.