You can pass values into either the Attribute or the Attribute map, and override the result from the generator. This allows you to fake a search result.
So going back to the attribute method and building on the previous example...if I add a value of "Smith" to the attribute "LastName" like so:
[LastName("Smith")]
public string LastName { get; set; }
And Re-run it all of my results will have the last name of "Smith"
Similarly with the Attribute Map method I can set the GeneratorDefaultValue property to "Smith" and get the same results.
TTFN!
You can accomplish the same as the above but without using the Attribute decoration method, but rather a collection of Attributes.
Building on the above example, remove all the attributes from FakeCustomer.cs so it looks like this:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5
6
7 namespace SampleHydrator.Models
8 {
9 public class FakeCustomer
10 {
11
12 public string FirstName { get; set; }
13
14 public string LastName { get; set; }
15
16 public string Address { get; set; }
17
18 public string City { get; set; }
19
20 public string State { get; set; }
21
22 public string Zip { get; set; }
23
24 public string Phone { get; set; }
25
26 }
27 }
Next replace your FakeRepository AllCustomers() method with the following:
11 public IList<FakeCustomer> AllCustomers()
12 {
13 FillMe<FakeCustomer> generator = new FillMe<FakeCustomer>();
14 IList<AttributeMap> mymap = new List<AttributeMap>();
15 AttributeMap attmap;
16 attmap = new AttributeMap();
17 attmap.GeneratorName = "FirstName";
18 attmap.PropName = "FirstName";
19 mymap.Add(attmap);
20 attmap = new AttributeMap();
21 attmap.GeneratorName = "LastName";
22 attmap.PropName = "LastName";
23 mymap.Add(attmap);
24 attmap = new AttributeMap();
25 attmap.GeneratorName = "AmericanAddress";
26 attmap.PropName = "Address";
27 mymap.Add(attmap);
28 attmap = new AttributeMap();
29 attmap.GeneratorName = "AmericanCity";
30 attmap.PropName = "City";
31 mymap.Add(attmap);
32 attmap = new AttributeMap();
33 attmap.GeneratorName = "AmericanState";
34 attmap.PropName = "State";
35 mymap.Add(attmap);
36 attmap = new AttributeMap();
37 attmap.GeneratorName = "AmericanPostalCode";
38 attmap.PropName = "Zip";
39 attmap.GeneratorDefaultValue = "False";
40 mymap.Add(attmap);
41 attmap = new AttributeMap();
42 attmap.GeneratorName = "AmericanPhone";
43 attmap.PropName = "Phone";
44 mymap.Add(attmap);
45 return generator.GetList(20, mymap);
46 }
It's a bit more verbose, but allows you to keep your model free of Attributes if you wish. There's more work to be done for sure...but there's the sneak peek.
I'll be doing this in ASP.NET MVC.
WARNING: THIS IS NOT INTENDED TO SHOW BEST PRACTICES OF ASP.NET MVC
First download and compile Object Hydrator.
Create a new ASP.NET MVC project and add a reference to Foundation.ObjectHydrator from the newly created DLL from the above step.
Create a new class in your Models folder that looks like this:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using Foundation.ObjectHydrator.GeneratorTypes;
6
7 namespace SampleHydrator.Models
8 {
9 public class FakeCustomer
10 {
11 [FirstName("")]
12 public string FirstName { get; set; }
13
14 [LastName("")]
15 public string LastName { get; set; }
16
17 [AmericanAddress("")]
18 public string Address { get; set; }
19
20 [AmericanCity("")]
21 public string City { get; set; }
22
23 [AmericanState("")]
24 public string State { get; set; }
25
26 [AmericanPostalCode(false)]
27 public string Zip { get; set; }
28
29 [AmericanPhone("")]
30 public string Phone { get; set; }
31
32 }
33 }
Next Create a class in your Models folder called FakeCustomerRepository that looks like this:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using Foundation.ObjectHydrator;
6
7 namespace SampleHydrator.Models
8 {
9 public class FakeCustomerRepository
10 {
11 public IList<FakeCustomer> AllCustomers()
12 {
13 FillMe<FakeCustomer> generator = new FillMe<FakeCustomer>();
14 return generator.GetList(20);
15 }
16 }
17 }
Next...modify the Index method of your HomeController to look like this:
13 public ActionResult Index()
14 {
15 FakeCustomerRepository fcr = new FakeCustomerRepository();
16 ViewData.Model = fcr.AllCustomers();
17 return View();
18 }
Finally change your /Views/Home/Index.asp to look like this:
<%
@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IList<SampleHydrator.Models.FakeCustomer>>" %>
<asp
:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>
<asp
:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2><ul><%foreach(SampleHydrator.Models.FakeCustomer fc in Model)
{
%>
<li>
<%=fc.LastName %>,<%=fc.FirstName %>
<br
/><%=fc.Address %>
<br
/> <%=fc.City %>, <%=fc.State %> <%=fc.Zip %>
<br
/><%=fc.Phone %></li>
<%
} %> </ul>
</asp
:Content>
Now browse to your default page and you should see a list of Random Customers...
First off...long time since I've last written...yeah I guess frequent blogging isn't my thing.
But I wanted to post this to solicit feedback from the community about something I've been thinking about lately.
Call it DDD, BDD, TDD or a bananna there is a lot of merit in approaching a new application, from an angle other than the database and how you're going to persist the data. If you've been building applications long enough, you know that data access (in any form) is one of the most repetitive and code heavy features of your application. I called it a feature because it really is...and with all features, you're smart to delay the building of the feature until last responsible moment. This allows you to garner the maximum knowledge of said feature.
What if we could build 'working' applications, that demonstrates the solution to the particular business challenge we are trying to solve...*without* a database at all. Well at least until it makes sense to.
Rob Conery's SubSonic has a fantastic feature called the SimpleRepository. This allows you to save any object into a database without having previously created a table and without having done the alphabetical gymnastics of mapping said object to the database. It just saves it. This mimic's closely the concept of the object centric database functionality of db4O etc... I think it's brilliant but what if we could delay that decision even longer still.
What if we could design our object, and pass it through a ''generator" that returned us that object filled with data that mimicked real world data. What if it could return a collection of these objects? Theoretically we could be repositories that acted like databases, but since we hadn't yet commited to a database structure we have the flexibility of tweaking those objects at will.
What we end up with is an interface and business objects that behave like they should, that demonstrate the intent of the application without having to commit to a persistence strategy until nearly the end of the project.
I didn't have any luck finding this out there already...so to that end I started Object Hydrator...it's free and up on CodePlex in source form. It will allow you to create data filled objects during runtime. I think it could have a lot promise when it comes to TDD and DDD/BDD/R2-D2. It currently works with two methods...you can add attributes to your object's properties, or you can use a mapping collection.
So if it interests you, feel free to go check it out and look at the tests to see it in action. It's still a veritable infant, so keep that in mind, but please let me know what you think about its usefulness and the code itself.