Enhancements to the ‘Create data repository classes from business entities’ recipe

Topics: Service Factory Modeling Edition Forum
Feb 27, 2007 at 5:05 PM
I work in an Agile development environment, and have found myself wishing for better support for small, incremental changes in the DAL. This motivated me to look at modifying the Service Factory both to make my life easier and as a way to better understand the guts of a factory. In the Agile spirit of ‘design-a-little, build-a-little, test-a-little’, I find I am continually adding stored procedures, making small updates to tables, and adding new tables as I increase the functionality of my site. The recipes for integrating those changes into the DAL, however, are not very well suited to this mode of development. Most problematic for me was the ‘Create data repository classes from business entities' recipe, where there are a number of short-comings that made me start to dread running the recipe whenever I made changes to the database. Here are the list of issues that I tackled, in order of importance to me, and what I did to address them.

1) The recipe assumes that you will be running it only once or very infrequently because each time you run it, it replaces the repository class file with one that only includes operations for those SPs you have explicitly included in the current run of the recipe. This means that in order to get a complete repository you either have to re-specify all SPs every time, or you have to do some manual work to save off the old version of the file and then re-integrate the older operations into the new version of the file (a bit counter to the purpose of a recipe).

Solving this problem was actually quite straightforward and only required changes to the 'EntityRepository.t4' template. I modified it to create the base repository as a partial class and create additional partial classes with the operations to invoke the non-default operations. (I considered ‘add’, ‘update’, ‘delete’ and ‘get all’ default operations because the recipe automatically addresses them. They are in the base repository class file). When you add a new procedure, you still re-generate the base repository file, but since it only contains common stuff, it is unchanged when you add a new operation. I then create additional partial classes, each containing a single operation for the SPs you are adding. Previously generated operations are unaffected, so you now only need to specify changes. So where before you would see a single repository file per entity (e.g. ‘EmployeeRepository.cs’) you now will see a number of files (e.g. ‘EmployeeRepository.cs’, EmployeeRepository_GetEmployeesByDepartmentId.cs’, EmployeeRepository_GetEmployeesByPayGrade.cs’, EmployeeRepository_GetEmployeesByLocation.cs’).

2) Having made the first change dramatically reduced the time it took me to add a new SP, but there were still times when I would need to regenerate the complete set of operations. For the non-default operations, this meant that I needed to manually re-do the mappings, and for my larger tables this was a painful and repetitious task of pointing and clicking till my hand was cramping.

Because I use the same names for my table columns, SP parameters, and business entities, I solved this problem by adding an auto-mapping capability to the ‘Edit Mappings’ form in the recipe. This involved adding an ‘AutoMap’ checkbox to the OutputMappingForm. When checked, the mapping for columns and properties that have the same name is done automatically. Unchecking it removes all of the mappings. Now, adding mappings for a non-default operation is usually as simple as selecting the SP and clicking OK.

3) The final problem I addressed was related to the sheer number of SPs I have created. As the list of SPs in the ‘Edit Mappings’ screen gets large, it becomes increasingly annoying to have to scroll down a huge list to select the desired SP.

To solve this, I have added a second checkbox, 'Filter by Entity Name', which will subset the SP list by only showing those SPs whose names contain the selected entity name in them. This is not a completely generalized feature because I created the plural by adding an 's' or by deleting the 'y' and adding 'ies' (I use the proper plurals in my SP names), but it is really useful for what I do as it reduces a list from a hundred or more to a dozen or so.

In the end, I only made a small handful of changes to the recipe, and it was relatively simple even with my limited knowledge of the project. I suspect I haven’t made all of the changes needed to completely generalize this solution, but what I have done has satisfied my most time-consuming issues. This is what I modified:

1. Data Access Guidance Package/Templates/T4/DAC/EntityRepository.t4

I modified the repository class to be defined as ‘partial’.
I split the loop which handled the ‘GetOne, GetMany’ processing out and duplicated the file creation and class framework code, creating one partial class per operation.

2. Data Access Guidance Package/CustomPages/OutputMappingFormCP.*

• I added two checkboxes to the lower left-hand side of the ‘Edit Mappings’ form, one labeled ‘AutoMap’ and the other 'Filter by Entity Name'.
• I modified the event handler ‘cmbStoredProcedures_SelectedIndexChanged’ to test the AutoMap checkbox and if checked, call the ‘AutoSetMappings()’ operation.
• I added two new event handlers, ‘checkBoxAutoMap_CheckedChanged’ and ‘checkBoxFilterOnEntity_CheckedChanged’ to do the appropriate actions on change to the state of the checkbox.
• I added ‘AutoSetMappings’ to the Private Implementation section to handle the mapping/unmapping functions.
• I modified the ‘GetStoredProcedures’ operation in the Private Implementation section to check the ‘filter by entity name’ checkbox and if checked, filter the SP list.

(Note: I'm new to this process, so I don't know exactly what the procedure is for posting the updated source files. I don't have a place to publicly post them and I don't know what the correct procedure is for making them available otherwise. If someone can give me some guidance, I will make the source changes available.)

Feb 27, 2007 at 9:46 PM
Thanks a lot for your feedback. I think these are great enhancements for the Data Access package. I'm checking with the WSSF team where you can upload and contribute with your changes. I will get back to you when I got further information about this topic.

Thanks again,
Charly
Mar 16, 2007 at 4:52 PM
Any news with this? Seems really interesting
Mar 16, 2007 at 10:25 PM
Ok guys, I finally got the publishing page. Go to the Community Contributions page and follow the instructions to share your code with others.
John, feel free to share your code.

Thanks,
Charly
Apr 25, 2007 at 6:56 AM
Edited Apr 25, 2007 at 7:04 AM
As a newbie I need som more information on how to modify the Web Service Software Factory.

1. Where can I download the source code for the Web Service Software Factory ?
2. After applying the changes I assume i have to replace some assemblies. Which and how ?

Regards
Lars
Apr 25, 2007 at 11:26 AM
Hi Lars, welcome to the WSSF community. Answers:
  1. The source code is included in the WSSF download as separate msi.
  2. You have some guidelines on how to update the packages in the documentation included in WSSF download and the Service Factory Hands-on Lab:http://www.codeplex.com/servicefactory/Wiki/View.aspx?title=HandsOnLab&referringTitle=Home (Excercise #11). You can also find further information about GAX on the forums and GAX site.

Thanks,
Charly
Apr 26, 2007 at 9:25 AM
Thank you, Charly.

I have installed WCF Gudiance Package Source Code, but I can not find files that johnslaby has changed (EntityRepository.t4, OutputMappingFormCP.*)

Lars
Apr 26, 2007 at 12:00 PM
You will find these files in the Community Contribution page (first item).

Charly
Apr 26, 2007 at 12:51 PM
I have dowloaded the files, but could not find the same files in the WCF Guidance Package SOurce Code project. As I understand the files from Johnslaby should replace some existing files or am I wrong ?

Lars
Apr 26, 2007 at 3:32 PM

larskols wrote:
I have dowloaded the files, but could not find the same files in the WCF Guidance Package SOurce Code project. As I understand the files from Johnslaby should replace some existing files or am I wrong ?

Lars


Lars,
The changes I have made are to the Data Access Guidance package which comes as one project in the Service Factory solution. When you install the service factory solution, there is a source directory which contains the installers for all of the projects which make up the Service Factory. You need to run the DataAccessGPSource.msi installer to create that project which will then allow you to make the appropriate modifications. In that project, you will find the directories referenced in the original posting. Hope this helps.
John
Apr 27, 2007 at 8:34 PM
John,

I've been using your modifications for a few days now and the automation is a Godsend compared to the manual mapping of every field and the overwriting of the repository classes. Thanks much. I wouldn't have thought to attempt to modify the package.

I am having one problem with it though :( When the repository classes are created, the <#= DataAccessClassNamespace#> field in the EntityRepository.t4 template is not being populated. This is my guess as the result is that the repository classes do not have any namespace and the using statement to my DataAccess project's Generic namespace is missing. It does the same type of operations with the <#= BusinessEntityClassNamespace#> entity and that is populating fine.

Example:
using .Generic //error, missing path to DA project

*namespace *{ //error, missing the namespace
class myClass {
...
}
}


I'm not asking you to fix this. I'm just wondering if you have ever had similar problems and am looking for suggestion on where I can look to identify the problem. While I understand the concept of how the templates are used, I have no idea of the actual implementation. Where would the <#= DataAccessClassNamespace#> entity be assigned to?

Even with the problem of having to paste in my namespace into about 20 files, the modifications you made have saved me significant time and headaches with modifying my database and stored procs.

Mark
Apr 27, 2007 at 8:36 PM
Ignore the asterisks around the namespace statment in the example on my previous post. It supposed to bold the word per the formatting instructions.
Apr 30, 2007 at 2:58 PM
Mark,
I haven't seen this specific problem, so I'm afraid I can't help much. I suspect it's a simple omission somewhere, though. Charlyfriend understands the factory inside-out, so perhaps he can shed some light on this issue. Glad you found the changes useful. I can't imagine running the recipe without them at this point (my next goal is to add support for update many and delete many, as these are also procedures I would like, but it looks like that's a bit more work).
John
Apr 30, 2007 at 11:24 PM
Mark,

If you are using the "EntityRepository.t4" template and you have trouble with "DataAccessClassNamespace" where its value is provided by the DataAccessClassNamespace argument from one of these two recipes "CreateDataRepositoriesFromBEProject.xml" or "CreateDataRepositoriesFromDCProject.xml".
Now depending on which recipe you use, you may need to check if you had set the "Data Access project" responsability (this is for "CreateDataRepositoriesFromBEProject" recipe) and in this case the namespace of that project should be use to set the t4 value, or in case you run "CreateDataRepositoriesFromDCProject" recipe the you should set a default namespace to the selected project where you are running the recipe and then this value will populate the t4 value.
If you still have trouble after checking this, then let me know and we may try to narrow down your scenario and focues on the steps you did to update the package and run the appropiate recipe.

Thanks,
Charly
May 1, 2007 at 4:20 PM
It was the default namespace on both projects. In my solution, I have two separate products using some common business logic. I went through the entire guidance package to create each which produced two projects for each recipe. With this setup, when I created the second set of BE, DA, etc it didn't automatically populate the default namespace property on the projects although it did on the first set of recipes. I never thought to look there. This also explains some other quirky behavior that I was having. Thanks for the help.

Mark
May 3, 2007 at 2:41 PM
I'm glad to help you.

Charly