Modeling varying perspectives of an aggregate in Domain Driven Design - nhibernate

In employing Domain Driven design I often encounter an issue regarding the various perspective on a domain object, especially when using NHibernate. Perspectives are essentially ways to view an domain object. For example, a simplified model:
class Transaction
{
string Id { get; set; }
string CustomerName { get; set; }
DateTime Date { get; set; }
decimal Amount { get; set; }
decimal Tax { get; set; }
}
class Batch
{
string Account { get; set; }
string Number { get; set; }
DateTime? ClearDate { get; set; }
IList<Transaction> Transactions { get; }
decimal Total { get; }
}
The total property on the batch is the sum of the amounts on each transaction. When considering a single batch this model works well and is a proper representation of the domain. The client application however has a screen which displays collections of batches. That screen does not require any details about the transactions within a batch, only the total amount. Utilizing the same object on the listing screen is slow. One option is to make the Total property be settable, another option is to create a new class, such as:
class BatchOverview
{
string Number { get; set; }
decimal Total { get; set; }
}
This would have its own repository and its own NHibernate mapping to a database view.
Does this object belong to the domain model, or is it more application/GUI specific?
Should the batch overview object reference the batch object?
Is this a common pattern?
Is there any guidance in relation to this issue?
DDD has the concept of bounded contexts, however in this case the context is the same. Both the Batch class and the BatchOverview class refer to the same 'actual' batch - they are different views, or perspectives on it.

I would keep the new class out of the domain - it is a presentation concern in my book, and i would treat it as such. Normally this new object would be read-only so as not to having two ways of altering data (and one of them not having the full set of business logic contained).
However, you don't have to make a setter for the value just because you use nHibernate. Just make it use a backing field and let nHibernate write to that. (use access="field" in your mapping).
EDIT:
I call it a PresentationModel or ViewModel depending on the amount of logic inside.
I would probably keep a reference to the original object - but might only be an Id.

Related

Best way of modelling a list within a component in NHibernate

Imagine I have a property site which lets you enquire to different estate agents about a given property. Different enquiry methods might have different billing calculations associated with them, and not all agents will have every billing model enabled.
public class EmailEnquiryBillingModel : ValueObject
{
public string EmailAddress { get; set; }
public decimal CostPerEnquiry { get; set; }
}
public enum DayOfWeek
{
Monday,
Tuseday,
// etc.
}
public class OpeningHours : ValueObject
{
public DateTime OpeningTime { get; set; }
public DateTime ClosingTime { get; set;}
}
public class PhoneEnquiryBillingModel : ValueObject
{
public PhoneEnquiryBillingModel()
{
OpeningHours = new Dictionary<DayOfWeek, OpeningHours>();
}
public int PhoneNumber { get; set; }
public IDictionary<DayOfWeek, OpeningHours> OpeningHours { get; set; }
}
public class EstateAgent : Entity
{
public string Name { get; set; }
public EmailEnquiryBillingModel EmailEnquiryBillingModel { get; set; }
public PhoneEnquiryBillingModel PhoneEnquiryBillingModel { get; set; }
}
NHibernate has semantics with components (value objects) whereby if every property in a component is null, the component will also be null.
Therefore, with the appropriate mapping, you can write if(estateAgent.EmailEnquiryBillingModel != null) rather than having to check every individual property of the email enquiry billing model, or whether the model is valid: we either have the model or we don't. It's a simple, elegant way of checking if a particular billing model is enabled.
The problem comes when you have a set within a component, such as with the phone enquiry billing model and the various opening hours. Neither the PhoneEnquiryBillingModel nor the OpeningHours are entities. These are legitimate value objects: we don't care whether the estate agent is open from this 9am on Monday or that 9am on a Monday, just that it opens at 9am on a Monday.
Therefore, this feels like the semantically correct way of representing this domain model in C#.
However, the fact that the PhoneEnquiryBillingModel contains a set (of ProviderOpenHours), and a set cannot be null in NHibernate, only empty, means that ProviderOpenHours will always be non-null, even if the estate agent doesn't meaningfully have that enquiry model enabled. (For more info, see: https://ayende.com/blog/4685/those-are-the-rules-even-when-you-dont-like-them).
This means that you can't do a simple check like if(estateAgent.PhoneEnquiryBillingModel != null), because that object is always not-null.
Therefore, for some billing models you'd be able to do a null check to see if they are enabled, but for other billing models you'd have to find an alternative way of checking, depending on whether those billing models contain a set.
Effectively, you'd need to know the internal structure of a billing model to know if you could do that kind of comparison, which feels like you're breaking encapsulation and changing your domain model based on the rules of the ORM.
Is there a better way of modelling this? Or a way to get NHibernate to serialize in the PhoneEnquiryBillingModel as null, if it doesn't have a phone number or any opening hours?
Therefore, with the appropriate mapping, you can write
if(estateAgent.EmailEnquiryBillingModel != null)
This would not be the best encapsulation in itself.
Instead, you go for:
if (estateAgent.DoesAcceptEmailEnquiries())
and
if (estateAgent.DoesAcceptPhoneEnquiries())
This would give better encapsulation than interrogating properties on the EstageAgent aggregate to make an assumption about the EstateAgent's capabilities. What if you decided to change the implementation of how an EstateAgent stored this information internally? You need to change all clients.
There's nothing particularly bad about an EstateAgent performing individual property checks on its underlying value objects.
However, you could go further and implement a checker method on the PhoneEnquiryBillingModel, perhaps even static to avoid the null check in EstateAgent.
PhoneEnquiryBillingModel
public class PhoneEnquiryBillingModel : ValueObject
{
public PhoneEnquiryBillingModel()
{
OpeningHours = new Dictionary<DayOfWeek, OpeningHours>();
}
public int PhoneNumber { get; set; }
public IDictionary<DayOfWeek, OpeningHours> OpeningHours { get; set; }
public static bool DoesAcceptEnquiries(PhoneEnquiryBillingModel phone)
{
if (phone == null) return false;
if (phone.OpeningHours.Count == 0) return false;
return true;
}
}
Estate Agent
public class EstateAgent : Entity
{
public string Name { get; set; }
public EmailEnquiryBillingModel _emailEnquiryBillingModel { get; set; }
public PhoneEnquiryBillingModel _phoneEnquiryBillingModel { get; set; }
public bool DoesAcceptPhoneEnquiries()
{
return PhoneEnquiryBillingModel.DoesAcceptEnquiries(
_phoneEnquiryBillingModel);
}
}

asp.net web api controllers accept POCO or generic data

I am new with ASP.NET Web API and have been researching this for some time now. Admittedly, I have decision paralysis. I want to make a REST-like API for a system with about 250 tables in the database. It's basically a 2 tier system with a UI and a data access layer, not using business objects or ORM.
I cannot decide if my Web API Controllers should accept/return:
a) IDictionary of name/value pairs, which I would package into sql parameters and pass to the data access layer and return a serialized ado.net data table
b) strongly typed complex object (POCO objects). For example: Account class with all properties matching up with fields in the database.
If I have to create POCO classes for every table in the system, there would be 250+ classes that essentially do nothing except package the data and pass it to our data access layer.
Further, it seems as if I need to create an ApiController for basically every table in the database that I want to expose via the Web Api because you only have GET, POST, PUT, DELETE per route? Please help, banging head on desk.
Please see answers below:
1.**Using **"IDictionary of name/value pairs" is fine if your resource supports GET methods only. If you want users to post or update data, how will you validate the data? In addition, if you want to add HATEOAS, how would you do that? In terms of extension, how would you support nested object hierarchy like the one below:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
public IList<PurchaseDetail> PurchaseHistory { get; set; }
}
public class PurchaseDetail
{
public int Id { get; set; }
public DateTime PurchaseDate { get; set; }
public decimal Cost { get; set; }
}
2. You can have more than one GET, POST,etc per resources by defining different routes. More from this link http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

What is an optimal way to model inheritance in a database with mostly static data?

I'm modelling a role-playing game and need to create the database schema for equipment. The data will be mostly static.
This article discusses three ways to model inheritance in a database: Table per Class Hierarchy, Table per Subclass, and Table per Concrete Class. Of the three, which would you recommend?
I did a sample Entity Framework 4.2 code-first solution to see what it came up with and it used the "Table per Class Hierarchy" method.
Here are the (simplified) classes:
public class Gear {
public int GearID { get; set; }
public string Name { get; set; }
}
public class Armor : Gear {
public int Kinetic { get; set; }
public int Energy { get; set; }
}
public class Weapon : Gear {
public int Damage { get; set; }
public int Range { get; set; }
}
everything has a tradeoff. You need to pick the approach best for you. The downside of per call hierarchy is that the table needs to have all the fields that are on any subclasses, which could mean that some rows in the table are taking up more space than necessary because they don't have some fields. Also, you need a way to discriminate between which type of class to hydrate when loading rows.
On the other hand, per class hierarchy is pretty simple to implement. The other strategies become more attractive the more divergent the data between subclasses is.
You could do name value pairings. Have a table of Gear that has id, name, Attribute1Name, and Attribute1Value. Have as many name/value columns as you need.
So if you were storing an Armor item Attribute1Name would be Kinetic and Attribute1Value would be the value of Kenetic. Attribute2Name would be Energy and Attribute2Value would be the value of Energy.

Fluent nHibernate some kind of flat table

i have one problem (obviously :) )
Is it possible to make dynamic queries in nHibernate in that way...
I have many tables (let we say: User, City, Country, Continet,...) is it possible to flaten this data so i do not need to know joins between this tables (get continent for user, without making join user.city, city.country, coutry.continent)?
The point is i want to some kind flatten data, so user can dynamically select data on user interface without knowing data model behind application?
It will be great that someone gave me at least idea how to make this, or if it's possible...
One example on web is GoogleAnalytics Custom reports (you can drag dimensions and metrics on UI and get results)
You said you're using Fluent NHibernate, which means that, assuming your domain model is structured correctly, you should not need to use any joins.
"Flattening" the data is a UI concern, not a database concern, so you shouldn't flatten your data model or simplify it for the UI unless you absolutely have to.
Let's assume you have the following entities:
public class User
{
public virtual string Name { get; set; }
public virtual City City { get; set; }
}
public class City
{
public virtual string Name { get; set; }
public virtual Country { get; set; }
}
public class Country
{
public virtual string Name { get; set; }
}
If you want to filter users by a certain country, the LINQ query for this (assuming NHibernate 3) would be:
var country = session.Single<Country>(x => x.Name == "Africa");
session.Query<User>().Where(x => x.City.Country == country);

Splitting Out a Table to Improve Performance

my user's table in the database is becoming increasingly larger (in terms of columns not rows) and as a consequence is slowing down various areas of my site. This is because it tries to grab every column from the user's table everytime it does a join against it.
I figured i would keep all the common fields in the user's table and then put the additional fields in seperate tables. For example, say i have the following tables in my database:
Users:
- UserID (PK, Identity)
- UserName
- Password
...
UsersActivity:
- UserID (PK, FK)
- LastActivityDate
- LastLoginDate
...
UsersPreferences:
- UserID (PK, FK)
- HtmlEmail
- HideEmail
...
With the following entities:
public class User {
public virtual int UserID { get; set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual UserActivity Activity { get; set; }
public virtual UserPreferences Preferences { get; set; }
}
public class UserActivity {
public virtual User User { get; set; }
public virtual DateTime LastActivityDate { get; set; }
public virtual DateTime LastLoginDate { get; set; }
}
public class UserPreferences {
public virtual User User { get; set; }
public virtual bool HtmlEmail { get; set; }
public virtual bool HideEmail { get; set; }
}
I was just wondering what is the best way to map this for optimum performance? I figured i could do a one-to-one mapping on the Activity and Performance properties in the User entity. However as far as i understand one-to-one mapping doesn't support lazy loading and this approach would end up being slower.
I also looked into component mapping and wasn't too sure whether i could map this into a seperate table (please correct me if it would be better to keep it in the same table) and whether components supported lazy loading.
Before i go about doing some heavy refactoring of my application i thought i would get the opinion of someone who might have done this. Really appreciate the help.
Thanks
Edit: I found that you could lazy load a one-to-one relationship as long as it is required/constrained. Which it is my case. Therefore i went ahead and carried out the instructions in the following article:
http://brunoreis.com/tech/fluent-nhibernate-hasone-how-implement-one-to-one-relationship/
The trouble now is that i get the error:
NHibernate.Id.IdentifierGenerationException: NHibernate.Id.IdentifierGenerationException: null id generated for: UserActivity.
In NHibernate 3.0 one-to-one relationship supports lazy loading.
And I think that it is better to use Component with combination of Lazy property. Then you will be able to leave all properties in one table and not load them all at once.
You should do some additional application profiling to determine why you're having a performance problem. It's unlikely that it's due to the number of columns in the select list. You probably have an N+1 select problem.
That said, there are many good reasons to use a lightweight object so you might want to look at implementing a DTO (data transfer object) for this.