Saturday, November 29, 2008

Generic DAO with LINQ to SQL

One of the first thing I try to implement when learning a new programming language is a Generic Data Access Layer. I hate to write repetitive code and always try to find ways of working around this. I managed to implement this in Java and PHP and had no doubt that .NET will allow me to do so. After a good bunch of reading on the net and playing around with the tutorials for a while now, I managed to implement Generic DAL by using LINQ to SQL.  Here is what I did:

[ Step 1 ]:

I created a seperate Class Library to Generate all my Business Objects and handle all my Data Access Objects (DAO). In this Class Library I created a a LINQ to SQL Data Context and named it UTSDataContext.

[ Step 2 ]:

I then created a Generic class which had two Parameterized Type variables one being the class representing a Business Object and the other being the Primary Key type.

public class GenericDAO<E, K> where E : class

[ Step 3 ]:

I then added all methods that will carry out CRUD tasks. The code for the Generic DAO is as follows:

public class GenericDAO<E, K> where E : class
    {
        private UTSDataContext context = new UTSDataContext();

        public UTSDataContext Context
        {
            get { return context; }
            set { context = value; }
        }

        public virtual void save(E instance)
        {

            this.save();
        }

        public virtual void save()
        {
            context.SubmitChanges();
        }

        public virtual List<E> selectAll()
        {
            return context.GetTable<E>().ToList();
        }

        public virtual void insert(E instance)
        {

            context.GetTable<E>().InsertOnSubmit(instance);
            context.SubmitChanges();
        }

        public virtual void remove(E instance)
        {
            context.GetTable<E>().DeleteOnSubmit(instance);
            context.SubmitChanges();
        }

        public String getKeyProperty()
        {
            String primaryKeyFieldName = typeof(E).Name + "Id";
            return primaryKeyFieldName;
        }

        public Expression<Func<E, bool>> getLambaKey(K id)
        {

            var parameter = Expression.Parameter(typeof(E), "e");
            var propId = Expression.Property(parameter, typeof(E).GetProperty(getKeyProperty()));

            return Expression.Lambda<Func<E, bool>>(Expression.Equal(propId, Expression.Constant(id)), parameter);
        }

        public E findById(K id)
        {
            return context.GetTable<E>().Single(getLambaKey(id));
        }
    }
}

Limitations

(1) I am not in REFLECTIONS yet in order to identify primary key property field through annotations. As such, all my primary key fields are named as follows:

Exact Table Name +"Id"

For Example, the table Department will have DepartmentId as primary key Field.

 

(2) There are some reasons why an Object will no longer reside in LINQ Context and as such not be monitored for Changes. The most frequent one being Deserialisation. For example, if you stored an Object in session and retrieved it later on, you will have to fetch the object again from database (by using its Primary Key Identifier perhaps) and then write the changes to it.

Tuesday, November 25, 2008

ASP.NET Security, Authentication and Authorization

Security is one of the major features in a web application. A good way of providing reliable security in your web application is to use a tried and tested solution which follows known standards. ASP.NET's security mechanism is outstandingly beautiful. As a side note here, I have  good experience with Java Authentication and Authorization Service and the brillant Seam Security Implementation which uses underlying Java Security mechanisms.

ASP.NET though, provides the simplest way of implementing security in a web application. Authentication and Authorization has all been taken care of with even the possibility of customization. To demonstrate this, here are the various steps I have been carrying out:

(1) Configure your web application to use Membership and Role Management by adding the following in your web.config

<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
  <providers>
    <clear />
    <add
      name="SqlProvider"
      type="System.Web.Security.SqlMembershipProvider"
      connectionStringName="SimpleSqlConnection"
      applicationName="MyApplication"
      enablePasswordRetrieval="false"
      enablePasswordReset="true"
      requiresQuestionAndAnswer="true"
      requiresUniqueEmail="true"
      passwordFormat="Hashed" />
  </providers>
</membership>

<roleManager enabled="true" defaultProvider="CustomizedRoleProvider">
  <providers>
    <add name="CustomizedRoleProvider"
         type="System.Web.Security.SqlRoleProvider"
         connectionStringName="SimpleSqlConnection" />
  </providers>
</roleManager>

(2) Make sure that the connection string you specify here exists in your connection string settings in the web.config file

(3) Now using the Visual Studio Command Prompt type aspnet_regsql.exe to launch the ASP.NET SQL SERVER SETUP Wizard and configure your database with the required tables for security

(4) Once this is done, in Visual Studio IDE, launch the ASP.NET WEB SITE ADMINSTRATION TOOL (Click on Project -> ASP.NET Configuration )

(5) Click on the Security Tab and use the Security Wizard to create roles, users along with roles, and access rules

(6) ASP.NET comes with a variety of pre build login controls for Login, Authenticated User Information display and Logout

For Login Control, the code is as follows:

<div>
        <asp:Login DisplayRememberMe="false" ID="LoginControl" runat="server"/>
    </div>

For User Information Display

<asp:LoginView ID="LoginViewControl" runat="server" Visible="true">
    <AnonymousTemplate>
        <asp:HyperLink NavigateUrl="~/general/login.aspx" Text="Please Login"/>
    </AnonymousTemplate>
    <LoggedInTemplate>
        <table>
            <tr>
                <td>
                   Welcome <asp:Label ID="LoginUserName" runat="server"/>
                </td>
            </tr>
            <tr>
                <td>
                    You are logged in as <asp:Label ID="LoginRoles" runat="server"/>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:LoginStatus ID="LoginStatusControl" runat="server" />
                </td>
            </tr>
        </table>
    </LoggedInTemplate>
</asp:LoginView>

Hope its also a cruise for you.

Friday, November 21, 2008

Learning LINQ to Entities as compared to Hibernate

It took me hardly two days to implement a Generic Data Access Layer on .NET 3.5 SP1 by using LINQ to Entities. The first time I worked on an ORM solution (Hibernate) was on a project for the Danish Commerce and Companies Agency around two and a half years before. It took us around one week to set up Hibernate and even after the system went into production we had problems with performance and memory leaks which were later fixed by the folks at hibernate. Of course, hibernate is open source and sure it is much more powerful but still is has its lots of problems. Earlier this year, together with my team at M-ITC LTD, we built an in house ORM solution (TinyORM) by using annotations and reflection APIs. We wanted something simple without any persistence and usage of traditional SQL. We further extended this solution to provide support for Oracle PLSQL for the needs of our client. Performance wise, we were far better than Hibernate and it was superb experience. Object Relational Mapping has been in software development for a while now. Every language I have been into now has such implementations. However, LINQ to Entities (DLINQ as it was called in the past) and Entity Framework are to me the most promising. Coupled with Dynamic Data Framework, they can be of great effect in enterprise applications.

Until now my .NET learning has been going on all so good. I am really impressed with the speed at which I can develop features in my application as compared to JAVA. I still feel that JAVA is much more powerful though. Perhaps, its all down me having much more experience in JAVA. Hopefully, one year from now, I will unleash its full potential.

Tuesday, November 18, 2008

SOFTWARETEAMS now in Quatres Bornes

Since October, our company has been operating under a new brand. SOFTWARETEAMS now located in Quatres Bornes and together with new partners is now well in place and hopefully our major projects will kick off soon. I have been busy for the past month or so in the set up of our new infrastructures both here and in Denmark. University assignments and class tests have also been taking a lot of my precious time. Now that all of that are behind me I will be able to post some of my findings here.

Throughout the past month, I have mainly been focusing on some research into performance issues with Entity Framework. Having worked with Hibernate for the past two years, the amount of problems I have had with this framework with regards to concurrency, performance and other bottlenecks have only been discouraging. To workaround these problems, I have even developed, with the help of my team of course, an in-house ORM solution (TinyORM) for the needs of the CBS Housing Project. I don't want to repeat the same mistakes and throughout the various reviews and comments I have been looking, most of the conclusion sees to indicate that Entity Framework though promising is not there yet ! Instead, they recommend using LINQ to SQL Classes. So here I am now trying to implement a Generic Data Access Layer with LINQ SQL. My next post will discuss the architecture and implementation issues. Stay tuned !