Skip to main content

.NET Framework 4.8 Architecture

Technical architecture of the APS platform based on .NET Framework 4.8 and modern dependency injection patterns.

Overview

APS (Avanteam Process Studio) is an application platform built on .NET Framework 4.8 that leverages modern Microsoft technologies while maintaining compatibility with the complete .NET ecosystem. The architecture is based on solid principles of separation of concerns, dependency injection, and modularity.

Core Technologies

  • .NET Framework 4.8: Main framework for the majority of components
  • ASP.NET: For the legacy web application (Web.Model)
  • Microsoft.Extensions.DependencyInjection: Microsoft standard IoC container
  • Entity Framework Core: ORM for data access
  • OWIN: Middleware for SignalR and other components

Dependency Injection

The APS architecture uses the dependency injection (DI) pattern as the primary mechanism for managing dependencies between components.

IoC Container

The IoC container used is Microsoft.Extensions.DependencyInjection, Microsoft's standard container, offering:

  • Service registration with different lifetimes (Singleton, Scoped, Transient)
  • Constructor injection support
  • Automatic dependency resolution
  • Native integration with ASP.NET Core and compatible with ASP.NET Framework via adapters

ApsAppBuilder

The DI container configuration is performed via the ApsAppBuilder class, which provides a fluent API for registering services:

var apsAppBuilder = new ApsAppBuilder<ApplicationDependencyInjection>(
webAppbuilder.Configuration,
webAppbuilder.Services,
webAppbuilder.Build,
serviceProviderAccessor);

apsAppBuilder
.AddKernel()
.AddDirectoryWeb()
.AddDirectoryApi()
.AddApplicationApi()
.AddStartupExtensions("Web.Model");

Each application module exposes an Add{Module} extension method that encapsulates the registration of its services.

Startup Model

Each application module defines a Startup class (or {Module}Startup) that centralizes service configuration:

Example: DirectoryStartup

public static class DirectoryStartup
{
public static IApsAppBuilder AddDirectory(
this IApsAppBuilder apsAppBuilder)
{
AddServices(apsAppBuilder.Services);
return apsAppBuilder.AddStartupExtensions("Directory");
}

private static void AddServices(IServiceCollection services)
{
services.AddDbContext<DirectoryContext>();
services.TryAddScoped<IResourceManager, ResourceManager>();
services.TryAddScoped<IUserManager, UserManager>();
// ... autres services
}
}

This pattern enables:

  • Modular and decoupled configuration
  • Declarative service registration
  • Easy extension by new modules

Service Lifetimes

Services are registered with appropriate lifetimes:

  • Singleton: Services shared throughout the application lifetime (configuration, factories)
  • Scoped: Services tied to an HTTP request or application scope (EF contexts, managers)
  • Transient: New instance on each injection (lightweight, stateless services)
services.TryAddSingleton<IConfiguration>();
services.TryAddScoped<IDocumentManager, DocumentManager>();
services.TryAddTransient<IPasswordPolicyLocalizer, PasswordPolicyLocalizer>();

Architectural Layers

The application is structured into distinct logical layers, each with a clear responsibility.

Kernel Layer

The Kernel constitutes the foundation of the application and provides cross-cutting services:

  • Configuration: Reading and managing configuration (ini files, appsettings.json)
  • Data Source: Data access abstraction
  • Dependency Injection: DI infrastructure and service locator
  • Logging: Logging services (NLog)
  • Mail: Email sending
  • Parameters: Application parameter management

The Kernel does not depend on any other layer and can be used autonomously.

Directory Layer

The Directory module manages everything related to the directory and authentication:

  • Identity: User, resource, organization model
  • Authentication: Authentication (Forms, Windows, SAML, OAuth)
  • Authorization: Permission and policy management
  • Synchronization: Synchronization with Active Directory / LDAP

Main components:

  • DirectoryContext: User context (name, roles, groups)
  • IUserManager: User management
  • IResourceManager: Directory resource management
  • IDelegationManager: Delegation management

Application Layer

The Application module contains the core business logic:

  • Documents: Document and metadata management
  • Forms: Form management
  • Views: View and query management
  • Workflows: Workflow engine (in separate module)
  • Agents: Scheduled tasks and automations
  • Archives: Document archiving

Main components:

  • IDocumentManager: CRUD and business logic for documents
  • IFormManager: Form definition management
  • IViewManager: View and query execution
  • IProcessInstanceManager: Workflow process instances

Web Layer

The Web layer exposes the application via HTTP:

  • Web.Model: Main ASP.NET application (Framework 4.8)
  • Controllers/Pages: Controllers and web pages
  • API: REST API endpoints
  • SignalR: Real-time communication

The web application uses OWIN to host SignalR and other middleware.

Studio Layer

The Studio is the desktop configuration tool (WinForms):

  • Form modeling interface
  • Workflow editor
  • View configuration
  • Parameter management

It uses the same business layer (Application) as the web application.

Multi-Database Management

The architecture supports a multi-tenant model with one database per client application:

services.AddDbContext<ApplicationContext>(ConfigureApplicationContext);

private static void ConfigureApplicationContext(
IServiceProvider serviceProvider,
DbContextOptionsBuilder options)
{
var profile = serviceProvider.GetRequiredService<ApplicationProfile>();
options.UseSqlServer(profile.ConnectionString);
}

The ApplicationProfile contains connection information specific to each application/tenant.

Databases

  • Directory Database (Directory): A common database containing users, roles, organizations
  • Application Databases: One database per business application containing documents and business data

Compatibility and Migration

The architecture enables progressive migration:

  • Legacy ASP.NET Framework code coexists with new components
  • Dependency injection integrated via adapters (AspNetDependencyInjection)
  • Entity Framework Core used even on .NET Framework 4.8
  • Preparation for future migration to modern .NET

Best Practices

Service Registration

Use TryAdd* methods to avoid multiple registrations:

services.TryAddScoped<IDocumentManager, DocumentManager>();

Startup Organization

Each module exposes an extension method on IApsAppBuilder:

public static IApsAppBuilder AddMyModule(this IApsAppBuilder builder)
{
// Configuration du module
return builder.AddStartupExtensions("MyModule");
}

Dependencies Between Modules

Dependencies between modules are explicit via extension method calls:

apsAppBuilder
.AddKernel() // Kernel en premier
.AddDirectory() // Directory dépend de Kernel
.AddApplication() // Application dépend de Directory
.AddApplicationApi(); // API dépend d'Application

References