Concepts presented in the article
In this article I will detail three separate concepts:
1) How to use the Repository Factory to generate Business Entity and Data Repository classes that automatically work with the Enterprise Library Data classes, and generate basic CRUD stored procedures to match. To keep things simple we will use only one table, but you can use it for a whole database of tables.
2) How to set up a classic ASMX webservice to provide s Service Layer that talks to the DAL / BLL layers generated by the Repository Factory.
3) How to wire up an ASPX Web page that uses the WebService layer proxy class as the underlying type for an ObjectDataSource that's bound to a Gridview to perform automatically wired up Edit, Update and Delete operations, as well as a method to use the ObjectDataSourceView Insert method to add a new row to the GridView and place it in Edit mode for the user. User can then "fill it in" and update the newly added row.
I have always had a love-hate relationship with code generators. First, to use a generator, you more or less have to "buy in" to the given model or you'll never get to first base with these. Each flavor seems to come with its own idiosyncratic "missing features". Second, being more of a "stored procedures are NOT evil" kind of guy, I like to (where appropriate) put more of the business logic into the database, not less. Object Mappers and Entity Frameworks tend to use the database solely as a persistence mechanism. Logic like joins, cascading deletes, relational integrity and so on are, by definition, moved out of the database and into the code. And let's not forget about triggers, Table variables, and CLR - hosted Framework classes -- each can be incredibly useful and powerful, but the ORM purists don't want you to use them. Why? Simple - umm, they're EVIL!
However, there are some significant benefits to using the Repository Factory:
1) It provides a consistent behavior that can be "re-applied" against a changing database schema, and will regenerate the appropriate objects very quickly, saving hours of tedious coding and freeing the developer to be able to concentrate on the actual business logic she needs to implement for the client.
2) It starts you out at the database level - which is where 95% of all business applications start. In other words, you create a good db schema first; then you build your app's business logic, entities and DAL framework around that.
3) Since it uses the Enterprise Library under the hood, you are still free to make customized database calls in those situations where generated code simply does not "fit".
4) It provides maintenance freedom since a group of developers who are familiar with what the RF does now have a consistent programming object model to work with.
5) The learning curve to get up to speed with using RF is "pretty quick". There are only about four real operations, and they aren't "rocket science".
6) Finally, Repository Factory works by itself and doesn't force you into the complex world of WSSF etc. from which it was decoupled.
I will take you through the "ultra short" Repository Factory tutorial, then I'll show how to set up the WebService to use it, and finally we'll build a web page that uses the WebService reference.cs proxy class as the underlying type for the ObjectDataSource that is used for the GridView UI element. Finally, we'll see how you insert a row in a GridView, an operation that is not natively supported by GridView's many features.
The only thing Repository Factory really needs is one or more database tables. Obviously, good table design includes a primary key and relational integrity. My demo has only one table, "NOTES" that represents a simple personal note storage system.
The first step is to install the Repository Factory from Patterns and Practices.
The second step is to create the database and design and create your database table(s).
The third step is to create a DAL/ BLL Class library project. To keep things simple, my demo sticks everything except the connection string in one library project.
The fourth step is to create your Host project (in this case, our WebService) Make sure you set it to run under IIS, and create a Virtual Directory for it.
The fifth step is to enable your Repository Factory Guidance Package (Tools/Guidance Package Manager / Enable-Disable Packages / check "Repository Factory" ). This enables rght-click GAT actions on your project nodes in Solution Explorer.
The sixth step is to right click on your class library project and choose "Repository Factory / Specify Project Responsibility." You want to set the class library project to Business Entities and Data Access for this demo, and set your WebService Project for "Host Project".
Now you are ready to generate code:
1) In the Host project, "Add Database connection".
2) In the class library project, "Create CRUD Stored Procedures". Run the Generated stored procedure script against your database to install them.
3) In Class library, do "Create Business Entities", and then "Create Data Repository Classes from Business Entities". Follow the wizards, they are ultra - simple.
Build the solution. You're done with the Repository Factory! It cannot help you any further, unless you need to regenerate code.
Now you are ready to build your service layer. Add a WebMethod to your service for each of the basic CRUD operations. Here is an example:
public int UpdateNote(NOTES note)
int one = 1;
NOTESRepository rep = new NOTESRepository("Notes");
I hope the plural "NOTES" class didn't scare you; that's the name of the table. You can change this if you want when creating your RF "Stuff".
Now we move on to the Web UI layer. Create a Web Application Project. Add a WebReference to your WebService.
On your Default.aspx page, drop a GridView, and an ObjectDataSource. Then drop a button under the GridView and title it "Add Note".
Set up your ObjectDataSource to use your WebReference WebService proxy class for the "Service1" as its underlying type. Then hook up your Select, Insert, Update and Delete methods to the Webservice methods you previously created.
Set your GridView's DataSource to the Object DataSource. Enable auto Edit and Delete on the GridView. Set the DataKeys field to the NOTE_ID primary key (important!).
Click the "Add Note" button to expose the underlying _Click handler code. Here is what you would put in the body of the method:
protected void Button1_Click(object sender, EventArgs e)
// Create an instance of the ObjectDataSourceView, passing the ODS instance, a unique ID, and //current context
ObjectDataSourceView view = new ObjectDataSourceView(ObjectDataSource1, "NOTES", HttpContext.Current);
// specify the InsertMethod of the View
view.InsertMethod = "InsertNote";
// create a new instance of the WS proxy object being inserted
NotesWeb.notesService.NOTES aNote = new NotesWeb.notesService.NOTES();
// populate any default field values
aNote.SUBJECT = " ";
aNote.PRIORITY = 1;
aNote.NOTE_DATE = DateTime.Now;
aNote.BODY = " ";
aNote.DUE_DATE = DateTime.Now;
// specify the type name of the View
view.TypeName = ObjectDataSource1.TypeName.ToString();
// Create a new Generic Dictionary of type <string, yourObject>
Dictionary<string, NotesWeb.notesService.NOTES> dict = new Dictionary<string, NotesWeb.notesService.NOTES>();
// add your new item to the Dictionary
//call the Insert method of the View, passing your Dictionary instance.
catch (Exception ex)
System.Diagnostics.Debug.Write(ex.Message + ex.StackTrace);
// You have now actually inserted a new row in the database,
// so get the row count of the GridView, and put that new row in edit mode.
int index = GridView1.Rows.Count;
GridView1.EditIndex = index;
// finally, bind the GridView.
The above code is pretty well documented, so I suggest rather than reading another explanation, just single - step through it and read the comments. Basically, you need to use the ObjectDataSourceView class which is what ObjectDataSource uses internally to make its CRUD operation calls. At the bottom, after we've created a new GridViewRow (and actually inserted it into the database) we set its EditIndex so that when the GridView is bound, the row shows up in edit mode. Simply edit your new row, click the Update Link at the left of the row, and you're done: Select, Insert, Update and Delete. You could also have your button make a panel visible which would contain a form with very specific UI elements such as dropdownlists and Validation Controls wih which to create a new row, instead of putting a new GridViewRow into edit mode.
As with many "demos" I have left out exception checking and handling in order to keep the code as simple as possible. Please DO put proper exception handling into your applications!
One final note: I should not have to say this, but your connection string may not be the same as "my" connection string - so please make sure you get that part right.
You can download the Visual Studio 2005 solution here.