Carpool Project: Part #9

I started with the View a bit more and I ran into an issue that cuts to the heart of D3 and SOC. On my Carpool page, I want a grid of all practices that are associated with the car pool (usually 1, but could be more). In the view, I wrote this (headers omitted for brevity):

1 <% foreach (Com.Tff.Carpool.Domain.Practice practice in Model.Practices) 2 { %> 3 <tr> 4 <td> 5 <%: practice.Id%> 6 </td> 7 <td> 8 <%: practice.Date%> 9 </td> 10 <td> 11 <%: practice.DryLandIndicator%> 12 </td> 13 <td> 14 <%: practice.EndTime%> 15 </td> 16 <td> 17 <%: practice.StartTime%> 18 </td> 19 <td> 20 <% foreach (Com.Tff.Carpool.Domain.SwimGroup swimGroup in practice.SwimGroups) 21 { %> 22 <%: swimGroup.Name%> 23 <% } %> 24 </td> 25 <td> 26 <%: Html.ActionLink("Edit", "Edit", new { practiceId = practice.Id })%> 27 <%: Html.ActionLink("Delete", "Delete", new { PracticeId = practice.Id })%> 28 </td> 29 </tr> 30 31 <% } %> 32  

And it comes out with the expected HTML:

carpool32

Notice how the Swim Group is joined together using that secondary loop. This got me thinking, part of the reason I crated the ViewModel POCOs was to do this kind of flattening. If the UI can handle it easily, why not use EF-enabled POCOs and save the who Domain Layer step of mapping the EF Classes to the POCO ones? If all I had to worry about was the flattening of Swim Groups to practices, perhaps writing that join in the UI is better than the Domain Layer. Then I thought – NO. The domain layer should be responsible for serving objects, even if the UI can handle it. I would say that is analogous to “we can put the code in the code-behind in Web Forms.” Eventually, the code needs to be written – so I would rather have it in the Domain layer where I have exact control and can add in any custom logic. If any custom logic for the flattening happens, the UI will quickly become a morass of spaghetti. On a side note, I find writing C# is much much better than writing WebForms View Engine code – those gators drive me nuts.

Saying that, I realized I don’t need a carpool controller, I need a CarpoolSummary controller and view -> for the simple reason that Carpools don’t have PracticeSummaries – CarpoolSummaries do. Time to do some re-writing!

Carpool Project: Part #8

I am working on the Update features of the Carpool Factory. The biggest problem with using POCOs that are not automatically hooked up with EF classes is that you have to do the mapping back to the EF classes. Going from EF to POCO is straight forward – putting them back in is a different story.

I had 3 different challenges

#1) Assign properties to the main class. That was straight forward:

1 private static void MapCarpool_Carpool(Carpool_Carpool carpool_carpool, Carpool carpool) 2 { 3 carpool_carpool.CarPoolDate = carpool.Date; 4 carpool_carpool.SwimmerCapacity = carpool.SwimerCapacity; 5 carpool_carpool.TimeBack = carpool.ReturnTime; 6 carpool_carpool.TimeLeaving = carpool.LeaveTime; 7 } 8  

#2) Assign properties to another one-to-one class in the graph. The was also straight forward, with the caveat that you need to use the same EF conext for the entire graph so you need to pass that into the function:

1 private static void MapCarpool_CarpoolDriver(Carpool_Carpool carpool_carpool, Carpool carpool, CarpoolEntities carpoolEntity) 2 { 3 var selectedDriver = (from driver in carpoolEntity.Carpool_Driver 4 where driver.DriverID == carpool.Driver.Id 5 select driver).First(); 6 carpool_carpool.Carpool_Driver = selectedDriver; 7 } 8

#3) Assign properties to a collection of one-to-many classes in the graph. I tried a couple of different ways to do this with the least amount of code. The problem is that the collection could have had adds and deletes on the client that need to be synched up to the server:

Client   Server
    SwimmerA
SwimmerB   SwimmerB
SwimmerC   SwimmerC
SwimmerD    

My first thought was to clear the EF Collection and then then add in the POCOs like so:

1 carpoolToUpdate.Carpool_CarpoolPractice.Clear(); 2 3 Carpool_CarpoolPractice carpool_carpoolPractice = null; 4 5 foreach (Practice practice in carpool.Practices) 6 { 7 carpool_carpoolPractice = new Carpool_CarpoolPractice(); 8 carpool_carpoolPractice.CarpoolId = carpool.Id; 9 carpool_carpoolPractice.PracticeId = practice.Id; 10 carpoolToUpdate.Carpool_CarpoolPractice.Add(carpool_carpoolPractice); 11 } 12

 

The problem is that I could not clear the collection b/c of a referential constraint, even though I immediately re-added new objects before the Update method to the server.

1System.InvalidOperationException was unhandled by user code 2 Message=The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted. 3 Source=System.Data.Entity 4

Some digging found this article which explained why.

So then I thought to enumerate though the collection and remove each one and then the POCOs in. A couple more lines of code but that did the trick for adding the practice. Here is the code:

1 //Remove 2 foreach (Carpool_CarpoolPractice carpool_carpoolPracticeToDelete in carpoolEntity.Carpool_CarpoolPractice) 3 { 4 carpoolEntity.DeleteObject(carpool_carpoolPracticeToDelete); 5 } 6 7 //Add 8 Carpool_CarpoolPractice carpool_carpoolPracticeToAdd = null; 9 foreach (Practice practice in carpool.Practices) 10 { 11 carpool_carpoolPracticeToAdd = new Carpool_CarpoolPractice(); 12 carpool_carpoolPracticeToAdd.CarpoolId = carpool.Id; 13 carpool_carpoolPracticeToAdd.PracticeId = practice.Id; 14 carpoolToUpdate.Carpool_CarpoolPractice.Add(carpool_carpoolPracticeToAdd); 15 } 16

And here is the test:

1 [TestMethod()] 2 public void AddCarpoolPracticeTest() 3 { 4 Carpool carpool = CarpoolFactory.GetCarpool(1); 5 int notExpcted = carpool.Practices.Count; 6 7 Practice practice = PracticeFactory.GetPractice(2); 8 carpool.Practices.Add(practice); 9 CarpoolFactory.UpdateCarpool(carpool); 10 11 carpool = CarpoolFactory.GetCarpool(1); 12 int actual = carpool.Practices.Count; 13 14 Assert.AreNotEqual(notExpcted, actual); 15 } 16

 

The problem is the removal of the practice. I wrote this test:

1 [TestMethod] 2 public void DeleteCarpoolPracticeTest() 3 { 4 Carpool carpool = CarpoolFactory.GetCarpool(1); 5 int notExpcted = carpool.Practices.Count; 6 7 Practice practice = PracticeFactory.GetPractice(2); 8 carpool.Practices.Remove(practice); 9 10 CarpoolFactory.UpdateCarpool(carpool); 11 12 carpool = CarpoolFactory.GetCarpool(1); 13 int actual = carpool.Practices.Count; 14 15 Assert.AreNotEqual(notExpcted, actual); 16 } 17

 

And got the following fail:

carpool29

I need to add a comparable to the practice so that the remove recognize practices with the same PracticeId as the same.

1 public class Practice : ValidationBase, IEquatable<Practice> 2 { 3 public int Id { get; set; } 4 public DateTime Date { get; set; } 5 public DateTime StartTime { get; set; } 6 public DateTime EndTime { get; set; } 7 public bool DryLandIndicator { get; set; } 8 public List<SwimGroup> SwimGroups { get; set; } 9 10 public bool Equals(Practice other) 11 { 12 if (other.Id == this.Id) 13 return true; 14 else 15 return false; 16 17 } 18 } 19

 

And then the remove worked like a champ. This led me to my next (and last of the morning) thought – should I implement IEquiatable on the base abstract class (Validation Base) since all of the derived classes have a PK. If so, how would I implement that? I’ll do some research. Until then, my Carpool class now looks like it is ready for Updates. Unfortunately, looks are deceiving…

I started making my UI a bit more user-friendly. I put on a jQuery date picker for the carpool start date. I verified that the new date was being passed into the controller via the FormCollection (it was), but then the UpdateModel is reverting the change:

carpool30

And

carpool31

Oddly, the Update work for date/time values. I guess it cannot handle having a date without a time. I added a new line of code to handle this case:

1 try 2 { 3 Carpool.Domain.Carpool carpool = CarpoolFactory.GetCarpool(carpoolId); 4 UpdateModel(carpool); 5 carpool.Date = DateTime.Parse(collection[2].ToString()); 6 CarpoolFactory.UpdateCarpool(carpool); 7 return RedirectToAction("Index"); 8 } 9

 

Yuck, but it is the easiest way. Perhaps in the UI I can format the input?

Carpool Project: Part #6

I finished the factories and the POCOs. I made some changes that simplified the model some – I set up 7 factories for the non-flattened POCOs and 1 factory for a flattened POCO:

carpool21

I will see if the other flattened POCOs are needed. With enough factories to make me dangerous, I then thought about how to organize the UI. Since this exercise is to help me work though the Architectual features of VS2010, I created an activity diagram based on some of the Use Cases:

carpool22

Note how I started documenting business rules. I went back to the Task list for each activity and added both the data elements and the business rules:

carpool23 

I then have enough to launch a tracer bullet that matches how I want the home page to be. The challenge is that the home page will actually show 2 independent grids that use different data elements:

· A list of all practices without a carpool

· A list of all carpools

I don’t know the best way to implement this in MVC. In prior projects, I had 1 controller for the page that handles the “primary” data elements and then some AJAX calls to dynamically populate the remaining grids. Another possible way is to have the page be a composite of 2 independent User Controls. A final way is to have the page controller’s model collection just include both data element sets and refer to each in the collection.

I had already tried Option #1 on a different project and found that it requires too much JavaScript code. I then explored Option #2. I set up my MVC’s project controllers to match the domain model like so:

carpool24

I then tried to wire up some User Controls for each of the controllers that I could then combine on the Default page. I quickly learned that MVC2 User Controls Are not well supported in the MVC community (30 minutes of Bing/Google/MSDN searches did not give me a specific example of MVC2 User Controls tied together in 1 page). I also realized that I was taking a “bottom-up” approach.

I then revamped my project to take a “top-down” approach. Incidentally, this option seems to be the “happy path” for MVC2. I removed all of the POCO controllers:

carpool25

And then added the POCOs that I want on the main page to the ViewModel Collection:

1 public ActionResult Index() 2 { 3 ViewData["Message"] = "Welcome to ASP.NET MVC!"; 4 ViewData["CurrentCarpoolSummaries"] = CarpoolSummaryFactory.GetCurrentWeekCarpoolSummaries(); 5 ViewData["UncoveredPraciceSummaries"] = PracticeSummaryFactory.GetCurrentWekUncoveredPracticeSummaries(); 6 7 return View(); 8 } 9  

And then wired up the UI:

1 <table> 2 <tr> 3 <th> 4 Id 5 </th> 6 <th> 7 Day 8 </th> 9 <th> 10 Date 11 </th> 12 <th> 13 Description 14 </th> 15 <th> 16 Pracitce(s) 17 </th> 18 <th> 19 Driver 20 </th> 21 <th> 22 Swimmer(s) 23 </th> 24 <th> 25 Remaining Seats 26 </th> 27 </tr> 28 29 <% foreach (Com.Tff.Carpool.Domain.CarpoolSummary carpoolSummary in ViewData["CurrentCarpoolSummaries"]) 30 { %> 31 32 <tr> 33 <td> 34 <%: carpoolSummary.Id%> 35 </td> 36 <td> 37 <%: carpoolSummary.DayDescription%> 38 </td> 39 <td> 40 <%: carpoolSummary.CarpoolDate%> 41 </td> 42 <td> 43 <%: carpoolSummary.CarpoolDescription%> 44 </td> 45 <td> 46 <%: carpoolSummary.PracticeDescription%> 47 </td> 48 <td> 49 <%: carpoolSummary.DriverDescription%> 50 </td> 51 <td> 52 <%: carpoolSummary.SwimmerDescription%> 53 </td> 54 <td> 55 <%: carpoolSummary.RemainingSeats%> 56 </td> 57 </tr> 58 59 <% } %> 60 </table> 61  

I ran into this problem:

carpool26

It looks like I need to cast it via the page Inherits method – but I have multiple datasets. I tried ignoring the error – hoping that the object resolves at run time. No such luck:

carpool27

So I went back and casted the model into the proper type:

1 <% foreach (Com.Tff.Carpool.Domain.CarpoolSummary carpoolSummary in (System.Collections.Generic.List<Com.Tff.Carpool.Domain.CarpoolSummary>)ViewData["CurrentCarpoolSummaries"])

And

1 <% foreach (Com.Tff.Carpool.Domain.PracticeSummary uncoveredPracticeSummaries in (System.Collections.Generic.List<Com.Tff.Carpool.Domain.PracticeSummary>)ViewData["UncoveredPraciceSummaries"])

And boom goes the dynamite…

carpool28

Carpool Project: Part #5

I am now building factories for my POCOs. I have a design question. Should POCOs hold the key to another object or an actual reference? DDD says that I should a reference and EF does that, but POCOs do not seem to pattern that way.

The choice is this:

1 public class Swimmer : ValidationBase 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public SwimGroup SwimGroup { get; set; } 6 } 7  

or this (flattened class):

1 public class Swimmer : ValidationBase 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public int SwimGroupId { get; set; } 6 public string SwimGroupName { get; set; } 7 } 8  

I see the benefits to both sides. On one hand, the flattened class (option #2) makes it very easy to code up the UI. On the other hand, option #2 is much more rigid and brittle – you can have lots of properties and a change to 1 entity class means that every value object that depends on the entity object has to change. You can add interfaces for each of the permutations of the flattened classes to account for change, but that becomes unwieldy.

After going back and forth a couple of times, I settled on doing both. I left my base class (Swimmer) as option #1 and then build a SwimmerSummary class that is option #2. With both, I will see what is easier to work with on the UI.

Starting on Option #1, I created a Swimmer Factory with a mapper function like this:

Carpool17

The problem is that the SwimGroup reference is expected my Domain-Defined class, not the EF class. I need to wire up a factory for the SwimGroup and pass a Domain-Driven class like this:

1 Swimmer swimmer = new Swimmer { 2 Id = carpool_swimmer.SwimmerId, 3 Name = carpool_swimmer.SwimmerName}; 4 5 SwimGroupFactory swimGroupFactory = new SwimGroupFactory(); 6 swimmer.SwimGroup = swimGroupFactory.GetSwimGroup(carpool_swimmer.Carpool_SwimGroup.SwimGroupId); 7 8 return swimmer; 9  

Which leads me to my next problem – how to get both the Swimmer and the SwimGroup in the same database call? As this is written, each factory has a unique reference to the EF class, so getting the swimmer and his/her SwimGroup means 2 round trips. I can put them all into a single call (Unit of work) by using the include statement, but then I will need to change the factory to do the mapping WITHOUT the database call.

I started implanting this, but then I ran into references two deep – Swimmer needs SwimGroup which needs SwimTeam – so the SwimmerFactory has to know to call for SwimGroup and SwimTeam in it’s EF call. I wonder if there are guidelines about how deep to make the references?

So I have this:

1 public static SwimGroup MapSwimGroup(Carpool_SwimGroup carpool_swimgroup) 2 { 3 SwimGroup swimGroup = new SwimGroup { 4 Id = carpool_swimgroup.SwimGroupId, 5 Name = carpool_swimgroup.SwimGroupName, 6 SwimTeam = SwimTeamFactory.MapSwimTeam(carpool_swimgroup.Carpool_SwimTeam) }; 7 8 return swimGroup; 9 } 10  

and this:

1 public static Swimmer MapSwimmer(Carpool_Swimmer carpool_swimmer) 2 { 3 Swimmer swimmer = new Swimmer { 4 Id = carpool_swimmer.SwimmerId, 5 Name = carpool_swimmer.SwimmerName, 6 SwimGroup = SwimGroupFactory.MapSwimGroup(carpool_swimmer.Carpool_SwimGroup) }; 7 8 return swimmer; 9  

and then a EF call that does this:

1 public Swimmer GetSwimmer(int swimmerId) 2 { 3 var selectedSwimmer = (from swimmer in carpoolEntity.Carpool_Swimmer 4 .Include("Carpool_SwimGroup") 5 .Include("Carpool_SwimGroup.Carpool_SwimTeam") 6 where swimmer.SwimmerId == swimmerId 7 select swimmer).First(); 8 9 return MapSwimmer(selectedSwimmer); 10 } 11  

The 2 things I need to be mindful of are:

· No intellisense on the include statement – so the name has to match

· I need to check for null in the mapping in case the calling function forgets the include statement. My mapping cannot handle lazy loading.

This got me thinking about the Factory pattern in general. My Factory class is actually a plant with 2 factories. Factory 1 maps EF classes to POCO classes. Factory 2 class calls EF and returns POCOs. I wonder if I need to divide these 2 functions into separate classes? The examples of the repository pattern that I have seen keep them together – but I have only seen them in a “hello nerd dinner” context.

I then thought harder about the subject and realized that I missing the point of the factory. Conceptually, I picture a window with Alot behind it. I can either hand him an int or a EF class. No matter what I pass in, I get a POCO class out. In this sense, the factory spits out POCOs and I can use overloaded parameters to handle the different permutations that come in. The factory class then looks like this:

1 public class SwimGroupFactory 2 { 3 CarpoolEntities carpoolEntity = null; 4 5 public SwimGroupFactory() 6 { 7 carpoolEntity = new CarpoolEntities(); 8 } 9 10 public SwimGroup GetSwimGroup(int swimGroupId) 11 { 12 var selectedSwimGroup = (from swimGroup in carpoolEntity.Carpool_SwimGroup 13 where swimGroup.SwimGroupId == swimGroupId 14 select swimGroup).First(); 15 return MapSwimGroup(selectedSwimGroup); 16 } 17 18 public SwimGroup GetSwimGroup(Carpool_SwimGroup carpool_swimgroup) 19 { 20 return MapSwimGroup(carpool_swimgroup); 21 } 22 23 24 private static SwimGroup MapSwimGroup(Carpool_SwimGroup carpool_swimgroup) 25 { 26 SwimGroup swimGroup = new SwimGroup { 27 Id = carpool_swimgroup.SwimGroupId, 28 Name = carpool_swimgroup.SwimGroupName, 29 SwimTeam = SwimTeamFactory.MapSwimTeam(carpool_swimgroup.Carpool_SwimTeam) }; 30 31 return swimGroup; 32 } 33 } 34  

Which is great – but then the new class uses a new EF. I have 2 EF classes, though only 1 is used for an active connection. Perhaps the EF class should be moved from the constructor and placed in the methods that actually use it…

So I refactored and got all green – making my factories static and overloaded methods passing in ints or EF classes. For ints, the methods created a new EF context and queries the db. For EF classes, it just maps and send back…

For example:

1 public static SwimGroup GetSwimGroup(int swimGroupId) 2 { 3 using (CarpoolEntities carpoolEntity = new CarpoolEntities()) 4 { 5 var selectedSwimGroup = (from swimGroup in carpoolEntity.Carpool_SwimGroup 6 where swimGroup.SwimGroupId == swimGroupId 7 select swimGroup).First(); 8 return MapSwimGroup(selectedSwimGroup); 9 } 10 } 11 12 public static SwimGroup GetSwimGroup(Carpool_SwimGroup carpool_swimgroup) 13 { 14 return MapSwimGroup(carpool_swimgroup); 15 } 16 17 private static SwimGroup MapSwimGroup(Carpool_SwimGroup carpool_swimgroup) 18 { 19 SwimGroup swimGroup = new SwimGroup { 20 Id = carpool_swimgroup.SwimGroupId, 21 Name = carpool_swimgroup.SwimGroupName, 22 SwimTeam = SwimTeamFactory.GetSwimTeam(carpool_swimgroup.Carpool_SwimTeam) }; 23 24 return swimGroup; 25 } 26 } 27  

I then used this pattern for the rest of my factories…

Carpool Project: Part #3

My first question was “where do I put the POCOs?” I can put them in the Models folder in the MVC solution – there is already a ChangePassword, Logon, and Register Model there. They are all POCOs with some validation attributes added.

However, those Models only exist in context of the MVC application – they are not in the Domain. Therefore, I am leaning to putting the Domain POCOs in the Domain Layer (as recommended in DDD). I then realized I could use the Layering diagram in VS2010 – Yippie!

Carpool11

I note that the data layer is not abstract enough – rather it is the implementation. I just didn’t know what to call it

My next big thought – do I add validation attributes to POCOs? Without actually trying anything, I learned towards yes – so I can get the built in features of MVC validation.

I then went back and removed the class name from the properties (CarPoolId is now Id, etc…) to make the code more readable.

My next dilemma has to do with dependency properties. Consider this class:

1 public class SwimmerSummary 2 { 3 public int SwimmerId { get; set; } 4 public string SwimmerName { get; set; } 5 public int SwimGroupId { get; set; } 6 public string SwimGroupName { get; set; } 7 public int SwimTeamId { get; set; } 8 public string SwimTeamName { get; set; } 9 } 10  

I want to assign the Swimmer Group on the UI, perhaps change the name, perhaps assign a new team. The problem is that I run the risk of changing the Swim Team and Swim Group to an invalid state. I can limit the Update to group and put the swim team name into the swim group name, but that is not what I want. Do I need to check the group and team on each update and make sure that it is valid? I think yes – that is what the factory can do…

I then thought about how I want to signal that the ViewModels are valid. I realized the pattern that Rob and I used on another project will work well. I inherit from a base class that has 2 properties: IsValid and List<Errors> that can be traversed.

I wondered then if I needed two validation mechanisms: using attributes on the properties and then using this IsValid pattern. I think the answer is yes – you can signal to the UI the required length and IsNull validation via the attributes, but then you also can have a return on every CRUD to say if the class is OK.

Note that I have not tested anything yet – there is nothing to test. Testing getters and setters without any custom logic is testing the .NET framework – which is a waste of time. My code coverage is 0, but that is fine.

I now have enough of my Domain Model conceptualized to set up a backing store.  In this case, a SQL Server 2008 database.  Since a picture can say a thousand words:

Carpool12

Once the database was done, I set up my Entity Framework Model:

Carpool13

My data layer was then setup well enough to continue into the business layer…

Carpool Project: Part #2

The next section in DDD is about factories – where you create classes that control the creation and updating of these . These classes are not part of the domain model but are part of the domain design. That would be easy enough to do right now and I have taken that approach on several projects, but I want to take a different approach using POCOs and ViewModels. The problem with DDD is that only have 1 representation of an entity/value object. In most applications, there are different flavors of a given value object and depending on the circumstances, different behaviors from the objects.

I then thought of soft drinks. You have a base class – Coke – for example. From that, you have Cherry Coke, Vanilla Coke, etc… Each one of these specialty flavors start with the base Coke and then add something new to it. In addition, some other flavors of Coke (Diet Coke) actually DON’T start with the base Coke. This distinction points directly to Evan’s notion of ubiquitous language.

Going back to the Coke example, you can either use 1 factory that can spit out any flavor of Coke (G0f4 Factory/Builder pattern) or 2 Factories. Factory #1 takes in raw materials and spits out base Coke. This base code can then be used directly by the Consumer(UI). The base Coke can then also be used by Factory #2 that takes in base Coke and some flavoring and spits out Cherry Coke. From a design point of view – does it make sense to have a factory for each variety of Coke? In addition, what happens when a new flavor is invented? Is it better to make a new factory or just add a new loading/unloading bay to an existing factory?

I suspect, like most things, that the answer is not clear-cut. Given the choice of 1 uber-class with lots of methods (or 1 method with multiple inputs via dependency injection) or many classes (like a plant – many factories in 1 place), I lean toward the later. Creating classes are cheap and as long as they use an interface (or a base abstract class) you can enforce some rigor in its construction. In addition, if you have some business logic around Cherry Coke, the code has to written somewhere. Using DI, many classes, or any other technique does not magically remove the need to write fewer lines of code (assuming all are following DRY principles). So if the code needs to be written somewhere – where is it better to be placed? My answer follows Martin and Fowler – more classes with functions that do only 1 thing. Organizing projects via namespaces and VS2010 is a snap and the benefit of having clear-cut responsibilities is clear.

Side note, the problem is that if you have a Brownfield app that many developers have touched over the years. Some might believe in 1 factory using DI, others might believe in 1 factory using extension methods, still others might believe in a plant concept. What happens when all do what they want on the project? You get a mess. That is why having readable code, ubiquitous language, and a standard domain design is so important.

I then launched into DDD’s section on specification – specifically predicates. An example shows better than a textual explanation. Is it better to have a Trip.IsInvalid() method with a collection of invalid reasons, a Trip.HasNoDiver() method + Trip.DoesNotCoverPractice() method, etc.., or an InvalidTrip Class() with a property that gives the collection of invalid, or an TripHasNoDriver() class? I can see the merits of all 4 possible solutions – I generally use the 1st option – but just because I used it before does not mean it is the right way. DDD recommends the 4th option – having a class for every violation of business rules. Depending on the number of business rules, this solution can get pretty unwieldy. Since I am doing this exercise as a chance to learn, I will try option 4 and see where it gets me…

I wanted to start building factories but I wanted to do it in context of the POCOs that the Presentation Layer will consume. I am using a ViewModel pattern so I started listing POCOs that tie directly to the User Stories. Here is my strategy:

· Build a View Model (using an interface or an abstract class)

· Build a Factory – input is the Domain Model, output is the View Model

· Wire it up

My 1st stop is the Car Pool Class (renamed from Trip to have ubiquitous language). Taking the Domain Model’s Car Pool, I stubbed out what the 1st Car Pool View Model would look like:

Carpool07

Notice that the ViewModel Car Pool takes all references and makes them the description of the reference – effectively taking classes and making the strings. My first question – what do I call the Car Pool View Model? Since there can be an infinite number of CarPool-based View Models, I need something that is descriptive enough but still allow for additional View Models – CarPool1 won’t cut it. My typical naming is to call it CarPoolSummary but that locks me in because what if I need two different types of summaries? I then thought that if the summary class covers all of the Car Pool class, I can always subtract fields in the View. I then thought – but if I do that, I am getting away from 1 ViewModel per View. I then decided to tie my class to the actual view that it is supporting – the CarPoolSummary ViewModel will tie to the Summary View. Not great, but I will work though the permutations to see how well this holds up.

My model now looks like:

Carpool08

I then went to add another View Model based on the next Use Case when I realized I really need a description field for each car pool. This string needs to be a combination of Dates/Times/Teams/SwimmerGroups – something to show the user. I then added the next View Model like so:

Carpool09

Calling two points a trend, I then finished the rest of the view models. Note that I made the following changes:

· The car pool description changes depending on if the driver has been assigned, the swim team/groups, and the time leaving.

· Most of the time, there is only 1 swim group per practice. Occasionally, practices are combined with groups (but never teams).

· I removed calculated fields from the Domain model -> practice start and end times are in the domain model, practice length is in the view model

Here is the resulting View Model:

Carpool10

I think this enough to go with, so I then went to write my POCOs.

Carpool Project: Part #1

There are some kids in the neighborhood that need to get a lift over to a local swim center for swim team practice. The swim team practices year-round.

Currently, there is an Excel spreadsheet on a Live Account. I went to add functionality to the Excel spreadsheet and learned that you cannot do conditional filtering in an on-line copy.

I checked out some on-line carpool sites and realized they were a bit of an overkill

I then thought I can build a car pool site and in the process, work through using the Architectural features of VS2010 and apply what I am learning in Domain Driven Design.

Carpool01

Step #1: Set Up the Infrastructure

I set up the needed infrastructure on WinHost and locally for the new solution. I won’t go into the details here.

Step #2: Set Up the Domain Model and Use Cases/User Stories

I opened VS2010 and set up a basic class diagram that captures the data elements that are included in the current Excel workbook. I added multiple swim teams in case there are some people in the neighborhood that want to jump in…

Carpool02

Based on this class diagram, I started entering some user stories into TFS (I am using the Agile template). Here is the 1st one:

Carpool03

Here are the user stories:
Notification

· The carpool that my child is in now has a driver

· Your child is in a carpool without a driver and the practice is less than 24 hours away

· Admin notified on an error

Action – Standard User

· Need to sign up for a day

· Need to cancel for a day

· Need to add a child to a car pool

· Need to remove a child from a car pool

· Need to see the weekly schedule of carpools

Action – Administrator

· Need to add a new swimmer

· Need to add a new driver

· Need to change a swimmer to a new Swim Group

Non-Functional

· Person signs into the site

· Person changes their password

· Person updates their contact info

· All errors and logins are logged

I then thought about the POCOs that would be part of the ViewModel so I went back to my stories to identify the data elements that each story includes. I created my 1st query of all of the work items that I put into TFS. As you can see, I screwed up – I mistakenly made all of my User Stories Work Items:

Carpool04

Also, with the multiple practices, I realized that I needed to add the ability for the standard user to add new practices to a day, and then determine if 1 or 2 car pools are needed. Also, looking at the class diagram and reading DDD, I see that I need to add more stories. For example, does swimmer have an entry point? If so, then who can add/remove swimmers?

I looked at the class diagram again and realized I had to add for some more changes -> cars might have a max capacity, but the actual capacity changes for each trip – depending if there are siblings along for the ride. Also, the notion of the car is not needed, the trip can tell you who is the driver and the capacity allowed for the trip. My model changed to this.

Carpool05

I then went through Domain Driven Design – Chapters 5 & 6 – and tried to identify the Entity, Value, and Aggregate objects. Below is my initial thought.

Carpool06

The Root Entity is Trip and Practice. However, this is not right because the Root Entity has a global identity and the entities inside the aggregate are unique only within the aggregate. That is not the case – for example, the swim team is unique for the entire graph. The fact that the driver is not associated with the swim team doesn’t mean they are in different aggregates. Also, since nothing outside of the aggregate can hold a ref to the inside entities and Swimmers clearly need to be associated with a Swim Group/Team, this separation is not going to work.

After reading some more on aggregates and the canonical example of purchase order/line items, I think that I don’t have any aggregates.