Advice for vb.net web application structure with code generator - refactoring, rewrite, change ORM?
Hello Experts -
I have been working on a web application for the past year and I have been using a code generator that I wrote that creates all the necessary classes, web fields, javascript code, code behind, data access and stored procedures, generated from a database table. This application was originally intended to be a small interim solution between my client's company use of spreadsheets, and a full blown enterprise application. Turns out now they want to expand the application I've been working on for their enterprise application, and I'm nervous about handing it off to other developers. I'm in a quandry since I'm not deeply trained in .net development, and I'm not sure what the best solution is at this point. Would you share with me your recommendations on what you might do in this situation? The site has become quite large now, so I'm wondering if refactoring the code would be enough, or converting to Entity Framework for the database/stored procedure, or using a different ORM would be a good idea? I'm using DataReaders to load classes from the database records, then then looping through those class records to write literal HTML code in the code behind, which I am tying to form objects (literal). The reason I wanted to use data readers and JSON Ajax is its speed and leanness, not depending on Microsoft's built in objects which I understand tend to slow down performance generally. The upside is anyone who uses my generator can output all the code necessary for any database calls and presentation very quickly. The downside is there's a lot of code generated. Here's the architecture of the site as is:
Web Forms (aspx) referencing JSON Ajax calls to Code Behind
>
Code Behind (aspx.vb)
>
Entity Class
>
Abstract Data Provider Class (for optionally switching data store)
>
SQL Server Data Provider Class
>
SQL Server Stored Procedures
Thanks for whatever suggestions/recommendations you have. Is this structure so dated that other developers would shoot me for having to wade through all these layers, or is this a workable code base?
Thanks,
Steve
Here is a sample of the typical patter I'm using throughout the site:
################# JAVASCRIPT (on .aspx page) #################function InsUpd_Person() { // … set vars to form field vals var first_name = document.getElementById("txtFirstName").value; var person = new clientPerson(person_id, person, company_id, department_id, first_name, last_name, email); // invoke PageMethods var serializedPerson = Sys.Serialization.JavaScriptSerializer.serialize(person); PageMethods.InsertUpdate_Person(serializedPerson, callBackUpdatePerson);}################# CODE BEHIND #################<WebMethod()> _ <ScriptMethod()> _ Public Shared Function InsertUpdate_Person(ByVal jsonPerson As String) As String Dim serializer As New JavaScriptSerializer() Dim oPerson As Person = serializer.Deserialize(Of Person)(jsonPerson) objPerson = New Person objPerson.Person_ID = oPerson.Person_ID objPerson.Company_ID = IIf(oPerson.Company_ID = "-1", 0, oPerson.Company_ID) objPerson.Department_ID = IIf(oPerson.Department_ID = "-1", 0, oPerson.Department_ID) objPerson.First_Name = ToNothing(oPerson.First_Name) objPerson.Last_Name = ToNothing(oPerson.Last_Name) objPerson.Email = ToNothing(oPerson.Email) SiteProvider.Company.UpdatePerson(objPerson)End Sub################# CLASS #################<Serializable()> _Public Class PersonPublic Sub New() End Sub Public Sub New(ByVal vPerson_ID As Integer, _ ByVal vRecCount As Integer, _ ByVal vCompany_ID As Integer, _ ByVal vDepartment_ID As Integer, _ ByVal vFirst_Name As String, _ ByVal vLast_Name As String, _ ByVal vEmail As String) Me.Person_ID = vPerson_ID Me.RecCount = vRecCount Me.Company_ID = vCompany_ID Me.Department_ID = vDepartment_ID Me.First_Name = vFirst_Name Me.Last_Name = vLast_Name Me.Email = vEmailEnd SubPrivate _Person_ID As Integer = NothingPublic Property Person_ID() As Integer Get Return _Person_ID End Get Set(ByVal Value As Integer) _Person_ID = Value End SetEnd Property Private _Company_ID As Integer = Nothing Public Property Company_ID() As Integer Get Return _Company_ID End Get Set(ByVal Value As Integer) _Company_ID = Value End SetEnd Property Private _Company As String = ""Public Property Company() As String Get Return _Company End Get Set(ByVal Value As String) _Company = Value End SetEnd Property Private _Department_ID As Integer = Nothing Public Property Department_ID() As Integer Get Return _Department_ID End Get Set(ByVal Value As Integer) _Department_ID = Value End SetEnd Property Private _Department As String = ""Public Property Department() As String Get Return _Department End Get Set(ByVal Value As String) _Department = Value End SetEnd Property Private _First_Name As String = "" Public Property First_Name() As String Get Return _First_Name End Get Set(ByVal Value As String) _First_Name = Value End SetEnd Property Private _Last_Name As String = "" Public Property Last_Name() As String Get Return _Last_Name End Get Set(ByVal Value As String) _Last_Name = Value End SetEnd Property Private _Email As String = "" Public Property Email() As String Get Return _Email End Get Set(ByVal Value As String) _Email = Value End SetEnd PropertyEnd Class################# ABSTRACT PROVIDER CLASS #################Public MustOverride Function InsertPerson(ByVal Person As Person) As Integer################# SQL STORED PROCS ACCESS CLASS #################Public Overloads Overrides Function InsertPerson(ByVal oPerson As Person) As Integer Using cn As New SqlConnection(Me.ConnectionString) Dim cmd As New SqlCommand("wsa_Person_i", cn) cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add("@Company_ID", SqlDbType.Int).Value = oPerson.Company_ID cmd.Parameters.Add("@Department_ID", SqlDbType.TinyInt).Value = oPerson.Department_ID cmd.Parameters.Add("@First_Name", SqlDbType.VarChar).Value = oPerson.First_Name cmd.Parameters.Add("@Last_Name", SqlDbType.VarChar).Value = oPerson.Last_Name cmd.Parameters.Add("@Email", SqlDbType.VarChar).Value = oPerson.Email cmd.Parameters.Add("@Person_ID", SqlDbType.Int).Direction = ParameterDirection.Output cn.Open() Dim ret As Integer = ExecuteNonQuery(cmd) Return DirectCast(cmd.Parameters("@Person_ID").Value, Integer) End UsingEnd Function################# STORED PROCEDURE #################CREATE PROCEDURE wsa_Person_i( @Company_ID int = Null, @Department_ID tinyint = Null, @First_Name varchar(50) = Null, @Last_Name varchar(50) = Null, @Email varchar(150) = Null, @Person_ID int OUTPUT)AS BEGIN TRAN INSERT Person ( Company_ID, Department_ID, First_Name, Last_Name, Email ) VALUES ( @Company_ID, @Department_ID, @First_Name, @Last_Name, @Email ) IF @@error <> 0 BEGIN ROLLBACK TRAN RAISERROR ('An error occurred adding to Person',1,1) RETURN END Set @Person_ID = CAST(SCOPE_IDENTITY() AS INT) COMMIT TRANReturn
Thanks, Vadim - I appreciate the input. It's good to be reminded that all other frameworks are doing is generating code themselves, so what I'm up to isn't that different. I like your response, and I'd like to wait to see if others chime in. Thanks.
tablaFreak
ASKER
Looks like no more input, so I'll take your answer, thanks, Vadim!
Vadim Rapp
Always at your service. Having re-read my comment, I'd add yet another condition to consider: your willingness to continue support and further development of your generator.