Business assemblies
When you create a business assembly in Neos Studio, it generates C# projects following Clean Architecture principles.
Create business assemblies
To create business assemblies for a module in Neos Studio:
- Open the module's screen
- Navigate to the Business Assemblies tab
- Click the Create projects button
A dialog appears allowing you to configure the project generation:
- Layers: Select which layers to generate (Domain, Application, or both)
- Unit test projects: Choose whether to generate the associated unit test projects (
Domain.Tests.UnitTestsandApplication.Tests.UnitTests)
Tip
If you only need to implement entity validation rules or event rules that don't require application services, you can generate only the Domain layer. You can always add the Application layer later if needed.
Project structure
modules/
└── MyModule/
└── businessAssembly/
├── Domain/ # Domain layer
│ ├── EventRules/ # Entity event rules
│ ├── ValidationRules/ # Entity validation rules
│ ├── Startup.cs # Service registration (optional, manually created)
├── Domain.Tests.UnitTests/ # Domain tests
├── Application/ # Application layer
│ ├── DomainValidationRules/ # Entity validation rules needing Application services
│ ├── DomainEventRules/ # Entity event rules needing Application services
│ ├── EventRules/ # Entity view event rules
│ ├── Methods/ # Server methods
│ ├── ValidationRules/ # Entity view validation rules
│ ├── Startup.cs # Service registration (optional, manually created)
└── Application.Tests.UnitTests/ # Application tests
Note
Beyond the directories created by Neos Studio for validation rules, event rules, and server methods, you are free to organize your business assemblies as you see fit. You can create additional directories such as Helpers/, Services/, Extensions/, or any structure that suits your project. You can also add classes anywhere within the project.
Server methods can be further organized in subfolders within the Methods/ directory (e.g., Methods/Orders/CreateOrder.cs). The Neos code generator determines the expected namespace based on the folder structure. For more details, see Organizing server method files.
Startup class
The Startup.cs file is not automatically generated by the framework. You can create it manually in your business assembly when you need to register custom services for dependency injection. If the file exists, the framework will automatically discover and call the ConfigureServices method at startup. For detailed instructions, see Register additional services.
// Domain layer Startup.cs
public static class Startup
{
public static void ConfigureServices(IServiceCollection services)
{
// Register domain services
services.AddScoped<IDashboardHelper, DashboardHelper>();
services.AddScoped<IOrderValidator, OrderValidator>();
}
}
// Application layer Startup.cs
public static class Startup
{
public static void ConfigureServices(IServiceCollection services)
{
// Register application services
services.AddScoped<IOrderService, OrderService>();
services.AddTenantDatabaseMigrationInterceptor<MyMigrationInterceptor>();
}
}
Repositories and data access
Neos implements the repository pattern to abstract data access, following Clean Architecture principles:
- Domain layer: Defines repository interfaces (
IRepository<TEntity>) - Infrastructure layer: Implements repositories using Entity Framework Core
- Application layer: Uses
IEntityViewRepository<TEntityView>for entity views
// Domain layer - uses entity repository
public class OrderDomainService
{
private readonly IRepository<Order> _orderRepository;
public OrderDomainService(IRepository<Order> orderRepository)
{
_orderRepository = orderRepository;
}
}
// Application layer - can use entity view repository
public class OrderApplicationService
{
private readonly IEntityViewRepository<IOrderView> _orderViewRepository;
public OrderApplicationService(IEntityViewRepository<IOrderView> orderViewRepository)
{
_orderViewRepository = orderViewRepository;
}
}
For more details, see the Repositories documentation and the Unit of Work pattern.
Testing strategy
Clean Architecture enables effective testing strategies at each layer:
| Layer | Test Type | Dependencies |
|---|---|---|
| Domain | Unit tests | Mocked repositories only |
| Application | Unit tests | Mocked domain services and repositories |
| End-to-End | E2E tests | Full application stack |
// Domain layer test - minimal dependencies
public class CheckOrderTotalTests : ValidationRuleTest<CheckOrderTotal, Order>
{
[Fact]
public async Task Validate_WhenOrderTotalIsNegative_ShouldReturnError()
{
// Arrange
Order order = new();
order.Total = -100;
// Act
IValidationRuleResult result = await ExecuteValidationRuleAsync(order);
// Assert
result.IsSuccess.Should().BeFalse();
}
}
For detailed guidance on testing your code in Visual Studio, see Testing your code in Visual Studio.
See also
- Clean Architecture - Architecture principles and framework structure
- Domain vs Application - When to use each layer
- Repositories - Data access patterns
- Dependency injection - Service registration and scopes
- Register additional services - Custom service registration