CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Eric Wise

Business & .NET

February 2005 - Posts

  • Codesmith rocks!

    If you haven't already purchased a copy of codesmith, please do so, I'll wait...

    This is by far the best bang for my buck I've ever gotten out of a non microsoft tool.  Case in point: I've been making tweaks to the database schema for Easy Assets .NET adding fields to various tables and changing some data types.  In the old days I'd have to go through all my basic stored procedures and tweak them as well.

    Not so!  Thanks to CodeSmith and the tweaks I made to the AllStoredProcedures.cst and StoredProcedures.cst templates I was able to regenerate all 80 of my stored procedures in less than 3 minutes.  Tweaking this by hand would have taken hours.

    Also, if you don't want to share this with your co-workers (not that I condone such deception), your incredible gains in productivity can make you look like a super wiz.  Or you could just generate most of your code and spend a week reading CodeBetter.com then turning in the project early anyway...

  • .NET Reflector Rocks!

    Where have I been?  I've been working like a madman on the local install version of Easy Assets .NET!

    Have you ever really gone back and reviewed code you've wrtten long ago?  I've been working on Easy Assets .NET for quite some time and the hosted version works great!  I'm happy with the performance etc.  When I started working on the local install/open source version though I realized just how far my skill with .NET has come along in the last year+ and so I've decided to refactor the entire project so that the local install / open source versions will be even easier to work with.

    Good news for my future customers, bad news for my time and sanity.  I must give great thanks for .NET Reflector though, it allows me to quickly and easily run through my hosted .dll and pull out the bits I want in VB .NET.  The hosted version is in C# but my gut feeling tells me that a VB .NET local install / open source version will be more universally easy to work with.

  • Easy Assets .NET Subscription Offer

    There are some big changes in the pipeline for my ISV product, Easy Assets .NET, the biggest of which being a version for local install and a source included version.  I'm going to be looking for a few small to midsized companies to "eat my dogfood" i.e. test some of the new features and functionality.

    What's in it for you?  You get access to your own Easy Assets .NET database for free!  When the release comes your company will be awarded 5 free licenses for the local install version or a significant discount on the hosted version.

    If you're interested just send me an email from my blog indicating your company name, approximately how many users would need access, and broadly how many fixed assets you need to track.  I'll be looking for 2-3 companies to start with and probably add 1 or 2 more as the beta progresses.

  • Developer Express Xtra Reports - My first 10 minutes

    One of the most popular posts I had last year as far as hits and feedback involved my comparison of Active Reports to SQL Reporting services where I concluded that even though Reporting Services was free, there were some factors and situations which made Active Reports a much better choice for a development team that wasn't highly constrained by budget.

    After posting that review, I received several emails from developers who told me I should check out a product called Xtra Reports from Developer Express.  I've been meaning to do just that for a while now and finally had the chance this weekend.  Here's a summary of what I found.

    Price

    The price for the Xtra Reports suite is very competitive, coming in at around1/3 of what the Active Reports package comes in.  They have the same royalty free distribution license and also for $100 more you can snag the source code.

    Installation

    The installation ran flawlessly.  I didn't have to do any configuration beyond adding the web controls to my toolbox by referencing the dll.  It was clean and easy.

    Report Designer

    The report designer is on par with other designers out there.  Once you've used one you've used them all for the most part.  I had little difficulty building the same report (Asset valuation by category type) that I built for SQL Reporting Services and Active Reports.

    Server Configuration

    Active Reports did require me to reference some assemblies in my web.config file.  Xtra Reports did not.  I set copy local = true on their dlls and I was able to xcopy deploy my web project to the server and it all worked fine with no additional fine tuning.  Simple is good.

    Dynamic Connection String

    One of the challenges I had with SQL Reporting Services was that I couldn't find a clean and easy way to change the database connection string based on the logged in user.  Being that my hosted product, Easy Assets .NET grants each licensed company its own database I need a reporting solution that can connect to the proper database for the current user.  Active Reports was able to accomplish this through some runtime code, but as far as simplicity and lines of code the Developer Express product won out on this challenge.

    Conclusion

    I haven't had the opportunity to go very deep with the component, but initial impressions are critical to me as a developer since I generally do not have the time or patience to deal with complex installs or deployment scenarios.  Both Active Reports and Xtra Reports are easy to install and configure, the only difference being the web.config settings for Active Reports which weren't really hard to figure out, it was just nicer to copy and forget with Xtra Reports.

    I honestly haven't had a chance to play with their toolbar yet which claims to be able to export report data to a variety of file types (pdf, xls, etc).  I poked at it a bit on the sample application on their website but for some reason it was trying to download a .aspx page instead of the file type I was expecting.

     

    If anyone at devexpress finds my blog, you should probably take a look at that.

    Keep in mind that this review only scratches the surface of what the Developer Express product is capable of.  Active Reports is a solid product and still my favorite choice, but I can conclude that developers on a budget would be well served by Developer Express's product.

  • Speaking of VB 6.0 Code

    Sahil made me think of this little tibit.

    When I attended the VB Roadshow earlier this year I was fortunate enough to be invited to an earlier session that set down the "best and brightest" local developers with members of the Microsoft VB team.  When asked if it was a good idea to re-write old VB 6.0 code into VB .NET code the answer given by the teams was NO.

    The idea here is that a strict re-write doesn't gain you much at all.  If you are refactoring or re-writing the code for another reason fine, but rewriting just to be able to say "yay I have managed code" isn't worth the effort.

    Posted Feb 16 2005, 04:30 PM by Eric Wise with no comments
    Filed under:
  • Object Oriented Programming VB .NET - Level 000

    I have recently been tasked with creating a 1,000 ft overview of Object Oriented concepts in the VB .NET world for a development staff whose experience is mostly in old school ASP and VB 6.0

    Much credit to The Book of Visual Studio .NET, ISBN 1-886411-69-7 from No Starch Press written by Robert B. Dunaway which I used as a template for the document and borrowed some examples from.

    What is an object?

    In its most basic form, an object simply is an entity that exposes properties, methods, and events.  Objects provide abstraction and encapsulation to make our job as programmers easier by exposing code in ways that are easy for a human being to organize and comprehend.

     

    Abstraction

    Abstraction is the easiest of the OOP concepts to understand and is often something we implement naturally without realizing it. In short, abstraction is the implementation of code to mimic the actions and characteristics of any realworld entity.

    The most commonly-used example for describing abstraction is the abstraction of a person. Imagine that we want to create an object from a class that represents a person. A person class will need to describe its characteristics through the implementation of properties (height, weight, eye color, etc).  Actions of the person class are performed by methods (Speak, Eat, Sleep, etc).

     

    Encapsulation

    We expose properties and methods through abstraction, but we implement the actual workings of our component through encapsulation. A few encapsulated actions might include data access, data validation, calculations, adding data to an array or collection, or calling other methods or other components. Exposing our component's interface while hiding the component's implementation code effectively separates interface implementation from our black box implementation. This separation helps to modularize components to perform a more specific task while requiring minimal knowledge of how the black box actually works.

    One of the more useful applications of encapsulation is in making a complex component. For example, your program may require interaction with a third party system, but interaction with this system can only be achieved through a complex API. Rather than requiring all developers on a project to spend valuable time figuring out how to correctly use the third party API or even find ways to misuse it, one developer could study the API then encapsulate it in a component that exposes a less complex interface. This is a common practice that saves time and reduces potential bugs.  The .NET Framework itself encapsulates various Windows APIs.

     

    Polymorphism

    Polymorphism is the ability to implement the interface of another class into multiple classes or to implement multiple interfaces on a single class. This method of implementation is referred to as interface-based programming. A vehicle is a good example of polymorphism. A vehicle interface would only have those properties and methods that all vehicles have, a few of which might include paint color, number of doors, accelerator, and ignition. These properties and methods would apply to all types of vehicles including cars, trucks, and semi-trucks.

    Polymorphism will not implement code behind the vehicle's properties and methods. (That's the job of inheritance covered in the next section.) Instead, polymorphism is the implementation of an interface. If the car, truck, and semitruck all implement the same vehicle interface, then the client code for all three classes can be exactly the same.

    Implementing the vehicle interface only requires the declaration of properties and methods. To create a new interface, use the Interface keyword in place of the Class keyword. The client implementing the new interface can do so by using the Implements keyword as shown in the example:

    Public Interface IVehicle
        Property PaintColor() As String
        Property NumberOfDoors() As Integer
     
        Function Ignition() As Boolean
    End Interface
     
    Public Class Car
        Implements IVehicle
     
        Public Function Ignition() As Boolean Implements IVehicle.Ignition
     
        End Function
     
        Public Property NumberOfDoors() As Integer Implements IVehicle.NumberOfDoors
            Get
     
            End Get
            Set(ByVal Value As Integer)
     
            End Set
        End Property
     
        Public Property PaintColor() As String Implements IVehicle.PaintColor
            Get
     
            End Get
            Set(ByVal Value As String)
     
            End Set
        End Property
    End Class
    

     

    Inheritance

    Inheritance is the ability to apply another class's interface and code to your own class. Remember, with polymorphism, you got the interface; however, you must apply your own code. The power of inheritance is the ability to inherit code, saving developers time. This type of inheritance is called implementation inheritance. To inherit another class, use the Inherits keyword.

    In the domain manager pattern, objects are inherited from a base class called DomainObject.  This means that every object in the system, whether it is a student, teacher, building, address, or any other object type a system requires will return True if asked if it is a Domain Object.  The power of this type of inheritence is that it allows us to design generic functions that take an object of the type DomainObject and route them appropriately to specialized code to deal with them.  This is used in the Domain Manager's call to the data layer:

        Public Function Load(ByVal d As DomainObject) As DomainObject
            Dim dao As Object
            For Each dao In _SupportedDAOs
                If dao.SupportsLoadType = d.GetType.ToString() Then
                    Dim hydratedObject As DomainObject
                    Try
                        dao.ConnectString = _Connection
                        hydratedObject = dao.Load(d.Key)
     
                        If (Not IsNothing(hydratedObject)) Then
                            hydratedObject.ObjectDomainMGR = Me
                        End If
                    Catch ex As Exception
                        Throw ex
                    Finally
                        Try
                            If Not IsNothing(dao.DataReader) Then
                                dao.DataReader.Close()
                            End If
                        Catch ex As Exception
                            Trace.Write(ex.Message)
                        End Try
                    End Try
     
     
                    Return hydratedObject
                End If
            Next
     
            Throw New Exception("Load not supported for this type[" + d.GetType.ToString() + "]")
        End Function
    

    Notice how load takes any domain object as a parameter.  The code then walks through a list of supported Database Access Objects (DAOs) to find the appropriate data access functionality for the object given.  This means that any object in our system can be loaded just by passing it into a single function, making it easy for new developers to be able to use our pattern without having to understand the workings of the DAO classes or the domain manager.  All they need to know is to call DomainManager.Load()!

     

    Events

    Raising events is a great way to "bubble up" notifications from a class to a caller.  In order to create an event, simply use the Event keyword as seen in class Test below.  To raise an event simply use the RaiseEvent command and the event will be passed to the caller of the object.  In the example below you can see a very simple example where the class TestCaller has a variable of class Test declared with the WithEvents keyword.  This keyword must be used in the declaration in order to capture events.

    The sub PostSaveLogic() is declared as a handler of the TestSaved event.  That is to say that whenever Test.Save() is called, the code within PostSaveLogic is called.  An example of where this could be useful is in sending email notifications to users.  The test object certainly doesn't need to know how to send email, email functionality should be encapsulated into an email interface which can be called when an event that requires email notification occurs.

    Public Class Test
        Event TestSaved()
     
        Public Sub save()
            RaiseEvent TestSaved()
        End Sub
    End Class
     
    Public Class TestCaller
        Private WithEvents t As New Test
     
        Public Sub SaveTest()
            t.save()
        End Sub
     
        Public Sub PostSaveLogic() Handles t.TestSaved
     
        End Sub
    End Class
    

     

    Declaration Options

    Here is a list of the most commonly-used declaration options in .NET with brief descriptions of each:

    • Private: The Private keyword defines a variable or method as accessible only by code within the context of where the declaration occurred; outside code is not permitted access.
    • Public: The Public keyword declares a property or method as accessible by anyone within the calling application or within the class itself.
    • Friend: The Friend keyword defines a property or method as accessible by members within the class it is declared in.
    • Protected: The Protected keyword defines a property or method as accessible only by members of its class or by members of an inheriting class.
    • Default: A Default property is a single property of a class that can be set as the default. This allows developers that use your class to work more easily with your default property because they do not need to make a direct reference to the property. Default properties cannot be initialized as Shared or Private and all must be accepted at least on argument or parameter. Default properties do not promote good code readability, so use this option sparingly.
    • Overloads:The Overloads property allows a function to be described using deferent combinations of parameters. Each combination is considered a signature, thereby uniquely defining an instance of the method being defined. You can define a function with multiple signatures without using the keyword Overloads, but if you use the Overloads keyword in one, you must use it in all of the function's Overloaded signatures.
    • Shared:The Shared keyword is used in an inherited or base class to define a property or method as being shared among all instances of a given class. If multiple instances of a class with shared properties or methods are loaded, the shared properties or methods will provide the same data across each instance of the class. When one class alters the value for a shared property, all instances of that class will reflect the change. Shared properties of all instances of the class point to the same memory location.
    • Overridable:The Overridable keyword is used when defining a property or method of an inherited class, as overridable by the inheriting class.
    • Overides: The Overides keyword allows the inheriting class to disregard the property or method of the inherited class and implements its own code.
    • NotOverridable: The NotOverridable keyword explicitly declares a property or method as not overridable by an inheriting class, and all properties are "not overridable" by default. The only real advantage to using this keyword is to make your code more readable.
    • MustOverride: The MustOverride keyword forces the inheriting class to implement its own code for the property or method.
    • Shadows: The Shadows keyword works like the Overloads keyword except that with shadows we do not have to follow rules such as implementing the same signature. The Shadows keyword does not require the consent (override ability) of the inherited class to replace the property or method's implementation code. A method does not have to be defined as overridable for the Shadows keyword to work.

  • Seeking: Good 3rd party calendar control

    I'm looking for something that is fairly lightweight and easy to use.  It needs to be able to do outlook style calendar functions (show appointments etc).  It needs to be an ASP .NET Control.
  • No longer on the market

    Today I accepted an offer from School One so I'm no longer available for contract work.

    They are a relatively small software shop that offers online applications to schools.  The majority of their products are written in old ASP and they're looking to start moving over to ASP .NET.  I'm pretty excited about the opportunity to get into a growing company that will utilize the 3 years of experience I have built in ASP .NET to continue to grow their staff's skillset and continue in creating excellent products.

    Thanks to everyone who responded to my previous looking for work post.  It seems the market for .NET developers in northeast Ohio is strong!

  • More handling complex objects in grids

    Mike Lorengo and I are having a fantastic dialogue about complex objects and handling the display of their information in grids.  I do recommend you read his post before continuing here.  Don't mind me... I'll wait...

    Ok now that you're back I'd like to explain a little deeper on my preference for domain queries that return data tables to populate grids instead of the other methods Mike goes into.  Yes, my main gripe with such a method is the performance concern.  Mike's post, and the feedback he's received the main concern has been about executing many calls instead of one call.

    Mike answer's these concerns by giving four ways that you can handle databinding these complex objects:

    1. Return a DataReader of Wine records, and then lazy load the WineVarietal (and Varietal) records in another DataReader as needed
    2. Return a DataReader of Wine records and for each one get another DataReader to load the associated Varietal information
    3. Return a DataReader of Wine records with multiple INNER JOIN's and iterate through the records building the Wine and Varietal information
    4. Issue a batch of Sql Statements for each set of information and use the  IDataReader's  NextResult() method to advance the DataReader to the next result set while building the Wine and Varietal information.

    This is all well and good but the point that I wanted to get across is that the purpose of binding the information to the grid is to display summary information.  We're not exposing any specific object calls to the summary information except the load of referential data.  In this case, the end result is that we are using a collection of complex objects as a datatable.  So my point, in the end, is if you are trying to act like a datatable, you might as well be a datatable.  It'll save you all the time of parsing those datareaders and building objects whose functionality you aren't really using.

    Great discussion Mike.  I love blogging for the same reasons you do.

  • Handling complex objects in grids

    Mike Lorengo has an interesting post about binding gridviews in ASP .NET 2.0 to “complex” objects.  I have already posted a short reply to his blog and wish to elaborate upon it here.

    To start with, let me say that I am a huge fan of using objects inherited from CollectionBase over datasets.  Objects to me are simply more flexible and make more sense.  However, it is very easy to get caught up in the ease and "neatness" factor of databinding your complex objects.

    Consider the following scenario.  You have two objects called Category and Subcategory.  A category is a top level describer which contains zero to many subcategories.  For the purposes of simplicity we'll examine only the subcategory object which will contain a lazy loaded property reference to category.  In a typical lazy loading scenario you'll end up with an object that looks something like this:

        1     public class Subcategory
        2     {
        3         #region private members
        4  
        5         //property accessors
        6         private int _subcategoryid = -1;
        7         private int _categoryid;
        8         private string _subcategoryname;
        9         private Category _category;
       10  
       11         //Database key
       12         private string _connectstring;
       13  
       14         #endregion private members
       15  
       16         #region Properties
       17  
       18         public int SubCategoryID
       19         {
       20             get
       21             {
       22                 return _subcategoryid;
       23             }
       24             set
       25             {
       26                 _subcategoryid = value;
       27             }
       28         }
       29  
       30         public int CategoryID
       31         {
       32             get
       33             {
       34                 return _categoryid;
       35             }
       36             set
       37             {
       38                 _categoryid = value;
       39             }
       40         }
       41  
       42         public string SubCategoryName
       43         {
       44             get
       45             {
       46                 return _subcategoryname;
       47             }
       48             set
       49             {
       50                 _subcategoryname = value;
       51             }
       52         }
       53  
       54         public Category Category
       55         {
       56             get
       57             {
       58                 if(_category == null)
       59                     _category = new Category(_categoryid, _connectstring);
       60  
       61                 return _category;
       62             }
       63         }
       64  
       65         #endregion Properties


    Now in Mike's scenario if you wanted to display a grid with a list of Subcategories and their category names you would simply access the Category property of Subcategory which would check to see if it was populated and if not load it by id.  One thing to be mindful of is that the application has already made a database call to get the subcategories and now may end up making additional calls to load the subobjects for subcategory.  Instead of one query you end up with 1 + (NumberOfRows * NumberOfComplexProperties) calls.  You can see how as you bound objects that contained references to many other objects you could quickly end up with a ton of database calls which damages your performance and scalability.

    The solution?  Either expose inital load methods that make the huge database call and prepopulate the referenced objects in one shot

    or (my preferred method)

    A more efficient way to display summary information is to expose domain level queries that execute single sql statements and return datatables. If you need to go from that summary down to specific items you have access to the keys and can load the individual objects as needed.

  • ASP .NET BasePages - Level 100

    Anyone who is new to the world of ASP .NET, or new to the concepts of inheritence in general probably is missing out on a great way to organize their ASP .NET application.  When you first create a webform and switch to code view you are faced with the following statement (c#):

    public class YourPage : System.Web.UI.Page

    What many new coders do not realize is that they can create class files that inherit System.Web.UI.Page and embed common functionality into those pages.  Shown here is a sample of a new class BasePage that inherits System.Web.UI.Page.  Notice that it exposes a property called connectstring which would allow any pages that inherit BasePage to already have a lookup for the connection string.

        public class BasePage : System.Web.UI.Page
        {
            private string _connectstring = "";
            protected string connectstring
            {
                get
                {
                    if(_connectstring == "")
                    {
                        //Get Connection string
                    }
     
                    return _connectstring;
                }
            }
      
            public BasePage()
            {
                //
                // TODO: Add constructor logic here
                //
            }
        }

    All you have to do to inherit the BasePage is to change:

    public class YourPage : System.Web.UI.Page   To    public class YourPage : BasePage

    A common question I get from new developers when I present this concept to them is “How can I tell when something should be moved to a base page?”.  For me personally, if a segment of code is used more than twice, it goes into a BasePage.  Keep in mind that through the power of inheritance you can create a top level BasePage which has functions common to the majority of the application and Inherit the BasePage class into more page specific classes.  For example:

    If the above represented a theoretical order taking system you could group common order functionality into the OrderPage class, the customer functionality into the CustomerPage class, and the Administrator functions into the AdminPage class.  By inheriting one of these classes you can gain access to the special functionality they provide.  The end result is code organization that is clean and easy to follow.

More Posts

Our Sponsors

Free Tech Publications