When I use Web (MVC), I always to create a separate classes layer. These classes often the same as DTO classes, but with attributes like [Display(Name = "Street")] and validation. But for web api Display attributes are not necessary, validation can be used by FluentValidation. Should Api controller returns ViewModels classes or DTO classes will be fine too?
the answer, as always is .... it depends.
If your API is serving multiple clients , apps etc, then returning DTOs is a better options.
ViewModels are specific to the MVC client and should already be prepared for display, meaning the data should already be formatted in a specific way, some fields maybe combined, they should satisfy whatever requirements the display pages have. They are called ViewNodels for a reason. The point is that they are rarely exactly the same as the data the API returns, which should be a bit more generic and follow a certain pattern to make sense to its users.
If your ViewModels are exactly the same and you only have one client then it's up to you if you want to create a set of duplicated classed just to avoid having the attributes.
Mapping from DTO to ViewModel and viceversa is not exactly complicated, but the process does introduce one more complication, one more layer.
Don't forget one thing though. API DTOs are supposed to return the data they have on any entity regardless of the requirements of any UI. Requirements can change anyway, new fields added or discarded. You're more than likely to leave the API alone when that happens and simply change your ViewModels.
Your ViewModels are specific to a UI page and should contain only the data required by that page. This means that you can end up with multiple ViewModels for the same data, it's just that the display requirements are different for each.
My vote goes towards keeping the ViewModels and DTOs separate, even if, at this point in time they are exactly the same. Thins always change and this is one of those things you can actually be ready for.
Actually it depends on application's architecture how we want to return response. In this case yes we can return DTO classes but i think that would not be the good approach because we should create a separate Resource classes that will map with DTO and then return. Just see the below example:
public class CustomerDTO
{
public int ID { get; set; }
public string Name { get; set; }
public int DepartmentId { get; set; }
}
public class CustomerResource
{
[JsonObject]
public string Name { get; set; }
[JsonObject]
public string Department { get; set; }
}
Suppose we have CustomerDTO class and we want to return response in the following json format
{
"name":"Abc xyz",
"department":"Testing"
}
So in this case we should we have separate class that will return as a response to the end user as i created CustomerResource. In this scenario we will create a mapper that will map DTO with resource object.
And also with this implementation we can test resources independently
Related
I hear that for a small project DTO's are not recommended for example here and here. I wonder if it is OK for a considerably small project (team-wise) to merge non-persistent properties in the domain models? eg:
namespace Domain.Entities
{
public class Candidate : BaseEntity
{
public Candidate()
{
// some construction codes
}
// region persistent properties
public string FirstName { get; set; }
public string LastName { get; set; }
public bool? IsMale { get; set; }
public DateTime BirthDate { get; set; }
// other properties ...
// region non-persistent properties
public string FullName => $"{FirstName} {LastName}";
}
}
Is this just keeping simple or am loosing anything valuable this way?
I'm not advocating a particular approach, just sharing information...
I wouldn't put your computation of FullName in a DTO. A DTO is just a simple object, really more of a struct, and shouldn't have any logic in it. The purpose of a DTO is to move data from one layer/tier to another and create a layer of indirection that allows your domain model to evolve independent of your clients. FullName on your Entity as a non-persistent property makes more sense here than in the DTO. If you want to go full enterprise, it would be in a transformer/adapter.
If your project is really small, and is likely never going to grow, then abandoning the DTO can be acceptable. Just keep in mind, that if your project grows you may have to do some refactoring, and there are some other things to consider...
Another benefit of the DTO is keeping some data where it needs to stay. For example, if you have sensitive data in your entity object and you don't put something in place to prevent it from being returned in a web request, you just leaked some information off your app server layer (think the password field in your user entity). A DTO requires you to think about what is being sent to/from the client and makes including data an explicitly intentional act vs an unintentional act. DTOs also make it easier to document what is really required for a client request.
That being said, each DTO is now code you have to write and maintain, which is the main reason to avoid them, and a model change can have a noticeable ripple effect through the system.
It comes down to deciding how you want to handle potential data leakage, how you want to manage your clients (if you can), and how complex your model may get.
So, I've got an aggregate( Project ) that has a collection of entities (ProjectVariables) in it. The variables do not have Ids on them because they have no identity outside of the Project Aggregate Root.
public class Project
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<ProjectVariable> ProjectVariables { get; set; }
}
public class ProjectVariable
{
public string Key { get; set; }
public string Value { get; set; }
public List<string> Scopes { get; set; }
}
The user interface for the project is an Angular web app. A user visits the details for the project, and can add/remove/edit the project variables. He can change the name. No changes persist to the database until the user clicks save and the web app posts some json to the backend, which in turns passes it down to the domain.
In accordance to DDD, it's proper practice to have small, succinct methods on the Aggregate roots that make atomic changes to them. Examples in this domain could be a method Project.AddProjectVariable(projectVariable).
In order to keep this practice, that means that the front end app needs to track changes and submit them something like this:
public class SaveProjectCommand
{
public string NewName { get; set; }
public List<ProjectVariable> AddedProjectVariables { get; set; }
public List<ProjectVariable> RemovedProjectVariables { get; set; }
public List<ProjectVariable> EditedProjectVariables { get; set; }
}
I suppose it's also possible to post the now edited Project, retrieve the original Project from the repo, and diff them, but that seems a little ridiculous.
This object would get translated into Service Layer methods, which would call methods on the Aggregate root to accomplish the intended behaviors.
So, here's where my questions come...
ProjectVariables have no Id. They are transient objects. If I need to remove them, as passed in from the UI tracking changes, how do identify the ones that need to be removed on the Aggregate? Again, they have no identification. I could add surrogate Ids to the ProjectVariables entity, but that seems wrong and dirty.
Does change tracking in my UI seem like it's making the UI do too much?
Are there alternatives mechanisms? One thought was to just replace all of the ProjectVariables in the Project Aggregate Root every time it's saved. Wouldn't that have me adding a Project.ClearVariables() and the using Project.AddProjectVariable() to the replace them? Project.ReplaceProjectVariables(List) seems to be very "CRUDish"
Am I missing something a key component? It seems to me that DDD atomic methods don't mesh well with a pattern where you can make a number of different changes to an entity before committing it.
In accordance to DDD, it's proper practice to have small, succinct
methods on the Aggregate roots that make atomic changes to them.
I wouldn't phrase it that way. The methods should, as much as possible, reflect cohesive operations that have a domain meaning and correspond with a verb or noun in the ubiquitous language. But the state transitions that happen as a consequence are not necessarily small, they can change vast swaths of Aggregate data.
I agree that it is not always feasible though. Sometimes, you'll just want to change some entities field by field. If it happens too much, maybe it's time to consider changing from a rich domain model approach to a CRUD one.
ProjectVariables have no Id. They are transient objects.
So they are probably Value Objects instead of Entities.
You usually don't modify Value Objects but replace them (especially if they're immutable). Project.ReplaceProjectVariables(List) or some equivalent is probably your best option here. I don't see it as being too CRUDish. Pure CRUD here would mean that you only have a setter on the Variables property and not even allowed to create a method and name it as you want.
I'm a novice trying to wrap my head around MVVM. I'm trying to build something and have not found an answer on how to deal with this:
I have several models/entities, some of which have logical connections and I am wondering where/when to bring it all together nicely.
Assume we have a PersonModel:
public class PersonModel
{
public int Id { get; set; }
public string Name { get; set; }
...
}
And a ClubModel:
public class ClubModel
{
public int Id { get; set; }
public string Name { get; set; }
...
}
And we have MembershipModel (a Person can have several Club memberships):
public class MembershipModel
{
public int Id { get; set; }
public PersonId { get; set; }
public ClubId { get; set; }
}
All these models are stored somewhere, and the models are persisted "as in" in that data storage.
Assume we have separate repositories in place for each of these models that supplies the standard CRUD operations.
Now I want to create a view model to manage all Persons, e.g. renaming, adding memberships, etc. -> PersonMangementViewModel.
In order to nicely bind a Person with all its properties and memberships, I would also create a PersonView(?)Model that can be used in the PersonManagementViewModel. It could contain e.g. view relevant properties and also the memberships:
public class PersonViewModel : PersonModel
{
public Color BkgnColor { get return SomeLogic(); }
public IEnumerable<MembershipModel> { get; set; }
...
}
My question here is, how would I smartly go about getting the Membership info into the PersionViewModel? I could of course create an instance of the MemberShipRepo directly in the PersionViewModel but that seems not nice, especially if you have a lot of Persons. I could also create all repositories in the PersonManagementViewModel and then pass references into the PersonViewModel.
Or does it make more sense to create another layer (e.g. "service" layer) that returns primarily the PersonViewModel, therefore uses the individual repositories and is called from the PersonManagementViewModel (thus removing the burden from it and allowing for re-use of the service elsewhere)?
Happy to have pointed out conceptional mistakes or some further reading.
Thanks
You are creating separate model for each table I guess. Does not matter, but your models are fragmented. You can consider putting related data together using Aggregate Root and Repository per Aggregate root instead of per model. This concept is discussed under DDD. But as you said you are new to MVVM, there is already lot much to learn. Involving DDD at this stage will only complicate the things.
If you decide to keep the things as is, best and quick thing I can guess is what you are doing now. Get instance of model from data store in View Model (or whatever your location) and map somehow. Tools like Automapper are good but they does not fit each situation. Do not hesitate to map by hand if needed. You can also use mix approach (Automapper + map by hand) to simplify the things.
About service layer, sure... why not. Totally depends on you. If used, this layer typically contain your business logic, mapping, formatting of data, validations etc. Again, each of that thing is up to you.
My suggestions:
Focus on your business objectives first.
Design patterns are good and helpful. Those are extract of many exceptionally capable developers to solve specific problem. Do use them. But, do not unnecessarily stick to it. Read above suggestion. In short, avoid over-engineering. Design patterns are created to solve specific problem. If you do not have that problem, then do not mess-up your code with unnecessary pattern.
Read about Aggregate Root, DDD, Repository etc.
Try your best to avoid Generic Repository.
So, i decided to learn DDD as it seems to solve some architectural problems i have been facing. While there are lots of videos and sample blogs, i have not encountered one that guides me to solve the following scenario:
Suppose i have the entity
public class EventOrganizer : IEntity
{
public Guid Id { get; }
public string Name { get; }
public PhoneNumber PrimaryPhone { get; }
public PhoneNumber AlternatePhone { get; private set; }
public Email Email { get; private set; }
public EventOrganizer(string name, PhoneNumber primaryPhoneNr)
{
#region validations
if (primaryPhoneNr == null) throw new ArgumentNullException(nameof(primaryPhoneNr));
//validates minimum length, nullity and special characters
Validator.AsPersonName(name);
#endregion
Id = new Guid();
Name = name;
PrimaryPhone = primaryPhoneNr;
}
}
My problem is: suppose this will be converted and fed to a MVC view and the user wants to update the AlternatePhone, the Email and a lot of other properties that make sense to exist within this entity for the given bounded context (not shown for brevity)
I understand that the correct guidance is to have a method for each operation, but (AND I KNOW ITS KINDA OF ANTI-PATTERN) i cant help but wonder if this wont end up triggering multiple update calls on the database.
How is this handled ? somewhere down the line, will there be something that maps my EventOrganizer to something - say DbEventOrganizer and gathers all changes made to the domain entity and apply those in a single go?
DDD is better suited for task-based UIs. What you describe is very CRUD-oriented. In your case, individual properties are treated as independent data fields where one or many of these can be updated by a single generic business operation (update).
You will have to perform a deeper analysis of your domain than this if you want to be successfull with DDD.
Why would someone update all those fields together? What implicit business operation is the user trying to achieve by doing that? Is there a more concrete business process that is expressed by changing PrimaryPhone, AlternatePhone and Email together?
Perhaps that is changing the ContactInformation of an EventOrganizer? If that's the case then you could model a single ChangeContactInformation operation on EventOrganizer. Your UI would then send a ChangeContactInformation command rather than an update command.
As for the persistence of your aggregate roots (AR), this is usually handled by an ORM like NHibernate if you are using a RDBMS. However, there are other ways to persist your ARs like Event Sourcing, NoSQL DBs and even storing JSON or any other data inter-change formats in a RDBMS.
You question is quite broad!
EventOrganizer itself should not be updating anything. You should keep your update code quite separate from the entity. A different class would take an EventOrganizer object and update the DB. This is called 'persistence ignorance' and makes the code a lot more modular and cohesive.
It would be common to create a View Model - a class whose purpose is to provide the View with the exact data it needs in the exact form it needs. You would need to create the View Model from your EventOrganizer, after which the View can update it - programmatically or with binding. When you're ready to save the changes, you'll need to update your EventOrganizer from the View Model and pass it onto the updater. This seems like a layer you don't need when the project is small and simple, but it is becomes invaluable as the complexity builds.
For reasons beyond my control I cannot use a real ORM, so I am forced to create a custom DAL that sits over the raw data and returns "domain objects" to the consumer. Also for reasons beyond my control I must use Stored Procedures for data access.
I am making use of the Factory and Repository patterns for data access, or at least in basic theory:
The call to SqlCommand and friends is hidden by a Repository class that takes parameters as needed and returns domain objects.
To create the domain object, the Repository has an internal reference to a Factory of it's own type (e.g. Customer, Order, etc.). The factory has a single method, Create, which takes a DataRow as its input and maps the DataRow's columns to properties of the domain object.
This seems to work fairly well for basic objects that map to a single table. Now, here's the issue I'm running into: I want some of these domain objects to be richer and have collections of related objects. Here's a concrete example of a domain object in this system I'm working on:
class Case
{
public string CaseNumber { get; internal set; }
public ICollection<Message> Messages { get; set; }
}
class Message
{
public int MessageId { get; internal set; }
public string Content { get; set; }
}
In simple parlance, Case has many Messages. My concern is the best way to retrieve the raw data for a Case, since I also need a list of associated messages. It seems to me I can either:
Run a second stored procedure in the CaseRepository when I retrieve a Case to get all the Messages that belong to it - this doesn't seem like a good idea because it means every time I look up a Case, I'm making two database calls instead of one.
Use one stored procedure that returns two tables (One containing a single row with information for the Case, one containing zero or more rows with messages that belong to it) and calling two factory methods i.e. CaseFactory.Create(caseDataRow) and a loop that calls MessageFactory.Create(messageDataRow). This makes more sense as the Case is the aggregate root (or pretending to be one as the case may be) so should know how to create messages that hang off of it.
The second option seems better performance but more code. Is there a third option I'm overlooking or is #2 the best way to handle this kind of composite object when I can't use a true ORM (or even something like Linq to SQL)
As it stands, your repositories are more like table gateways (even via sprocs). You'll need a new layer of repositories, which have access to one or more table gateways, and are able to assemble the composite domain entities from the data returned from many tables.
class Customer
{
string name; // etc
Address homeAddress;
Order[] orders;
}
interface ICustomerTableGateway { ... }
interface IAddressTableGateway { ... }
interface IOrderTableGateway { ... }
class CustomerRepository
{
Customer Get(int id)
{
customer = customerTableGateway.Get(id);
customer.Address = addressTableGateway.Get(customer.id);
customer.Orders = orderTableGateway.GetAll(customer.id);
}
}
If you can return multiple tables from the single sproc than that simplifies things further :)