0% found this document useful (0 votes)
7 views

C# Concepts 4

Uploaded by

musabinshabeer
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

C# Concepts 4

Uploaded by

musabinshabeer
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 25

C# Concepts

Repository Pattern
C#: Repository Pattern

• Definition: The Repository pattern abstracts the data access layer,


providing a collection-like interface for accessing domain objects. It
mediates between the domain and data mapping layers, promoting a
more loosely coupled architecture.
Singleton Pattern : Purpose
• Abstraction: Separates business logic from data access logic.

• Maintainability: Easier to manage and change data access


code.

• Testability: Facilitates mocking data access during testing.

• DRY Principle: Avoids duplication of data access code.


What is DRY Principle ?
• DRY stands for Don't Repeat Yourself, a key principle in
software development aimed at reducing repetition and
improving maintainability.
• The main idea of DRY is to avoid duplicating code or logic
across multiple parts of a program by ensuring that
functionality is defined in one place and reused whenever
needed.
• This helps make the code more modular, easier to maintain,
and less prone to errors.
Repository Pattern: Key Components
• Entity: Represents a domain object (e.g., User, Product).

• Repository Interface: Defines the operations for accessing


and manipulating entities.

• Repository Implementation: Implements the repository


interface, handling data access logic.

• Unit of Work (Optional): Manages transactions across


multiple repositories.
Example: User Repository with
Entity Framework Core
Assumptions:

• Using Entity Framework Core (EF Core) as the ORM.

• Having a User entity and a DbContext named AppDbContext.


Example Step 1: Define the Entity

public class User


{
public int Id { get; set; }
public string Name { get; set; }
// Additional properties...
}
Example Step 2: Define the
Repository Interface
public interface IUserRepository
{
Task<User> GetByIdAsync(int id);
Task<IEnumerable<User>> GetAllAsync();
Task AddAsync(User user);
Task UpdateAsync(User user);
Task DeleteAsync(int id);
}
Example Step 3: Implement the
Repository
using Microsoft.EntityFrameworkCore;

public class UserRepository : IUserRepository


{
private readonly AppDbContext _context;
private readonly DbSet<User> _dbSet;

public UserRepository(AppDbContext context)


{
_context = context;
_dbSet = _context.Set<User>();
Example Step 3: Implement the
Repository
public async Task<User> GetByIdAsync(int id)
{
return await _dbSet.FindAsync(id);
}

public async Task<IEnumerable<User>> GetAllAsync()


{
return await _dbSet.ToListAsync();
}
Example Step 3: Implement the
Repository
public async Task AddAsync(User user)
{
await _dbSet.AddAsync(user);
await _context.SaveChangesAsync();
}

public async Task UpdateAsync(User user)


{
_dbSet.Update(user);
await _context.SaveChangesAsync();
Example Step 3: Implement the
Repository
public async Task DeleteAsync(int id)
{
var user = await GetByIdAsync(id);
if (user != null)
{
_dbSet.Remove(user);
await _context.SaveChangesAsync();
}
}
}
Example Step 4: Configure
Dependency Injection
• In Program.cs or Startup.cs:

builder.Services.AddDbContext<AppDbContext>(options =>

options.UseSqlServer(builder.Configuration.GetConnectionString(
"DefaultConnection")));

builder.Services.AddScoped<IUserRepository, UserRepository>();
Example Step 5: Using the
Repository in a Service
public interface IUserService
{
Task<User> GetUserAsync(int id);
Task<IEnumerable<User>> GetAllUsersAsync();
Task CreateUserAsync(User user);
Task UpdateUserAsync(User user);
Task DeleteUserAsync(int id);
}
Example Step 5: Using the
Repository in a Service
public class UserService : IUserService
{
private readonly IUserRepository _userRepository;
private readonly ILogger _logger;

public UserService(IUserRepository userRepository, ILogger


logger)
{
_userRepository = userRepository;
_logger = logger;
}
Example Step 5: Using the
Repository in a Service
public async Task<User> GetUserAsync(int id)
{
_logger.Log($"Fetching user with ID: {id}");
return await _userRepository.GetByIdAsync(id);
}

public async Task<IEnumerable<User>> GetAllUsersAsync()


{
_logger.Log("Fetching all users.");
return await _userRepository.GetAllAsync();
}
Example Step 5: Using the
Repository in a Service
public async Task CreateUserAsync(User user)
{
_logger.Log($"Creating user: {user.Name}");
await _userRepository.AddAsync(user);
}

public async Task UpdateUserAsync(User user)


{
_logger.Log($"Updating user with ID: {user.Id}");
await _userRepository.UpdateAsync(user);
}
Example Step 5: Using the
Repository in a Service

public async Task DeleteUserAsync(int id)


{
_logger.Log($"Deleting user with ID: {id}");
await _userRepository.DeleteAsync(id);
}
}
Example Step 6: Using the Service
in a Controller
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
private readonly ILogger _logger;

public UsersController(IUserService userService, ILogger logger)


{
_userService = userService;
_logger = logger;
}
Example Step 6: Using the Service
in a Controller
HttpGet("{id}")]
public async Task<IActionResult> GetUser(int id)
{
var user = await _userService.GetUserAsync(id);
if (user == null)
return NotFound();

return Ok(user);
}
Example Step 6: Using the Service
in a Controller
[HttpGet]
public async Task<IActionResult> GetAllUsers()
{
var users = await _userService.GetAllUsersAsync();
return Ok(users);
}
Example Step 6: Using the Service
in a Controller
[HttpPost]
public async Task<IActionResult> CreateUser(User user)
{
await _userService.CreateUserAsync(user);
return CreatedAtAction(nameof(GetUser), new { id =
user.Id }, user);
}
Example Step 6: Using the Service
in a Controller
[HttpPut("{id}")]
public async Task<IActionResult> UpdateUser(int id, User user)
{
if (id != user.Id)
return BadRequest();

await _userService.UpdateUserAsync(user);
return NoContent();
}
Example Step 6: Using the Service
in a Controller
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUser(int id)
{
await _userService.DeleteUserAsync(id);
return NoContent();
}
}
Benefits of Repository Pattern:
• Separation of Concerns: Business logic is separated from data
access logic.

• Testability: Easier to mock repositories for unit testing services.

• Maintainability: Changes in data access logic affect only the


repository layer.

• Abstraction: Clients do not need to know the details of data storage.

You might also like