DTO naming conventions , modeling and inheritance - c#

We are building a web app using AngularJS , C# , ASP.Net Web API and Fluent NHibernate.
We have decided to use DTOs to transfer data to the presentation layer ( angular views).
I had a few doubts regarding the general structuring and naming of DTOs.
Here's an example to illustrate my scenario.
Lets say I have a domain entity called Customer which looks like:
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Address Address { get; set; }
public virtual ICollection<Account> Accounts { get; set; }
}
Now, in my views/presentation layer I need to retrieve different flavors of Customer like :
1) Just Id and Name
2) Id , Name and Address
3) Id , Name , Address and Accounts
I have created a set of DTOs to accomplish this :
public class CustomerEntry
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CustomerWithAddress : CustomerEntry
{
public AddressDetails Address { get; set; }
}
public class CustomerWithAddressAndAccounts : CustomerWithAddress
{
public ICollection<AccountDetails> Accounts { get; set; }
}
AddressDetails and AccountDetails are DTOs which have all the properties of their corresponding Domain entities.
This works fine for querying and data retrievals ; the question is what do I use for inserts and updates. During creation of a new customer record , name and address are mandatory and accounts are optional ..so in other words I need an object with all the customer properties. Hence the confusion :
1) What do I use for insert and updates?
The CustomerWithAddressAndAccounts DTO has everything in it but its name seems a bit awkward to be used for insert/updates.
2) Do I create another DTO .. if I do , wouldn't that be duplication as the new DTO will exactly be like CustomerWithAddressAndAccounts ?
3) Last but not least , does the DTO inheritance strcuture described above seem like a good fit for the requirement ? Are there any other ways to model this ?
I have gone through other posts on this topic but couldn't make much headway.
One thing that I did pickup was to avoid using the suffix "DTO" in the class names.
I think it feels a bit superfluous.
Would love to hear your thoughts
Thanks

Recommendation is that you should just have one DTO class for each entity suffixed with DTO e.g. CustomerEntryDTO for the Customer entity (but you can certainly use inheritance hierarchies as per choice and requirements).
Moreover, Add a abstract DTOBase kind of base class or an interface; and do not use such deep inheritance heirarchies for each Address, Account and other properties to be included in child DTOs. Rather, include these properties in the same CustomerEntryDTO class (if possible) as below:
[Serializable]
public class CustomerEntryDTO : DTOBase, IAddressDetails, IAccountDetails
{
public int Id { get; set; }
public string Name { get; set; }
public AddressDetails Address { get; set; } //Can remain null for some Customers
public ICollection<AccountDetails> Accounts { get; set; } //Can remain null for some Customemer
}
Moreover, your DTOs should be serializable to be passed across process boundaries.
For more on the DTO pattern, refer below articles:
Data Transfer Object
MSDN
Edit:
In case you don't want to send certain properties over the wire (I know you would need to that conditionally so would need to explore more on this), you can exclude them from the Serialization mechanism by using attributes such as NonSerialized (but it works only on fields and not properties, see workaround article for using with properties: NonSerialized on property).
You can also create your own custom attribute such as ExcludeFromSerializationAttribute and apply it to properties you don't want to send every time over wire based on certain rules/conditions. Also see: Conditional xml serialization
Edit 2:
Use interfaces for separating the different properties in the one CustomerEntryDTO class. See the Interface Segregation Principle on Google or MSDN. I will try to put a sample explanation later.

What do I use for insert and updates?
Service operations are usually defined in very close relation to business operations. Business language doesn't speak in terms of "inserts" and "updates", neither do services.
Customer management service is likely to have some Register operation that takes customer name and maybe some other optional parameters.
Do I create another DTO?
Yes, you should create another DTO.
Sometimes service operation contract may be enough and there is no need to define a separate DTO for a particular operation:
function Register(UserName as String, Address as Maybe(of String)) as Response
But most of the time it is better to define a separate DTO class even for only a single service operation:
class RegisterCommand
public UserName as String
public Address as Maybe(of String)
end class
function Register(Command as RegisterCommand) as Response
RegisterCommand DTO may look very similar to CustomerWithAddress DTO because it has the same fields but in fact these 2 DTOs have very different meanings and do not substitute each other.
For example, CustomerWithAddress contains AddressDetails, while a simple String address representation may be enough to register a customer.
Using a separate DTO for each service operation takes more time to write but easier to maintain.

As of your item 1, for inserts and updates it's better to use Command pattern. According to CQRS, you don't need DTOs. Consider this schema:
via blogs.msdn.com

Related

One to many relationship doesn`t retrieve data in entity framework

I`m in process of learning C# & .NET and EF (with aspnetboilerplate) and I came up with idea to create some dummy project so I can practice. But last 4 hour Im stuck with this error and hope someone here can help me.
What I create( well at least I think I create it correctly ) is 2 class called "Ingredient" and "Master"
I want to use it for categorize Ingredient with "Master" class.
For example ingredient like
Chicken breast
chicken drumstick
Both of them belong to Meat ( witch is input in "Master" database ) and here is my code
Ingredient.cs
public class Ingrident : Entity
{
public string Name { get; set; }
public Master Master { get; set; }
public int MasterId { get; set; }
}
Master.cs
public class Master : Entity
{
public string Name { get; set; }
public List<Ingrident> Ingridents { get; set; } = new();
}
IngridientAppService.cs
public List<IngridientDto> GetIngWithParent()
{
var result = _ingRepository.GetAllIncluding(x => x.Master);
//Also I try this but doesn`t work
// var result = _ingRepository.GetAll().Where(x => x.MasterId == x.Master.Id);
return ObjectMapper.Map<List<IngridientDto>>(result);
}
IngridientDto.cs
[AutoMap(typeof(IndexIngrident.Entities.Ingrident))]
public class IngridientDto : EntityDto
{
public string Name { get; set; }
public List<MasterDto> Master { get; set; }
public int MasterId { get; set; }
}
MasterDto.cs
[AutoMap(typeof(IndexIngrident.Entities.Master))]
public class MasterDto : EntityDto
{
public string Name { get; set; }
}
When I created ( for last practice ) M -> M relationship this approach with .getAllIncluding work but now when I have One -> Many it won`t work.
Hope someone will be able to help me or at least give me some good hint.
Have a nice day !
Straight up the examples you are probably referring to (regarding the repository etc.) are overcomplicated and for most cases, not what you'd want to implement.
The first issue I see is that while your entities are set up for a 1-to-many relationship from Master to Ingredients, your DTOs are set up from Ingredient to Masters which definitely won't map properly.
Start with the simplest thing. Get rid of the Repository and get rid of the DTOs. I'm not sure what the base class "Entity" does, but I'm guessing it exposes a common key property called "Id". For starters I'd probably ditch that as well. When it comes to primary keys there are typically two naming approaches, every table uses a PK called "Id", or each table uses a PK with the TableName suffixed with "Id". I.e. "Id" vs. "IngredientId". Personally I find the second option makes it very clear when pairing FKs and PKs given they'd have the same name.
When it comes to representing relationships through navigation properties one important detail is ensuring navigation properties are linked to their respective FK properties if present, or better, use shadow properties for the FKs.
For example with your Ingredient table, getting rid of the Entity base class:
[Table("Ingredients")]
public class Ingredient : Entity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IngredientId { get; set; }
public string Name { get; set; }
public int MasterId { get; set; }
[ForeignKey("MasterId")]
public virtual Master Master { get; set; }
}
This example uses EF attributes to aid in telling EF how to resolve the entity properties to respective tables and columns, as well as the relationship between Ingredient and Master. EF can work much of this out by convention, but it's good to understand and apply it explicitly because eventually you will come across situations where convention doesn't work as you expect.
Identifying the (Primary)Key and indicating it is an Identity column also tells EF to expect that the database will populate the PK automatically. (Highly recommended)
On the Master side we do something similar:
[Table("Masters")]
public class Master : Entity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int MasterId { get; set; }
public string Name { get; set; }
[InverseProperty("Master")]
public virtual ICollection<Ingredient> Ingredients { get; set; } = new List<Ingredient>();
}
Again we denote the Primary Key, and for our Ingredients collection, we tell EF what property on the other side (Ingredient) it should use to associate to this Master's list of Ingredients using the InverseProperty attribute.
Attributes are just one option to set up the relationships etc. The other options are to use configuration classes that implement IEntityConfiguration<TEntity> (EF Core), or to configure them as part of the OnModelCreating event in the DbContext. That last option I would only recommend for very small projects as it can start to become a bit of a God method quickly. You can split it up into calls to various private methods, but you may as well just use IEntityConfiguration classes then.
Now when you go to fetch Ingredients with it's Master, or a Master with its Ingredients:
using (var context = new AppDbContext())
{
var ingredients = context.Ingredients
.Include(x => x.Master)
.Where(x => x.Master.Name.Contains("chicken"))
.ToList();
// or
var masters = context.Master
.Include(x => x.Ingredients)
.Where(x => x.Name.Contains("chicken"))
.ToList();
// ...
}
Repository patterns are a more advanced concept that have a few good reasons to implement, but for the most part they are not necessary and an anti-pattern within EF implementations. I consider Generic repositories to always be an anti-pattern for EF implementations. I.e. Repository<Ingredient> The main reason not to use repositories, especially Generic repositories with EF is that you are automatically increasing the complexity of your implementation and/or crippling the capabilities that EF can bring to your solution. As you see from working with your example, simply getting across an eager load through to the repository means writing in complex Expression<Func<TEntity>> parameters, and that just covers eager loading. Supporting projection, pagination, sorting, etc. adds even more boiler-plate complexity or limits your solution and performance without these capabilities that EF can provide out of the box.
Some good reasons to consider studying up on repository implementations /w EF:
Facilitate unit testing. (Repositories are easier to mock than DbContexts/DbSets)
Centralizing low-level data rules such as tenancy, soft deletes, and authorization.
Some bad (albeit very common) reasons to consider repositories:
Abstracting code from references or knowledge of the dependency on EF.
Abstracting the code so that EF could be substituted out.
Projecting to DTOs or ViewModels is an important aspect to building efficient and secure solutions with EF. It's not clear what "ObjectMapper" is, whether it is an Automapper Mapper instance or something else. I would highly recommend starting to grasp projection by using Linq's Select syntax to fill in a desired DTO from the models. The first key difference when using Projection properly is that when you project an object graph, you do not need to worry about eager loading related entities. Any related entity / property referenced in your projection (Select) will automatically be loaded as necessary. Later, if you want to leverage a tool like Automapper to help remove the clutter of Select statements, you will want to configure your mapping configuration then use Automapper's ProjectTo method rather than Map. ProjectTo works with EF's IQueryable implementation to resolve your mapping down to the SQL just like Select does, where Map would need to return everything eager loaded in order to populate related data. ProjectTo and Select can result in more efficient queries that can better take advantage of indexing than Eager Loading entire object graphs. (Less data over the wire between database and server/app) Map is still very useful such as scenarios where you want to copy values back from a DTO into a loaded entity.
Do it like this
public class Ingrident:Entity
{
public string Name { get; set; }
[ForeignKey(nameof(MasterId))]
public Master Master { get; set; }
public int MasterId { get; set; }
}

Specification Pattern with Navigation Properties

Is it correct to use Specification Pattern with Navigation Properties ?
I have the follow context:
When I add a student, I need to validate the addresses.
Student class:
public class Student {
public string Name { get; set; }
public DateTime Birth { get; set; }
//...
public virtual ICollection<StudentAddress> StudentAdresses { get; set; }
}
StudentAddress class:
public class StudentAdress{
public int Id { get; set;}
public string Street { get; set; }
//...
}
On my student service (DDD):
Service:
public void AddStudent(Student student)
{
// code
var studentValidation = new StudentValidation().Validate(student); // Student Validation has a set of specifications that will populate a validation result object and that I'll retrieve it by Domain Controller Notification (MVC)
// code
}
PS: Student Validation has a set of specifications that will populate a validation result object and that I'll retrieve it by Domain Controller Notification (MVC)
Back to the question...
Where may I put my Student Addresses class specifications ?
I thought of the possibility of putting them inside StudentValidation class and there use the Navigation property to be able to validate each address. I do not know if that is correct. It would be a type of transversal validation.
In DDD, validation is a form of ensuring invariants are met. This is the responsibility of the Aggregate Root in an Aggregate. In your example, perhaps Student is the root of the Student Aggregate, with StudentAddress as a child. In that case, it makes sense for Student to be responsible for ensuring the aggregate is in a valid state. Ideally, the logic for this should literally live inside of the Student class itself, but in your case you appear to be using a StudentService to perform validation of Student. So, in your case, it would be fine and proper (IMO) to perform the address validation from StudentService, since it's essentially taking on the responsibility of your aggregate root.
Whether or not you need separate validator types for StudentAddress than for Student depends on the context/scope of the validation rule in question. For example, if you must validate that an Address includes a City, that's easily done at the StudentAddress level. However, if you need to validate that a Student has at least one Address, or that a Student doesn't have two duplicate Addresses, that would need to be done at the Student level.
You can learn more about DDD in general here.

Use AutoMapper to map two VM to one Entity object

I'm using AutoMapper to map a lot of Entity models to View Model that I use in my controllers and views (.Net MVC)
There is a lot of relations in the DB and so our VM have a lot of childs (who have childs, and so and so)
public class InvoiceVMFull : VMBase
{
public int Id { get; set; }
public InvoiceType InvoiceType { get; set; }
public string Reference { get; set; }
//.... shortened code for readability
// list all entity fields
public List<string> InvoiceMainAddress { get; set; }
public List<string> InvoiceDlvAddress { get; set; }
}
It works just fine, but is very slow and always load from the DB all relations whereas I usually need only a few datas...
So I created some light VM that I want to use for the majority of our pages.
public class InvoiceVMLite : VMBase
{
public int Id { get; set; }
public string Reference { get; set; }
//.... shortened code for readability
// list only some of the entity fields (most used)
public StoredFileVM InvoiceFile { get; set; }
}
The problem is I can't find how :
to map one Entity object to the two VMs and how to choose the right one (to load from DB) using the context (the page or event called)
to map two VMs to one entity and save (on the DB) only the fields that are present in the VM used and don't erase the absent ones
I tried to create the mapping both VM :
Mapper.CreateMap<Invoice, InvoiceVMLite>();
Mapper.CreateMap<Invoice, InvoiceVMFull>();
But when I try to call the mapping for Lite, it doesn't exist (have been overridden by Full) :
Mapper.Map(invoice, InvoiceEntity, InvoiceVMLite)
Correct Use of Map function
It looks like you are calling map incorrectly. Try these instead
var vmLite = Mapper.Map<Invoice, InvoiceVMLite>(invoice);
var vmFull = Mapper.Map<Invoice, InvoiceVMFull>(invoice);
var vmLite = Mapper.Map(invoice); // would work if it were not ambiguous what the destination was based on the input.
Entity to two view models
You would usually create two mappings, one for each view model from the one entity. I'd suggest the cleanest is to have two separate views (separate Actions in a controller) for each view model. This may involve a quick redirect after you've decided on context which one to use.
View models to entity
Automapper is not meant for mapping from view models to Entities for many reasons, including the challenge you'd face. Instead you would pass specific parameters. The author of Automapper, Jimmy Bogard, wrote a good article on why this is the case.
I couldnt manage to do that with AutoMapper, and so I created my own convert methods (Entity <=> VM) with a lot of reflexivity, and with specific cases handled in each of the VM classes.
Now I can easily get a full or lite VM from an Entity, and also specify the depth in relation I want to go. So it's A LOT faster and more adaptable than AutoMapper
And I can save a VM to an entity (only saving modified fields if I want) that I create or that i got from base. So it's A LOT faster and adaptable than AutoMapper
In conclusion : Don't use autoMapper, it seem easy but create so many performance issues that it isn't worth it

Domain Design crossing Aggregate Root Boundaries

I'm a novice DDD'er and struggling with my first attempt to implement some of these concepts. I am writing an application to manage some marketing campaigns for different users, so a Campaign is an obvious aggregate root, but I also have Users as an aggregate root.
public class Campaign : IDomainObject
{
public virtual int CampaignId { get; set; }
public virtual string Name { get; set; }
...
public virtual int UserId { get; set; }
...
public virtual IList<CampaignEvent> Events { get; set; }
}
public class CampaignEvent
{
public virtual int CampaignEventId { get; set; }
public virtual int CampaignId { get; set; }
public virtual int UserId { get; set; }
...
}
So now when I search for a list of campaigns to display, how do I get the User's name from the Id?
If I design the model with a database-agnostic perspective, I would add a UserName string to both objects and develop from there. However, I have to be practical and consider how this will eventually go back-and-forth to the database, and it doesn't appear that this new model will work with the ORM (presently NHibernate, but I don't believe this is possible with EF either).
What are some meet-in-the-middle solutions that will accomplish the goal of getting some user information available in the object, without compromising the concepts of DDD?
I think the key here is that you want to change the thought process to entity to entity or value object relationships.
In the way you are modeling your classes, you have a UserId as a property and are talking about it as if it was a relationship. I think what you are wanting to convey is a relationship between the Campaign and a User, a CampaignEvent and a User, etc. It is perfectly acceptable for a Campaign to be an Aggregate Root and a User to be an Aggregate Root. When you search for a campaign, it will have a relationship to a User, so how you get the name is by getting the Name from the User entity. We don't want to speak about Id's alone, as this breaks our representation of the real entity we are trying to model. So a campaign has a/a collection user/users, and a user has a/a collection of campaign/campaigns, as opposed to a campaign has a userid.
If you would like to display the user name from some result set that you got from your ORM/domain model then this is a somewhat of a problem. You should not query your domain model. So how to do it then?
Well, you should try to incorporate a query/read model. A very simple query layer should be developed. To get the data, you have a couple of options. You probably want to opt for some denormalisation along the way. You could add the user id and name as a value object to your aggregate so that it is stored in your transactional store. Your query would be able to access that and have the data readily available; else your query side would need to do a join.
You could also go with eventual consistency via a truly read-specific store that contains view-specific tables.
This approach will probably bring up some more questions but it really is not as cumbersome as it may appear.

Entity Framework - Multiple Project support

I am looking into migrate a large project to Entity Framework 4.0 but am not sure if it can handle my inheritance scenario.
I have several projects that inherit from an object in the “main” project. Here is a sample base class:
namespace People
{
public class Person
{
public int age { get; set; }
public String firstName { get; set; }
public String lastName { get; set; }
}
}
and one of the sub-classes:
namespace People.LawEnforcement
{
public class PoliceOfficer : People.Person
{
public string badgeNumber { get; set; }
public string precinct { get; set; }
}
}
And this is what the project layout looks like:
People - People.Education - People.LawEnforcement http://img51.imageshack.us/img51/7293/efdemo.png
Some customers of the application will use classes from the People.LawEnforcement and other users will use People.Education and some will use both. I only ship the assembles that the users will need. So the Assembles act somewhat like plug-ins in that they add features to the core app.
Is there anyway in Entity Framework to support this scenario?
Based on this SO question I'm think something like this might work:
ctx.MetadataWorkspace.LoadFromAssembly(typeof(PoliceOfficer).Assembly);
But even if that works then it seams as if my EDMX file will need to know about all the projects. I would rather have each project contain the metadata for the classes in that project but I'm not sure if that is possible.
If this isn't possible with entity framework is there another solution (NHibernate, Active Record, etc.) that would work?
Yes this is possible, using the LoadFromAssembly(..) method you've already found.
... but it will only work if you have an specialized model (i.e. EDMX) for each distinct type of client application.
This is because EF (and most other ORMs) require a class for each entity in the model, so if some clients don't know about some classes, you will need a model without the corresponding entities -- i.e. a customized EDMX for each scenario.
To make it easier to create a new model for each client application, if I was you I'd use Code-Only following the best practices laid out on my blog, to make it easy to grab only the fragments of the model you need actually need.
Hope this helps
Alex
Alex is correct (+1), but I'd strongly urge you to reconsider your model. In the real world, a police officer is not a subtype of a person. Rather, it's an attribute of that person's employment. I think programmers frequently tend to over-emphasize inheritance at the expense of composition in object oriented design, but it's especially problematic in O/R mapping. Remember that an object instance can only ever have one type. When that object is stored in the database, the instance can only have that type for as long as it exists, across multiple application sessions. What if a person had two jobs, as a police officer and a teacher? Perhaps that scenario is unlikely, but the general problem is more common than you might expect.
More relevant to your question, I think you can solve your actual problem at hand by making your mapped entity model more generic, and your application-specific data projections on the entities rather than entities themselves. Consider entities like:
public class JobType
{
public Guid Id { get; set; }
// ...
}
public class Job
{
public JobType JobType { get; set; }
public string EmployeeNumber { get; set; }
}
public class Person
{
public EntityCollection<Job> Jobs { get; set; }
}
Now your law enforcement app can do:
var po = from p in Context.People
let poJob = p.Jobs.Where(j => j.JobType == JobType.PoliceOfficerId).FirstOrDefault()
where poJob != null
select new PoliceOfficer
{
Id = p.Id,
BadgeNumber = poJob.EmployeeNumber
};
Where PoliceOfficer is just a POCO, not a mapped entity of any kind.
And with that you've achieved your goal of having a common data model, but having the "job type specific" elements in separate projects.

Categories