I have implemented service which working with db context. I am using entity framework and I do not need repositories because logic is quite simple.
I want to keep simple logic but clean approach. One problem I have is when I want to call service method 2 times in same service instance. I will get context dispose exception. this is not problem in my case because for now I do not have case like that. But maybe you have idea for better solution.
my code:
using Common.Configurations;
using Common.Container;
using Common.Factory;
using Common.Helpers;
using Common.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using RemoteManager.EntityFramework;
using Common.Entities;
namespace RemoteManagerApi.Services
{
public class MachineService : IMachineService
{
private readonly IOptions<ApplicationConfiguration> applicationConfiguration;
private readonly ILogger<MachineService> logger;
private readonly IMachineCleaner machineCleaner;
private readonly IFileContainer fileContainer;
private readonly RemoteManagerContext context;
public MachineService(RemoteManagerContext context, IFileContainerFactory fileContainerFactory, IOptions<ApplicationConfiguration> applicationConfiguration, IMachineCleaner machineCleaner, ILogger<MachineService> logger)
{
this.fileContainer = fileContainerFactory.CreateContainer();
this.applicationConfiguration = applicationConfiguration;
this.logger = logger;
this.machineCleaner = machineCleaner;
this.context = context;
}
public async Task<MachineConfiguration> Add(MachineConfiguration machine)
{
try
{
await this.fileContainer.CreateDirectory(machine.SessionFolder);
logger.LogInformation($"Start {nameof(MachineService)}:{nameof(this.Add)}");
using (var db = this.context)
{
var res = db.MachineConfigurations.Add(machine);
db.SaveChanges();
return await Task.FromResult(res);
}
}
catch
{
logger.LogError($"Error {nameof(MachineService)}:{nameof(this.Add)}");
throw;
}
}
public async Task<bool> Delete(int id)
{
try
{
logger.LogInformation($"Start {nameof(MachineService)}:{nameof(this.Delete)}");
using (var db = this.context)
{
var machineConfiguration = db.MachineConfigurations.FirstOrDefault(f => f.Id == id);
var isDeleted = db.MachineConfigurations.Remove(machineConfiguration);
db.SaveChanges();
return await Task.FromResult(true);
}
}
catch
{
logger.LogError($"Error {nameof(MachineService)}:{nameof(this.Delete)}");
throw;
}
}
public async Task<MachineConfiguration> Get(int id)
{
try
{
logger.LogInformation($"Start {nameof(MachineService)}:{nameof(this.Get)}");
using (var db = this.context)
{
var machineConfiguration = db.MachineConfigurations.FirstOrDefault(f => f.Id == id);
return await Task.FromResult(machineConfiguration);
}
}
catch
{
logger.LogError($"Error {nameof(MachineService)}:{nameof(this.Get)}");
throw;
}
}
public async Task<IEnumerable<MachineConfiguration>> GetAll()
{
try
{
logger.LogInformation($"Start {nameof(MachineService)}:{nameof(this.GetAll)}");
using (var db = this.context)
{
var machineConfigurations = db.MachineConfigurations.ToList();
return await Task.FromResult(machineConfigurations);
}
}
catch
{
logger.LogError($"Error {nameof(MachineService)}:{nameof(this.GetAll)}");
throw;
}
}
}
}
DbContext
is a unit of work - it encapsulates a transaction. Wrapping it with a full-blown UoW+Repository pattern isn't just overkill, it's outright wrong IMO. And it wouldn't solve the "who's responsible for disposing the context" problem. – Mat's Mug♦ Nov 10 '16 at 14:50