What's the best way to update an entity using a service layer? Performing a single, atomic action I can understand like BlogService.Publish(blogID) but what about editing multiple values which map to the database entity? Consider the following code:
public void Company(model As CompanyViewModel) {
var comp = _companyQueryService.GetByID(model.ID)
// ??? now what?
}
I could pass in the viewmodel to some kind of UpdateCompany method but tying the viewmodel to the service sounds super icky.
I could edit the values on the entity directly but then how do i save the changes without access to the context? (My context is only injected into services via a context scoping mechanism which allows me to nest dbcontexts for atomic, multi-action transactions.)
I could edit the values directly on the entity and then just call SaveChanges on the service directly but i'd rather let the services dictate when the context is saved.
Are there any other options?
1 Answer 1
Why not inject an application service into the viewmodel? The viewmodel would then use the application service to interact with the repository. Your code would look like this:
Application Layer
public class CompanyView
{
public CompanyView(CompanyViewModel companyVM)
{
_companyVM = companyVM;
}
// view methods
// if using WPF, would most likely not exist
private CompanyViewModel _companyVM;
}
public class CompanyViewModel
{
public CompanyViewModel(CompanyAppService companyService)
{
_companyService = companyService;
}
// view model methods to handle application logic
private CompanyAppService _companyService;
}
public class CompanyAppService
{
public CompanyAppService(ICompanyRepository companyRepo)
{
_companyRepo = companyRepo;
}
// application service methods that tie everything together with
// logging, coordinating BLL method calls, persistence, etc.
private ICompanyRepo _companyRepo;
}
Business Layer
interface ICompanyRepository
{
// CRUD interface methods
Company getById(CompanyId id);
}
public class Company
{
// handle business logic of a company entity
}
Data Access Layer
public class SqlCompanyRepository : ICompanyRepository
{
// implement CRUD methods for SQL databse
Company getById(CompanyId id) { //return a company entity }
}
Then you would inject everything in Main (or MainViewModel) like:
CompanyView companyView = new CompanyView(
new CompanyViewModel(
new CompanyAppService(
new SqlCompanyRepository())));
Obviously with MVC you wouldn't have a viewmodel, but would use a controller instead to handle the application logic. Your service would then handle orchestrating the business layer, logging, saving to the database, etc.
Additionally, your domain model would have domain events that the application layer could subscribe to for things like logging.
Explore related questions
See similar questions with these tags.