NetTiers is great! There are a few kinks to work out, especially since I'm a newby, but after getting the config file set, reviewing some samples and working with it I'll never go back to CSLA.
Yup, there are some windows forms controls created by the template manager but I've not had the chance to work with them. I use Infragistics and I have little time to build a base control for each Infragistics control, would have to code and test each class... Maybe next year. However for now I have developeed a few strategies that help solve some problems that make life easier.
The thing is to generate the NetTiers classes. This will take a little time at first but after reading the limited help at NetTiers.Org you should be an old hand after a few days. Basically you need to setup some template parameters i.e. your Source Database, Output directory and Root Name. There are a few more setting that are beneficial to know as well i.e. IncludeDatabaseFeatures, BusinessLogicLayerNameSpace, DataAccessLayerNameSpace, ParseDbColDefaultVal and IsolationLevel. There are others but I find these are the most important for my apps.
Of course you should know what version of the NetTiers template your using as well. From the download page you'll find a "Nightly Builds" Section. This is where the newest builds of the template can be found. For awhile I feared this page because it had cause my applications to break. LOL But since build 2.2 I've had not problems with latests builds.
You should be aware that the builds require the Microsoft Enterprise library. You might want to research this technology and get a better handle on the features you can utelize.
When building from the template you will get a set of directories and classes that provide all your data access, some really nice functionality. You will also get a report webpage popup that describes what classes were generated as well as how to impliment the config file.
I always create a directory under the project's root directory for holding the NetTiers generated classes and set the Output directory there.
You also have options, in the template, to build a ComponentLayerNameSpace. I tried to use this feature at first but ran into problems because I'm always making changes to my database as I design and code. I'm a single developer I don't get lots of chances to architect, design and code my application. Just create basic archeticture and run.... And sometimes I have to make patches to the NetTiers templates to get what I want, this means I have to physically delete some of the classes each time I rebuild from the template. I found it easier to just delete the complete directory and regenerate all the files again. So When I tried using the ComponentLayerNameSpace I would have to individually copy files modified from Visual Studio, became difficult considering I sometimes regenerate NetTiers every couple hours in a single day. My bad!
However, I have in essance create a simple version of the ComponentLayerName Space as you should consider doing to help limit headaches down the road.
Most apps I design are multiuser and require sycronizing the database at all times with all user views on each client workstation. This is a reall hassle believe me. But the Component Layer has simplified it some. For example; Each table has a static class in the application and a asscociated propery for holding the NetTiers Lists. So when multiple forms want to show the same list the result comes from a single instance of the list. Then if any simultaneously open form modifies the list it is reflected in all other open forms. This is great stuff thanks to NetTiers modified events.
NetTiers also provides a great way to access database stored procedures, however, I don't use them much since I don't have time to build upgrades and SQL Server patches for new versions. I usually have to generated hand coded converters for putting in place application version upgrades, really sucks doing it that way but I get paid for speed.
Ok, now that we've covered some basic intro stuff here is my process for using NetTiers on a form.
First thing; I love code completion so I try to steer in that direction even if it takes a few more lines on my part.
Once you generate your database, set your config file and include references to the 3 NetTiers projects into your work project your ready.
You'll need to compile your project so that all the NetTiers objects are available;
Next in the form where you want to access the NetTiers classes use an include, something like;
using Data;
using Data.sqlClient;
using Entities;
Now you can put some controls on your form, say a textbox, checkbox and combobox...
Then drag a Binding Source object to the form.
Now set up the Binding Source object. I associate the binding source object to the actual NetTiers object I want to use. For our purpose lets consider a table named patient.
Click on the binding source object and look for the DataSource property. Set this property equal to Entities.Patient.
To do this, since you have not added and Data Source to your project yet, just click the drop down and chose "Add Project Data Source". Next Chose "object" then select the object from the NetTiers classes. Your NetTiers namespace will appear something like Entities. Then open the Entities leaf and find patient--or you table. And click finish.
Now you have added your NetTiers Patient table to the project and can call it up any time you want without having to go through the wizard again.
What we have just done by associating the Binding Source object the NetTiers Patient Table object allows use to use Code Completion. We have not actually set anything up to automatically retrieve data. We have only told the Binding Source object what type of object it should find field names from when show the developer available field names for the target table.
Now you can set the form controls up by associating each control with the binding source and assign the various properties envolved with showing the table data. Remember we have not actually retrieved any data yet. Only notified the Binding Source object of its target table and field names to chose. You will notice when setting the necessary fields of each control that the binding source actually allows your to see fields from the table.
For example if you had a field Patient.NameLast you would use a text object and assign this object's Text Project to Patient.NameLast. (Of course the table would have to have a "NameLast" field right? LOL
Ok, so now you can setup your other controls like you would normally with a binding source object. There are other ways to use the NetTiers objects with your form controls but I prefer this way, fast and simple right!
Next we need to get the data from the Database Server. This is just as simple. You could use the next steps to supply the binding source with record objects, however, a better design pattern is suggested, i'll explain later.
Our goal here is to get a list of patients for the binding source to use and show a record. The following code gets all patients even though we are only showing a single patient record. This is so you can later and a listbox control and see how easy it is for yourself.
Some where in your project create a PatientService class, I used a separate project to hold these types of classes, similar to the following;
using
System;
using System.Collections.Generic;
using System.Text;
using
Tiffany.Entities;
using Tiffany.Data;
namespace
Services.Tables
{
static public class Patient
{
static private TList<
Patients> items =
new TList<
Patients>();
//Properties to access the list object
public static TList<
Patient> Items
{
get {
if (items ==
null)
{
items = DataRepository.PatientProvider.GetAll();
items.Sort(PatientColumn.NameLast.ToString());
}
return items;
}
//Code to save a patient here
public static bool Save(Patient patient)
{
return DataRepository.PatientProvider.Save(patient);
}
public static bool Save()
{
return DataRepository.PatientProvider.Save(this.Item);
}
}
}
}
As you can see from the above class there will only be a single instance of the Patient table in your system. So any changes here will be reflected by any forms or controls active at any time. I've dummied this class up some for the example but I'm sure you can see where this is going and how it helps the overall architecture of the app.
Now back to the form, you will want to add a reference to the newly created name space and class. So add the reference by right clicking the reference folder under your startup application and adding the project then with a using directive:
using Services.Tables;
Now where ever appropriate in your form set the BindingSource's DataSource property to the new created static object;
bsPatient.DataSource = Services.Tables.Patient.Items;
Now to save your changes? Add a button and implement the following code.
//Saving code here. works with a newly created Patient or even a previously Patient record.
bsPatient.EndEdit();
Services.Tables.Patient.Save();
That's it... Ok I cheated a little. I use the voided signiture of the Save function in the NetTiers object. This function will simply look at every Patient record and save all the ones that have been modified. If we want to save only a single record currently selected by the Binding Source Object? Then we must type case the BindingSource's CurrentObject field like so;
Add this accessor to the form or just type cast the object. I prefer the Accessor approach;
public Entities.Patient thePatient
{
get{return bsPatient.DataSource as Entities.Patient;}
//I also use the Accessor's set for later form access ease like so
set
{
bsPatient.DataSource=value;
}
}
The accessor allows the simple assignement back and forth of the Patient object without lots of casting in the code.
Ok, hope this encourages you to use NetTiers. I've found it simple and easy to use, most of the time. But still wish they would immpliment a few more features. Nothing can be perfect I guess.
Have a blast!