0% found this document useful (0 votes)
19 views25 pages

C# Concepts 4

Uploaded by

musabinshabeer
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views25 pages

C# Concepts 4

Uploaded by

musabinshabeer
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
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