In my repo I've got this `using MusicLab.Projects.Models;
using System.Collections.Generic;
using System.Linq;
namespace MusicLab.Projects.Data
{
public class InstrumentRepository : IInstrumentRepository
{
private readonly MusicDbContext _context;
public InstrumentRepository(MusicDbContext context)
{
_context = context;
}
public List<Instrument> GetInstruments()
{
return _context.GetInstruments();
}
public List<Instrument> GetInstrumentsByCategory(string category)
{
return _context.GetInstruments().Where(i => i.Category == category).ToList();
}
public Instrument FindById(int id)
{
return _context.FindById(id);
}
public void Add(Instrument i)
{
_context.Add(i);
}
public void Update(Instrument i)
{
_context.Update(i);
}
public void Remove(int id)
{
_context.Remove(id);
}
}
}`
and then in my interface :
C#
using MusicLab.Projects.Models;
namespace MusicLab.Projects.Utils
{
public interface ITaxCalculator
{
decimal CalculateTax(Instrument instrument);
}
public class DefaultTaxCalculator : ITaxCalculator
{
public decimal CalculateTax(Instrument instrument)
{
// Standard tax calculation replacing the static method
return instrument.Price * 0.15m;
}
}
}
and then my csv exporter :
C#
using MusicLab.Projects.Models;
using System.Collections.Generic;
using System.Text;
namespace MusicLab.Projects.Utils
{
public interface ICsvExporter
{
string ExportInstrumentsCsv(List instruments);
}
public class CsvExporter : ICsvExporter
{
public string ExportInstrumentsCsv(List<Instrument> instruments)
{
var sb = new StringBuilder();
sb.AppendLine("Id,Name,Price,Category");
foreach (var i in instruments)
{
sb.AppendLine($"{i.Id},{i.Name},{i.Price},{i.Category}");
}
return sb.ToString();
}
}
}
and then the controller :
C#
using Microsoft.AspNetCore.Mvc;
using MusicLab.Projects.Data;
using MusicLab.Projects.Models;
using MusicLab.Projects.Utils;
using System.Collections.Generic;
using System.Text;
namespace MusicLab.Projects.Controllers
{
public class InstrumentsController : Controller
{
private readonly IInstrumentRepository _repository;
private readonly ICsvExporter _exporter;
private readonly ITaxCalculator _taxCalculator;
public InstrumentsController(IInstrumentRepository repository, ICsvExporter exporter, ITaxCalculator taxCalculator)
{
_repository = repository;
_exporter = exporter;
_taxCalculator = taxCalculator;
}
public IActionResult Index(string category)
{
List<Instrument> instruments;
if (!string.IsNullOrWhiteSpace(category))
{
instruments = _repository.GetInstrumentsByCategory(category);
}
else
{
instruments = _repository.GetInstruments();
}
return View(instruments);
}
public IActionResult Details(int id)
{
Instrument instrument = _repository.FindById(id);
if (instrument == null) return NotFound();
ViewData["Tax"] = _taxCalculator.CalculateTax(instrument);
return View(instrument);
}
[HttpPost]
public IActionResult Create(Instrument model)
{
if (model == null) return BadRequest("No data");
// Replaced manual model.IsValid() with built-in ModelState validation
if (!ModelState.IsValid) return BadRequest("Invalid instrument");
_repository.Add(model);
return Redirect("/Instruments/Index");
}
public IActionResult Export()
{
List<Instrument> instruments = _repository.GetInstruments();
string csv = _exporter.ExportInstrumentsCsv(instruments);
byte[] bytes = Encoding.UTF8.GetBytes(csv);
return File(bytes, "text/csv", "instruments.csv");
}
}
}
and then program.cs :
C#
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using MusicLab.Projects.Data;
using MusicLab.Projects.Utils;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
// Register the mock DbContext as a Singleton so the list persists in memory
builder.Services.AddSingleton();
// Register dependencies for Dependency Injection
builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
var app = builder.Build();
app.UseRouting();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Instruments}/{action=Index}/{id?}");
app.Run();
Top comments (0)