Services & Helpers
Put code in another file — a service or a static helper — and call it from anywhere, the C# way.
#csharp #dotnet #services #architecture
You already write services in Laravel — the C# version is nearly the same shape.
The two things to learn are how another file becomes visible (namespaces +
using) and when to make it a static helper vs an instance service.
A service in its own file
Say you have a login service. It lives in its own file, in a namespace:
using MyApp.Models;
namespace MyApp.Services;
public class LoginService
{
private readonly List<User> _users;
public LoginService(List<User> users)
{
_users = users;
}
// Return a RESULT — let the caller decide how to present it.
public User? Login(string username, string password)
{
return _users.FirstOrDefault(
u => u.Username == username && u.Password == password
);
}
}
Use it from Program.cs — using makes the namespace visible:
using MyApp.Models;
using MyApp.Services;
var users = new List<User>
{
new User { Username = "ada", Password = "secret" }
};
var loginService = new LoginService(users);
var user = loginService.Login("ada", "secret");
// The CALLER handles presentation, not the service:
if (user is not null)
Console.WriteLine($"Welcome, {user.Username}!");
else
Console.WriteLine("Invalid credentials.");
Console.WriteLineinside the service. A service that returns a
User? (or a success/failure result) can be reused from a console app, a web
API, or a test. A service that prints to the console can only ever be a console
app. Same rule as Laravel: the service returns data, the controller renders it.
See Services return, callers present.Static helper (utility functions)
A helper is stateless — a bag of pure functions, like a Laravel helper file.
Make the class static so you call it directly without new:
namespace MyApp.Helpers;
public static class TextHelper
{
public static string Slugify(string input)
{
return input.Trim().ToLower().Replace(" ", "-");
}
}
using MyApp.Helpers;
var slug = TextHelper.Slugify("Hello World"); // "hello-world"
Service vs helper — which one?
| Use a service (instance) | Use a static helper |
|---|---|
| Holds state or dependencies (a user list, a DB, config) | Pure input → output, no state |
| You want to swap/mock it in tests | Never needs mocking |
new LoginService(users) | TextHelper.Slugify(...) |
| Laravel: an injected service class | Laravel: a helpers.php function |
The grown-up version: dependency injection
Creating services with new by hand is fine for a small console app. Real .NET
apps register services in a container and let it hand them to you — exactly
like Laravel's service container binding:
// In a full app's startup:
builder.Services.AddScoped<LoginService>();
// Then any class can just ask for it in its constructor:
public class LoginController(LoginService loginService) { /* ... */ }
new is honest and simple. But
recognise it when you see it: AddScoped / AddSingleton / AddTransient is
.NET doing what $this->app->bind() does in Laravel. Reach for it once you
have more than a handful of services wiring each other up.Next
See how namespaces, folders and the dotnet CLI tie all these files together → Project structure.
Classes & Models
Create a class, give it properties and a constructor, and use it — the C# version of a Laravel model.
Project Structure
How C# files, namespaces, folders and the dotnet CLI fit together into a running app.