Sunday, August 19, 2007

Starting an external program from C# procedure

We are working on Source Control integration for GenWise and needed some code to start an external process, and read the output or errors from the process. After some trials we found this is the best way to do it:

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.WorkingDirectory = this.WorkingFolder;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = this.VSSClientProgram;
proc.StartInfo.Arguments = pArguments;
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
string Error = proc.StandardError.ReadToEnd();
int ExitCode = proc.ExitCode;
proc.Close();

The CreateNoWindow sees to it that you will not see some Window popping up from your own program normally with no contents. The UseShellExecute = false makes it so you can redirect the standard outpout, input and error streams.

Saturday, July 7, 2007

GenWise 1.09 Released !

We have released version 1.09. It was a long cycle. It has proven difficult to get rid of our threading and events scheduling issues. But we feel very comfortable now that this release is very stable. We now use the latest NHibernate version (1.2GA). In the mean while we have also been developping our own applications and fixed many practical issues in working with GenWise. With this version full ASP.NET applications can be developped in record time.

Wednesday, June 13, 2007

Learning by doing

The proof is in the pudding they say. Or if you want eat "your own dogfood". Last week one of our principle developers (Ward Bekker) started using GenWise on a project for a new customer. It was an interesting experience to see someone who developed several years on GenWise get started with the tool himself. Some of the immediate lessons:
- Hey i've never seen that bug before...
- Wouldn't it be handy if...
- Yee, that part is really slow...
- Can't we...
- Should we not...

Needless to say our bug and feature tracking system is filling quite nicely!

Friday, June 8, 2007

What' s up at GenWise ?

Next week we are giving a GenWise course for customers in Maarssen. We are quite exited, since they will use our latest internal build named 1.09. If after the course the software is stable enough we will release it probably in the week after. 1.09 contains many bug fixes, more stability and numerous small enhancements. After 1.09 we will aim for 1.1. This release contains all that we had originally planned for 1.1.
Also 1.09 will contains the 1.2 GA release of NHibernate and is tested with that version.

People attending the course will get a free GenWise version. We hope that this will encourage people to start using GenWise after the course directly.

Wednesday, May 30, 2007

To schema or not to schema...

Today we ran into a very practical problem. Should schema names be included in the NHibernate mapping ? Well it depends a little bit on your back end. In Oracle the username is the schema name. In SQL server you have the Database concept. (Northwind database for example.) For one customer we generated a NHibernate business object layer with table mapping like so:
class name = "Customers" table= "Abel.Customers"
However when moving to production, the Oracle User / Schema name was different. So our code did not work. All we needed to do is take of the Able schema part to make it work with the production connection string.
We have immediately decided to make this a GenWise Option for the Table item template. So now you can generate the mapping with or without schemanames

Saturday, May 12, 2007

NHibernate Configuration from Code

Sometimes you do not want the connectstring in your NHibernate.config file. In fact setting it there without encryption seems not the right thing to do. Before you open sessions in NHibernate you can configure NHibernate to take connection settings from code. This way you can for instance let the user log in with his/her database username and or password:

_configuration = new NHibernate.Cfg.Configuration();
_configuration.SetProperty("hibernate.connection.provider",@"NHibernate.Connection.DriverConnectionProvider");
_configuration.SetProperty("hibernate.dialect",@"NHibernate.Dialect.Oracle9Dialect");
_configuration.SetProperty("hibernate.connection.driver_class",@"NHibernate.Driver.OracleDataClientDriver");
_configuration.SetProperty("hibernate.connection.connection_string",@"persist security info=True;data source=MyServer; user id=MyUserid; password=MyPassword;");

This example uses Oracle settings.
On the Web you will probably get the username and password somewhere from a session variable.

string _username = HttpContext.Current.Session["Username"].ToString();
string _password = HttpContext.Current.Session["Password"].ToString();
_Configuration.SetProperty("hibernate.connection.connection_string", @"persist security info=True;data source=RADORA9; user id=" + _username + "; password=" + _password + ";");

Friday, May 11, 2007

What is Code Generation

The answer seems obvious. Code Generation is Code Generating Code. Basically it is a skeleton filled in by a parser looking for variable parts. Off course in it's simplest form that's what it is.

But there is much more to it. Straight code generation does not allow you to have an extensible framework to build upon. True code generation should build on a flexible object oriented code generation framework with a hierarchical template set in which you can hook either with custom code or with other templates. Thats' just what we have been building, and it is extremely powerful. Templates can independently from each other generate code not only into each other but in different files.

Our templates are C# classes that implement certain interfaces. Each template uses a codeblock structure. All templates expose code insertion points. For instance the following code:

PageTemplate.AtPageLoadEnd.Add("{0}_ActionChanged(\"Browse\");", PrimaryControl.Name);


used in a template generates at an ASX page code behind in the AtPageLoad event, in the last code block of the Aspx Page template. These code insertion points can be used in all templates.