Does this qualify as Enterprisey?



  •  using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;
    using System.Data.SqlClient;
    using CompanyName.ProjectName.Exceptions;
    using CompanyName.ProjectName.Configuration;

    namespace CompanyName.ProjectName.DAL
    {
        /// <summary>
        ///     Abstract base class for all entity services
        ///        that provides a framework for common operations.
        /// </summary>
        /// <remarks>
        ///     The purpose of this class is to provide data services for entities.
        ///     Derived classes should expose their own public methods and use the
        ///     inherited, protected skeleton methods as needed.  
        ///
        ///        Note that this code may be executed in a multi-threaded environment
        ///        and therefore needs to be thread-safe.
        /// </remarks>
        ///
        /// <typeparam name="T"></typeparam>
        
        public abstract class EntityService <T>
        {

            #region Sproc Name Properties

            /// <summary>
            /// Defines the Sproc name for Creating or Updating a record
            /// </summary>
            protected virtual string CreateUpdateSproc
            {
                get { return string.Empty; }
            }

            /// <summary>
            /// Defines the Sproc name for Deleting a record
            /// </summary>
            protected virtual string DeleteSproc
            {
                get { return string.Empty; }
            }

            /// <summary>
            /// Defines the Sproc name for Selecting a record
            /// </summary>
            protected virtual string SelectSproc
            {
                get { return string.Empty; }
            }

            #endregion

            #region Entity Template Methods

            /// <summary>
            ///     Template method for GetParametersForSave
            ///     The inheriting class must implement this method that returns a parameter list
            ///     based upon the entity class.
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            protected virtual Dictionary<String, String> GetParametersForSave(T entity)
            {
                throw new ProjectNameException("GetParametersForSave must be implemented by inherited class");
            }

            /// <summary>
            ///     Template method for GetParametersForDelete
            ///     The inheriting class must implement this method that returns a parameter list
            ///     based upon the entity class.        
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            protected virtual Dictionary<String, String> GetParametersForDelete(T entity)
            {
                throw new ProjectNameException("GetParametersForDelete must be implemented by inherited class");
            }

            /// <summary>
            ///     Defines a method for constructing an Entity object based on the passed IDataReader
            ///     This must be implemented for each child class inheriting this class
            /// </summary>
            /// <param name="reader"></param>
            /// <returns></returns>
            protected abstract T CreateEntity(IDataReader reader);

            #endregion
            
            #region Base CRUD Methods

            /// <summary>
            ///     Base method for calling a stored procedure and passing a IDataReader to
            ///     Create Identity. This can be overridden in a child class for complex situations
            /// </summary>
            /// <param name="parameters"></param>
            /// <returns></returns>
            
            protected virtual T BaseGet(Dictionary<String,String> parameters)
            {
                string commandText = this.SelectSproc;

                SqlDataReader reader =
                    DataAccess.SQLServer.SQLServerManager.Instance.ExecuteReader
                        (ProjectName.Configuration.DataAccess.ConfigurationManager.ConnectionString,
                        CommandType.StoredProcedure,
                        commandText,
                        parameters,
                        null);

                return this.CreateEntity(reader);
            }

            /// <summary>
            ///     Base Method for calling a stored procedure for performing an Insert/Update
            ///     This can be overridden in a child class for complex situations
            /// </summary>
            /// <param name="entity"></param>
            protected virtual void BaseSave(T entity)
            {
                Dictionary<String, String> parameters = this.GetParametersForSave(entity);
                string commandText = this.CreateUpdateSproc;

                int rows =
                    DataAccess.SQLServer.SQLServerManager.Instance.ExecuteNonQuery
                        (ProjectName.Configuration.DataAccess.ConfigurationManager.ConnectionString,
                        CommandType.StoredProcedure,
                        commandText,
                        parameters,
                        null);
            }

            /// <summary>
            ///     Base Method for calling a stored procedure for performing a Delete
            ///     This can be overridden in a child class for complex situations
            /// </summary>
            /// <param name="entity"></param>
            protected virtual void BaseDelete(T entity)
            {
                Dictionary<String, String> parameters = this.GetParametersForDelete(entity);
                string commandText = this.DeleteSproc;

                int rows =
                    DataAccess.SQLServer.SQLServerManager.Instance.ExecuteNonQuery
                        (ProjectName.Configuration.DataAccess.ConfigurationManager.ConnectionString,
                        CommandType.StoredProcedure,
                        commandText,
                        parameters,
                        null);
            }
                   
            #endregion
            
        }
    }



  •  Ugh.

     Eyes, goggles, nothing.

     Where's the point at which comments start to obscure code rather than clarify?  



  •  I'm guessing they have something that parses the xml out of the code comments and auto-generates documentation. Hey - they're consistent. 



  • @medialint said:

     I'm guessing they have something that parses the xml out of the code comments and auto-generates documentation. Hey - they're consistent. 

     

     Its this handy tool called Visual Studio, those autogenerated XML comments show up as Intellisense when you are invoking class members elsewhere. Exceptionally handy, and when they are color coded, they don't obscure the code like it does here.

     



  • @upsidedowncreature said:

     Ugh.

     Eyes, goggles, nothing.

     Where's the point at which comments start to obscure code rather than clarify?  


    It could be worse. They could be using assembly-style commenting.



  • The real WTF here is they are creating shitty domain objects by hand / code generation and will be hamstringed later by objects that can only C, R, U, or D themselves ;)

    It took me about three months to get my last place off shitty DALs like this (which they did with code-generation) and onto Diamond Binding (Its easy to use, it musn't be enterprisey enough).



  •  Diamond Binding is nothing more than another ActiveRecord ORM, just like nHibernate or SubSonic.

    In this project, we are avoiding use ORM's in favor of a handrolled domain objects here because of the massive amount of transactions this system must handle.

     Each domain object service inherits from this entityservice, which provides basic CRUD, but if you want anything custom, its only a matter of adding it to the subclass. No big deal.

     

     



  • Yeah I did notice it was nHibernate based. Main value for us was in the VS integration and definition syncing though - theres not much around that does that with a similar quality API. We mainly moved to it from nHibernate mainly because we got sick of mapping files, although the API for queries etc is nice to have too.

    I'm very much in favour of the abstraction and agility you get from using an ORM - querying on the domain model for starters. That said theres times (like your system it seems) where the query the ORM layer generates just isn't predictable - and I admit sometimes I've pulled out an object query thats done something unexpected (missed all the indexes or something). Still have great faith in nHibernates (and by extension DBs performance though).

     Havent touched SubSonic for a while - it didn't seem to do much more than basic CRUD. Really was irking me too - if I have to use a string identifier for anything - seems to defeat the whole type safety of a 'proper' ORM layer. (Not that DB is a lot better - it just has some const strings in Foo.Columns.Bar - but at least those are typesafe and synchronised to the schema so you get compile errors if the column is dropped or whatever).

     



  • This is not XML any more than </sarcasm> is.

    Proper XML data has to be contained in an XML document defined by a rigorous syntax format and a special document type definition. Slapping a few angle-bracketed tags into some text in the middle of a file does not make it XML, it just makes it unreadable. Consider - the way these comments are included in the source file already requires a custom parser that steps outside the defined XML standard. Why not go all the way and use a superior comment markup like doxygen or javadoc, which are both readable to humans and to machines?

    It's stupidity like this that gives XML a bad name.



  • @Arancaytar said:

    This is not XML any more than </sarcasm> is.

    Proper XML data has to be contained in an XML document defined by a rigorous syntax format and a special document type definition. Slapping a few angle-bracketed tags into some text in the middle of a file does not make it XML, it just makes it unreadable. Consider - the way these comments are included in the source file *already* requires a custom parser that steps outside the defined XML standard. Why not go all the way and use a superior comment markup like doxygen or javadoc, which are both readable to humans and to machines?

    It's stupidity like this that gives XML a bad name.

    Wait, I'm confused. The XML-style comments are the WTF? These are standard Visual Studio XML-style comments. The "custom parser" is included with VS. It's actually very handy and one of the best features of VS. When you use the method somewhere else, VS will display information about the method and its arguments, displaying what you entered. You type /// and it will autoinsert all the required tags and variable names. It can also autogenerate documentation based on your comments. Not a WTF at all, it's actually very nicely implemented.

    At least its using a standard format, unlike javadoc with its @param, etc. And the whole point of XML in general is to be human and machine readable. I really don't get why you think javadoc is just peachy but XML comments are a WTF. Its your prejudiced aversion to anything resembling XML that gives XML a bad name.



  • @Arancaytar said:

    This is not XML any more than </sarcasm> is.

    Proper XML data has to be contained in an XML document defined by a rigorous syntax format and a special document type definition. Slapping a few angle-bracketed tags into some text in the middle of a file does not make it XML, it just makes it unreadable. Consider - the way these comments are included in the source file already requires a custom parser that steps outside the defined XML standard. Why not go all the way and use a superior comment markup like doxygen or javadoc, which are both readable to humans and to machines?

    It's stupidity like this that gives XML a bad name.

    Dude.. chill. Do you expect the code editor to handle raw XML on top of the declarations?! The Visual Studio IDE uses them for IntelliSense (as has been mentioned) and can be [i]extracted[/i] automatically to a [i]proper[/i] XML file upon build. So, the comments serve three purposes.. 1) Visual commenting.. 2) IntelliSense.. 3) XML documentation output at build.



  • @upsidedowncreature said:

    Where's the point at which comments start to obscure code rather than clarify?
     

    I think that depends on the colour you assign to comments in your editor.

    Mine are light grey, for the obvious goal of having them get the fuck out of the way. I mean seriously, what twit dreamed up green comments?



  • @Jonathan Holland said:

    Its this handy tool called Visual Studio, those autogenerated XML comments show up as Intellisense when you are invoking class members elsewhere. Exceptionally handy, and when they are color coded, they don't obscure the code like it does here.

     

    Thanks for explaining, I'll have to tell my friend Swampy about that. 

    TBH even when colour coded I find this amount of commenting intrusive and pretty useless (comments of the type shown here anyway).  This might be a reaction on my part to a guy who insisted on *everything* being XML commented (and why are they referred to as XML comments).  Yea even unto a collections Count property.



  • @upsidedowncreature said:

    TBH even when colour coded I find this amount of commenting intrusive and pretty useless (comments of the type shown here anyway).  This might be a reaction on my part to a guy who insisted on *everything* being XML commented (and why are they referred to as XML comments).  Yea even unto a collections Count property.

     

    It should also be mentioned that the XML comments all fold up into one line.



  • I agree with AbbydonKrafts. I'm a huge fan of XML, but I think it's general consensus that XML tags are inherently bloaty and distracting. This may be a small cost if they make your document compatible to some standard. But like said, in this case you still need to roll a custom parser if you wanted to use them in any way. So you pay for the bloatyness but gain nothing except maybe one point on the buzzword bar.
    Javadoc comments are not an inch less standard than those things but are just much more readable.



  • @Rimpinths said:

    At least its using a standard format, unlike javadoc with its @param, etc. And the whole point of XML in general is to be human and machine readable. I really don't get why you think javadoc is just peachy but XML comments are a WTF. Its your prejudiced aversion to anything resembling XML that gives XML a bad name.

    My $.02 

    I would say @param is a standard.  Just cuz Java's the only one using it doesn't make it not so.  It just means it's only a standard for Java, and that's fine by me.  I don't think either is better than the other, but I would say the @param is more human readable and writeable than xml.  The @param only appears once per function, whereas you have to have an open and a close tag for your XML tags.

    @Rimpinths said:

    You type /// and it will autoinsert all the required tags and variable names. It can also autogenerate documentation based on your comments. Not a WTF at all, it's actually very nicely implemented.

    You've just described what Eclipse and Javadoc do, except we type /** 



  • @belgariontheking said:

    I would say the @param is more human readable and writeable than xml.  The @param only appears once per function, whereas you have to have an open and a close tag for your XML tags.
     

    The only problem with that argument is that in Visual Studio, you don't type it at all.

    To make a new XML comment, you simply enter '///' and everything else appears. Fill in your fields, collapse the comment, move on.

    For readability, I don't know anyone who would read the comment itself... The comments appear in intellisense (obviously formatted without any XML) whenever you look up the function.



  • @MasterPlanSoftware said:

    To make a new XML comment, you simply enter '///' and everything else appears. Fill in your fields, collapse the comment, move on.

    The great thing about this is that if the procedure is modified to have a new parameter, typing "p" will bring up the "param" element for the new parameter. I also add in "remarks" and "exception" elements if needed. Heck, I comment everything (enumerations and their values, etc) simply because the comments are visible in IntelliSense and Object Browser.



  • @MasterPlanSoftware said:

    @belgariontheking said:
    I would say the @param is more human readable and writeable than xml.  The @param only appears once per function, whereas you have to have an open and a close tag for your XML tags.

     

    To make a new XML comment, you simply enter '///' and everything else appears. Fill in your fields, collapse the comment, move on.

    Please see the second half of that post.  In what you quoted, I was trying to talk about the human readability, but for people who develop in vim (shudders) it goes for writeability too.

    Oh well, here it is.

    @belgariontheking said:

    You've just described what Eclipse and Javadoc do, except we type /**


Log in to reply