Posted by: horizonguy | July 3, 2010

Repository Implementation in C#

There are a few repository implementations out there in C#. Rhino Commons and S#harp Architecture, among some other one listed on codeplex.

I’ve got my own as well that is part of the CommonLibrary.NET. See the repository example here http://commonlibrarynet.codeplex.com/documentation.

3 Mistakes with Repository Implementations

1. Non-Generic CRUD names

Approach 1
public class BlogPostRepository
{
public void CreateBlogPost(Post post)...
public void UpdateBlogPost(Post post)...
public void DeleteBlogPost(Post post)
....
}

instead of
Approach 2
public class BlogPostRepository : IRepository(Post)
{
public void Create(Post post)...
public void Update(Post post)...
public void Delete(Post post)
....
}

Now the 2nd approach is much better and has the following benefits:

  • Simpler
  • Allows you to extend from a common IRepository class that contains generics based Create,Update,Delete and other methods.
  • Provides for more consistency. All your repositories look and behave the same.
  • Allows for dynamically creating entities without knowing the type. What I mean by this is that you can populate either a Post or Event object( both of which have their own repositories ) and through some reflection, you can call .Create on the appropriate repository

Further improvement

Create your repository to be even more generic

public class Repository<T> where T: class
{
public void Delete(int id)…

public void Get(int id)…

….
}

 

public class BlogPostRepository : Repository<BlogPost>

{

public void Create(T entity)…
public void Update(T entity)…

}

2. Not using a IQuery for flexible queries

The second method involves having multiple FindXXX methods.

Approach 1


public IList(Event) FindByNameAndGroup( string eventName, string group )...

public IList(Event) FindByOwner( string owner )...

 

This can easily get out hand.
Instead the following can be done:
Approach 2


public IList(Event) Find( Query query )...

// The caller would use it like so.
public static void main(string[] args)
{
...
repository.Find( Query.New().Where( e => e.Name ).Is( "asp.net" ).And( e => e.Group ).Is( "web" );
}

Now the second approach will let you handle many different queries. In this example, I’m using a combination of Expression Tree’s and Fluent API to get the Query syntax. This approach is used in the CommonLibrary.net Repository implementation. You can also create helper methods above the repository layer as in example 1 and then delegate to the repo.Find(Query) method on the repository instead of creating multiple FindXXX methods in the repository.

Note: You can also use C#’s Expression Tree purely to accomplish the same effect, for example in Entity Frameworks Find(Expression exp ) methods.

One step further

Now with C# 4.0 dynamic and Expando Object. You can possibly build dynamic find/search method using a ruby rails like style.

e.g.

repo.FindByNameAndOwner(“asp.net”, “kishore”);

where:

1. FindByNameAndOwner is a dynamic method on an expando object.

2. You get the fields to search for using the name of the method ( Name, and Owner) and use the parameters for those variables.

3. You get the condition from the name of the method. ( “NameAndOwner” )

 

3. Audit fields

Finally, the last problem that I see, is that each entity that is persisted by a repository should have the following audit fields.

  1. Id
  2. CreatedBy
  3. UpdatedBy
  4. CreateDate
  5. UpdateDate
Posted by: horizonguy | June 11, 2010

ASP.NET MVC CMS – Using CommonLibrary.NET

My approach to the CommonLibrary.NET CMS ( ASP.NET MVC w/ C# 3.5 / 4. 0)

This is a 3rd post in the CMS series of posts.

There are a few principles I’m following when developing this ASP.NET MVC CMS.

  • Simple / Lightweight
  • Library/Frameworks – CommonLibrary.NET framework is generic enough for any development, not just web based ). It’s also completely separate from the CMS.
  • ActiveRecord based entities : To quickly generate / manage entities.
  • Code Generation – Use model schemas to generate your repositories, sql install files, UI’s ( much like ruby rails )
  • Agnostic Storage / Persistance – Entities can be persisted to either a database, file, in-memory, or other storage facility, using the same API, but different IRepository<T> implementations.
  • Minimal configuration
  • No Imposing CMS Framework – Using ASP.NET MVC, theorhetically, you can file copy the 1) CMS dlls, 2) CMS Views/folders, and just do some basic configuration for routes/global.aspx and that’s it. Basically you get a CMS system into your own site by simply copying a dlls, view folders. You’r application is not built into the CMS, but the CMS is fit into your app.
  • Import / Export as core feature – Import / Export of any model/entity type should be fully supported. This means import/export of data in/from xml, csv, ini, json, yaml formats.
Posted by: horizonguy | June 11, 2010

ASP.NET MVC CMS ( Thoughts, Reviews, Projects )

Just getting back into blogging after a long break. I’m developing an ASP.NET MVC CMS ( using my framework CommonLibrary.NET ).

Before I mention the specifics of my CMS, I do want to state that there are some rather good implementations of .NET based CMS systems. Let me first outline some of the available CMS products in .NET. I’ve used all the itemsThen I’ll talk about limitations I’ve found w/ CMS systems in general and then I’ll discuss the latest MVC 2 framework a bit.

OpenSource CMS Systems

  • DNN ( Dot Net Nuke )
  • Umbraco
  • Mojo Portal
  • BlogEngine.NET
  • N2
  • Kooboo
  • Graffiti CMS
  • Oxite / Orchard ( Microsoft’s CMS )

Commercial CMS Systems ( They also offer free versions )

  • Community Server
  • Kentico
  • SiteFinity
  • SiteCore

(NOTE: I’ve used DNN, BlogEngine, MojoPortal in the past, used Umbraco, N2, KooBoo less so and only ran orchard for demo purposes  and reviewed it’s codebase)

DNN

All in all, DNN has been around for a long time, has a huge user-base, it’s stable, may have had some performance issues in the past, but the team is/has continually improved the product. In addition, it’s got probably the most modules/plugins out there. All in all it’s pretty good. It is however developed in VB.NET( which is fine ) and the code base is quite old but being updated ( understandably so, given it’s been around a long time). And it’s currently targeting the C# 3.5 with ASP.NET WebForms.

BlogEngine.NET

I believe BlogEngine.NET is probably the lightest/simplest blogging engine w/ some CMS features. You can easily set it up and customize it fairly easily as well. Plus it doesn’t need to run against a database. Installation is a breeze(not much to actually install really). It’s written in ASP.NET 2.0 Web Forms with plans to upgrade and target 3.5/4.0.

MojoPortal

This is quite good as well. I found the usability of this to be very nice. It supports MySql, PostGres, SqlLite, MsSql among others. The codebase seems a bit big however and not as simple as BlogEngine.NET but this has a lot of features, from forums, to polls, to surveys. Install is fairly easy as well. It’s been upgraded to target 3.5 / 4.0 WebForms as of this writing.

Umbraco

Umbraco is elegant, it’s also fairly easy to use and really seems optimized for content/page management. It also has good support, documentation. The problem is not being able to run in medium-trust which many people complain about. I want a simple system install/development environment to run/test in. They are also looking to upgrade to 3.5/4.0

Oxite/Orchard

Now orchard is the successor to microsoft’s Oxite blog/cms platform which hasn’t been embraced by the community that well. Orchard however is getting a lot of attention these days it seems. I’ve played around with it a bit, reviewed the code base. It’s UI is quite nice, it’s dashboard is very simple. And of course it looks / acts very much like wordpress / blogger or any other high-end blogging site. The codebase is very big (especially for an MVC which i personally feel should “lighten” the load/code ). But still the codebase is still put together quite well. It also support multiple tenants( meaning muliple bloggers on one site, much like wordpress ). What I don’t understand is why microsoft is geting into this market. I agree w/ some of the reviews that were on it’s codeplex site. It is a strange position for them to be in, especially when so many of the open-source community members they are supporting, are building CMS systems and/or trying to make. Nevertheless, it’s still looks very interesting as a CMS/blog. This is also ASP.NET MVC based with the target framework of 3.5 I believe.

KooBoo – N2 – Graffiti CMS

Now as for the others, Kooboo, N2, GraffitiCMS, I personally haven’t used them as much as I would like have had to. And therefore, I won’t review them in detail as it wouldn’t be a fair/realistic evaluation. That being said, just from a superficial perspective of the codebase, the features, and demo’s, they also seem solid. Now all the other products in the open-source list for the most part are running either in 2.0 or 3.5 with WebForms, some type of hybrid WebForms/MVC or as mostly MVC.


Problems of the Hybrid “Web Application” + “CMS”

There are typically 3 types of CMS/Web App usecases.

1. A pure CMS system for only content.

2. A custom web system which needs some “CMS” features.

3. The opposite to # 2 which is a CMS sytem which needs custom features.

Now, regardless of whether you’re use case is #2 or #3 I found the following problems:

  • Imposing Framework – One problem that I found w/ CMS systems in general are that fact that you almost have to retrofit your application to use the CMS. For example, let’s say you wanted to create your own modules/components, for the most part, you stuck w/ having to fit your component and wire them into the CMS’s framework. You’re going to have to do some wiring up/integration to some degree but the biggest problem I’ve found is “how much”. I don’t want to have to write a component w/ certain limitations/guidelines just so that it can hook into the CMS. There might be parts to your application that specifically do not need the CMS and some parts that need it.
  • Customizations – If you need to build your application with customizations, then the degree to which you have to conform to you using the CMS systems framework can be a problem, ( this is somewhat related to “imposing framework”
  • Complexity – How complex is the CMS / framework
  • Testability – Testability of the components and/or customizations that you develop for the CMS


Posted by: horizonguy | October 18, 2008

Optimize a URL for SEO using C#

Below is some code you can use to generate a valid optimized URL for webpages.

Example: Given the title of the post, it will generate what the url should be for URL rewriting for SEO optimization.
Url: http://www.knowledgedrink.com/View-Class-Workshop-Details.aspx?postId=480
Post Title: How to SEO optimize site
Output title: how-to-seo-optimize-site
Final Url: http://www.knowledgedrink.com/class-workshop-how-to-seo-optimize-site-480.aspx

Unit Tests:
Unit tests have been done on the code.
Here is a sample of the input title, and output title.

Input Output
1. “Too—many—dashes”      

 “too-many-dashes”      

2. “Too many spaces”     

 “too-many-spaces”     

3. “Too ^&* many ;’\”[]\\_+= invalidChars”     

 “too-many-invalidchars”     

4. “Really~1@# Bad-*7s;:Title”     

 “really1-bad-7stitle”     

5. “This is a post about optimizing a title”     

 “this-is-a-post-about-optimizing-a-title”     

    /// <summary>
    /// Url optimizer utility class.
    /// </summary>
    public class UrlSeoOptimizer
    {
        /// <summary>
        /// Map of invalid characters that should not appear in
        /// an SEO optimized url.
        /// </summary>
        private static IDictionary<char, bool> _invalidChars;
        /// <summary>
        /// String containing each invalid character.
        /// </summary>
        public const string InvalidSeoUrlChars = @”$%#@!*?;:~`_+=()[]{}|\'<>,/^&””.”;

       
        /// <summary>
        /// Initialize the list of mappings.
        /// </summary>
        static UrlSeoOptimizer()
        {
            char[] invalidChars = InvalidSeoUrlChars.ToCharArray();
            _invalidChars = new Dictionary<char, bool>();

            // Store each invalid char.
            foreach (char invalidChar in invalidChars)
            {
                _invalidChars.Add(invalidChar, true);
            }
        }
        /// <summary>
        /// Generates an SEO optimized url.
        /// </summary>
        /// <param name=”url”></param>
        /// <returns></returns>
        public static string GenerateUrl(string title)
        {
            // Validate.
            if (string.IsNullOrEmpty(title)) return string.Empty;

            // Get all lowercase without spaces.
            title = title.ToLower().Trim();

            StringBuilder buffer = new StringBuilder();
            char currentChar, lastAddedChar = ‘a’;

            // Now go through each character.
            for (int ndx = 0; ndx < title.Length; ndx++)
            {
                currentChar = title[ndx];
               
                // Invalid char ? Go to next one.
                if ( _invalidChars.ContainsKey(currentChar) )
                {
                    continue;
                }

                // Handle spaces or dashes.
                if (currentChar == ‘ ‘ || currentChar == ‘-‘)
                {
                    // Only add if the previous char was not a space or dash (‘ ‘, ‘-‘).
                    // This is to avoid having multiple “-” dashes in the url.
                    if (lastAddedChar != ‘ ‘ && lastAddedChar != ‘-‘)
                    {
                        buffer.Append(‘-‘);
                        lastAddedChar = ‘-‘;
                    }
                }
                else
                {
                    buffer.Append(currentChar);
                    lastAddedChar = currentChar;
                }               
            }
            return buffer.ToString();
        }
    }

Posted by: horizonguy | July 5, 2008

Best practice checklist – Application Architechture

Application Architechture:

  • Make architecture layered ( BLL, DAL, Service, etc.., or use Plugin Model )
  • Make use of Domain driven design ( Real world business objects )
  • Make use of an IoC container ( Spring IoC, Castle Windsor )
  • Make use of MVC, Services, to prevent business logic in UI
  • Make sure to integrate a validation scheme(MS App Block, Spring)
  • Make use of declarative programming / attributes to simplify code
  • Make use of Aspects to simplify code
  • Make sure to include immediate support for automated Unit Testing
  • Make application very API based using layers and TDD
  • Make sure to support Import / Export functionality for business/testing
  • Use separate projects for generic utility code
  • Use separate projects for unit tests
  • Use separate projects for provider model implementations
  • Use Frameworks and libraries where appropriate
  • Use provider model to avoid excessive dependence on frameworks
  • Use ORM for non-performance intensive persistence
  • Support common requirements (Caching / import and export)
Posted by: horizonguy | July 5, 2008

Best practice checklist – Database Principles

Database Principles:

  • Make use of and enforce conventions and standards
  • Perform database testing (Database persistence code)
  • Make database scripts ( clearing out test data, common queries )
  • Make sure to backup database schema for each release (text file)
  • Make schema upgrade scripts (rather than manual updates)
  • Make it easy to store reference data
  • Make use of ORM libraries where appropriate ( NHibernate.NET, IBatis )
  • Make sure to apply indexes where appropriate
  • Make use of database paging if neccessary
  • Make sure to use functions
  • Make sure to prevent sql injection
Posted by: horizonguy | July 5, 2008

Best practice checklist – Tools of the trade

Tools of the trade:

  • Use testing tools ( NUnit, MSBuild, CruiseControl.NET )
  • Use scripting tools ( NAnt, VBScript )
  • Use code metric tools ( NCover, FXCop, Simian, devAdvantage)
  • Use visual design / diagram tools ( Visio )
  • Use File / Folder comparison tools ( Beyond Compare, ExamDiff )
  • Use code generation tools ( Code Smith, Resharper )
  • Use Refactoring tools ( Resharper )
  • Use database related tools ( Sql Compare by RedGate )
  • Use powerful text editors ( TextPad, NotePad++, SlickEdit )
  • Use performance testing tools ( Antz, DotTrace )
  • Use language feature tools ( Regulator, Reflector )
  • Use of frameworks where applicable ( NHibernate, SpringFramework )
  • Use of libraries where applicable ( UrlRewriter.net, MS App Blocks )
Posted by: horizonguy | July 5, 2008

Best practice checklist – Design principles

Design principles:

  • Use Gang Of Four design patterns where appropriate
  • Use Single Responsibility Principle as much as possible
  • Use Open-Closed Principle
  • Use interfaces to design by contract and reduce coupling
  • Use MVP / MVC – (Presenter, Controller, Service, Dao)
  • Use ORM – (Object Relational Mapping) where appropriate
  • Use DAO’s / Repositories for persistance
  • Use IoC – (Inversion of Control, Dependency Injection)
  • Use Service Locator where appropriate
  • Use Declarative Programming
  • Use AOP – (Aspect-Oriented Programming)
  • Use Provider model to get Framework / library independence
Posted by: horizonguy | July 5, 2008

Best practice checklist – Common Application Features

Common Application Features:

  • Support runtime configuration settings management
  • Support runtime reference data / meta-data management
  • Support runtime cache management
  • Support runtime security via Users / roles / membership management
  • Support job scheduling
  • Support runtime error-log viewing
  • Support Simple Reporting
  • Support Import / Export of data into and out of application
  • Support for user specific settings
  • Support simple / advanced searches
  • Support messaging and notifications of important actions
Posted by: horizonguy | July 5, 2008

Best practice checklist – Testing and Quality Control

Testing And Quality Control:

  • Make sure to develop using Test-Driven development
  • Make sure tests cases are well documented
  • Make sure all automated tests pass before deploying to QA
  • Make sure non-automated test cases pass before deploying to QA
  • Make sure to do group testing (Multi-user) before deploying to QA
  • Make sure to test different environments (IE versus Fire Fox)
  • Make sure business users have tested new functionality
  • Make sure to test for performance and memory leaks
  • Make sure to continuously expand on automated testing

Older Posts »

Categories

Follow

Get every new post delivered to your Inbox.