best practices

Method, Delegate and Event Anti-Patterns in C#

October 28, 2013 CSharp, Visual Studio , , , , ,

No enterprise application exists without a method, event, delegate and every developer would have written methods in his/her application.  While defining these methods/delegates/events, we follow a standard definitions.  Apart from these definitions there are some best practices that one should follow to ensure that method does not leave any object references, other methods are called in appropriate way, arguments to parameters are validated and many more. 

This article outlines some of the anti-patterns while using Method, Delegate and Event and in-effect highlights the best practices to be followed to get the best performance of your application and have a very low memory footprint.

The right disposal of objects

We have seen multiple demonstrations that implementing IDisposable interface (in class BaseClass) and wrapping its object instance in ‘using’ block is sufficient to have a good clean-up process.  While this is true in most of the cases, this approach does not guarantee that derived classes (let’s say DerivedClass) will have the same clean-up behaviour as that of the base class.

To ensure that all derived classes take responsibility of cleaning up their resources, it is advisable to add an additional virtual method in the BaseClass that is overridden in the DerivedClass and cleanup is done appropriately.  One such implementation would look like,

  1. public class BaseClass : IDisposable
  2. {
  3.     protected virtual void Dispose(bool requiresDispose)
  4.     {
  5.         if (requiresDispose)
  6.         {
  7.             // dispose the objects
  8.         }
  9.     }
  10.  
  11.     public void Dispose()
  12.     {
  13.         Dispose(true);
  14.         GC.SuppressFinalize(this);
  15.     }
  16.  
  17.     ~BaseClass()
  18.     {
  19.         Dispose(false);
  20.     }
  21. }
  22.  
  23. public class DerivedClass: BaseClass
  24. {
  25.     // some members here    
  26.  
  27.     protected override void Dispose(bool requiresDispose)
  28.     {
  29.         // Dispose derived class members
  30.         base.Dispose(requiresDispose);
  31.     }
  32. }

This implementation assures that the object is not stuck in finalizer queue when the object is wrapped in ‘using’ block and members of both BaseClass and DerivedClass are freed from the memory

The return value of a method can cause a leak

While most of our focus is on freeing the resources used inside the method, it is the return value of the method that also occupies memory space.   If you are returning an object, the memory space occupied (but not used) is large

Let’s see some bad piece of code that can leave some unwanted objects in memory. 

  1. public void MethodWhoseReturnValueIsNotUsed(string input)
  2. {
  3.     if (!string.IsNullOrEmpty(input))
  4.     {
  5.         // value is not used any where
  6.         input.Replace(" ", "_");
  7.  
  8.         // another example
  9.         new MethodAntiPatterns();
  10.     }
  11. }

Most of the string methods like Replace, Trim (and its variants), Remove, IndexOf and alike return a ‘new’ string value instead of manipulating the ‘input’ string.  Even if the output of these methods is not used, CLR will create a variable and store it in memory.  Another similar example is creation of an object that is never used (ref: MethodAntiPattern object in the example)

Virtual methods in constructor can cause issues

The heading speaks for itself.  When calling virtual methods from constructor of ABaseClass, you can not guarantee that the ADerivedClass would have been instantiated.

  1. public partial class ABaseClass
  2. {
  3.     protected bool init = false;
  4.     public ABaseClass()
  5.     {
  6.         Console.WriteLine(".ctor – base");
  7.         DoWork();
  8.     }
  9.  
  10.     protected virtual void DoWork()
  11.     {
  12.         Console.WriteLine("dowork – base >> "
  13.             + init);
  14.     }
  15. }
  16.  
  17. public partial class ADerivedClass: ABaseClass
  18. {
  19.     public ADerivedClass()
  20.     {
  21.         Console.WriteLine(".ctor – derived");
  22.         init = true;
  23.     }
  24.  
  25.     protected override void DoWork()
  26.     {
  27.         Console.WriteLine("dowork – derived >> "
  28.             + init);
  29.             
  30.         base.DoWork();
  31.     }
  32. }

 

Use SecurityCritical attribute for code that requires elevated privileges

Accessing of critical code from a non-critical block is not a good practice.

Mark methods and delegates that require elevated privileges with SecurityCritical attribute and ensure that only the right (with elevated privileges) code can call those methods or delegates

  1. [SecurityCritical]
  2. public delegate void CriticalDelegate();
  3.  
  4. public class DelegateAntiPattern
  5. {
  6.     public void Experiment()
  7.     {
  8.         CriticalDelegate critical  = new CriticalDelegate(CriticalMethod);
  9.  
  10.         // Should not call a non-critical method or vice-versa
  11.         CriticalDelegate nonCritical = new CriticalDelegate(NonCriticalMethod);
  12.     }
  13.  
  14.     // Should not be called from non-critical delegate
  15.     [SecurityCritical]
  16.     private void CriticalMethod() {}
  17.         
  18.     private void NonCriticalMethod() { }
  19. }

 

Override GetHashCode when using overriding Equals method

When you are overriding the Equals method to do object comparisons, you would typically choose one or more (mandatory) fields to check if 2 objects are same.  So your Equal method would look like,

  1. public class User
  2. {
  3.     public string Name { get; set; }
  4.     public int Id { get; set; }
  5.  
  6.     //optional for comparison
  7.     public string PhoneNumber { get; set; }
  8.  
  9.     public override bool Equals(object obj)
  10.     {
  11.         if (obj == null) return false;
  12.  
  13.         var input = obj as User;
  14.         return input != null &&
  15.             (input.Name == Name && input.Id == Id);
  16.     }
  17. }

 

Now this approach checks if all mandatory field values are same.  This looks good in an example for demonstration, but when you are dealing with business entities this method becomes an anti-pattern.  The best approach for such comparisons would be to rely on GetHashCode to find out if the object references are the same

  1. public override bool Equals(object obj)
  2. {
  3.     if (obj == null) return false;
  4.  
  5.     var input = obj as User;
  6.     return input == this;
  7. }
  8.  
  9. public override int GetHashCode()
  10. {
  11.     unchecked
  12.     {
  13.         // 17 and 23 are combinations for XOR
  14.         // this algorithm is used in C# compiler
  15.         // for anonymous types
  16.         int hash = 17;
  17.         hash = hash * 23 + Name.GetHashCode();
  18.         hash = hash * 23 + Id.GetHashCode();
  19.         return hash;
  20.     }
  21. }

You can use any hashing algorithm here to compute a hash of an object.  In this case, comparisons happen between computed hash of objects (int values) which will be more accurate, faster and scalable when you are adding new properties for comparison.

Detach the events when not in use

Is it necessary to remove event handler explicitly in C#?  Yes if you are looking for lower memory footprint of your application.  Leaving the events subscribed is an anti-pattern.

Let’s understand the reason by an example

  1. public class Publisher
  2. {
  3.     public event EventHandler Completed;
  4.     public void Process()
  5.     {
  6.         // do something
  7.         if (Completed != null)
  8.         {
  9.             Completed(this, EventArgs.Empty);
  10.         }
  11.     }
  12. }
  13.  
  14. public class Subscriber
  15. {
  16.     public void Handler(object sender, EventArgs args) { }
  17. }

Now we will attach the Completed event of Published to Handler method of Subscriber to understand the clean up.

  1. Publisher pub = new Publisher();
  2. Subscriber sub = new Subscriber();
  3. pub.Completed += sub.Handler;
  4.  
  5. // this will invoke the event
  6. pub.Process();
  7.             
  8. // frees up the event & references
  9. pub.Completed -= sub.Handler;
  10.  
  11. // will not invoke the event
  12. pub.Process();
  13.  
  14. // frees up the memory
  15. pub = null; sub = null;

After the Process method has been executed the Handler method would have got the execution flow and completed the processing.  However, the event is still live and so are its references.  If you again call Process method, the Handler method will be invoked.  Now when we unsubscribe (-=) the Handler method, the event association and its references are freed up from the memory but objects pub and sub are not freed yet.  When pub and sub objects are assigned null, they are marked for collection by GC.

If we do not unsubscribe (-=) and keep other code AS-IS – GC will check for any live references for pub and sub and it will find a live event.  It will not collect these objects and they will cause a memory leak.  This common anti-pattern is more prevalent in UI based solutions where the UI events are attached/hooked to code-behind / view-models / facade.

Following these practices will definitely reduce your application’s footprint and make it faster.

Silverlight Best Practices (Part 4 of 4)

November 25, 2011 CSharp, Silverlight, Visual Studio , , ,

This is in continuation to my previous post Silverlight Best Practices – III, where the focus was what should be and what should not be done while developing a Silverlight Application. It was purely from a developer’s perspective.  In this post, we would consider designing the ‘Data Access Layer’

Designing Data Access Layer

In most of the web applications, data access layer comprises of 3 components:

  • Utilities – that help in accessing data components. Example, converters and alike
  • Data components – core components that access the data sources
  • Service Agents – this is an additional layer (proxies) over the services that are called from DAL. Mostly done to bring an additional isolation, entity mapping, or service-specific conversions.

Here, we will concentrate on ‘Data Components’ as the other two components are relatively easier to design and readily available as well or tools can generate them too. 

Managing Connections

Which connection remains open/closed should be monitored by a single interface. All calls should be redirected to a single function which would manage opening, closing of a connection and its timeout.  Connections can be cached for smallest duration of time to increase performance – however, security should of sensitive information like hostname, password should be taken care of as well.

The application should also take care that the fan-out does not reach.  This will ensure that no user gets a timeout error.

Design should enable switching between two replicas of data sources. This is most important during maintenance shutdown, or release of a newer version of application, or when database crashes. 

Exception Handling

DAL should ideally handle all exceptions and should not crash in any scenario; however all CRUD operations MUST be handled by DAL.

Exceptions concerning data access (data source unavailable, timeout, etc) should be handled by DAL; while other business related errors should be returned in an Error object in a serialized format.

Profile for best performance

In Internet applications DAL is the most accessed-by, making it prone to crashes and security risks.  Profiling of DAL is must to gauge the impact of high number of concurrent users.  Also, in such scenario DAL should be prevented against attacks from hackers.  Any other source of access should be give least privilege and only the web application should be at a higher privilege.

Consider using Batch Processes to reduce round-trip to database server.

Managing data

One of the common problems seen in many projects while doing profiling exercises is degraded performance due to improper data handling.  So let us see some important guidelines:-

  • If the system involves lot of documents and image storing – prefer to store them in BLOB, than on a file system
  • Avoid Outer Joins wherever possible
  • Use of cursors should not be preferred – use in-memory temporary tables instead.
  • Open connections as late as possible.
  • Use XML pameters for bulk inserts or updates – this will save execution time.
  • Use parameterized SQL statements and typed parameters to mitigate security issues and reduce the chance of SQL injection attacks succeeding.
  • Do not use string concatenation to build dynamic queries in the data layer.
  • Use typed parameters as input values to the procedure and output parameters to return single values.
  • Use optimistic concurrency with non-volatile data to mitigate the cost of locking data in the database

 

Dynamic Queries or Stored Procedure

 

  1. For a small footprint application with lesser clients and few business rules, prefer Dynamic Queries. IF NO, STEP 2
  2. Larger application, multiple clients – abstraction can be at
    1. Database level in Stored Proc – minimal code changes
    2. DAL using patterns  – best till the schema does not change, can be debugged
    3. DAL using ORM – best till the schema does not change, can be debugged

 

ADO.NET Services

I would suggest a very good tutorial on MSDN. Click here to read through.

This concludes the series of best practices articles on Silverlight. Thanks for reading them through!


Silverlight Best Practices (Part 2 of 4)

November 16, 2011 Silverlight, Visual Studio , , ,

This is in continuation to my previous post Silverlight Best Practices – I, where I talked about Design Considerations.  These design considerations were a bird’s view and the posts to come will explain these in detail.  In this post, I shall deal with the Business Layer, its components, steps to design these components, and design considerations.  This post can be considered not just for Silverlight Applications, but for other Web Applications as well.

Business Layer

 

Let us take on the parts of the business layer for those who are newbie

  1. Application Façade – layer that combines multiple business operations into single message based operation
  2. Business Components – Business Rules & Validations
  3. Entities – Used to pass data between business components
  4. Business Workflow – Multi-step and/or long-running business process

Design Considerations

 

Before you jump into designing of business layer, it is advisable to do these

 

  1. Identify ACTORS or CONSUMERS
  2. How these ACTORS will communicate to your business layer.
    1.  Concurrency needs to be addressed for access to STATIC data.
    2.  Long-running transactions should not LOCK the data.
  3. SECURITY requirements for business layer
    1.  Apply AUTHENTICATION wherever required.
    2. Use SSO where appropriate.
  4.  VALIDATION and EXCEPTION HANDLING strategies
    1. DONOT RELY on validations at presentation layer – reuse the VALIDATION logic.
    2. Should NOT reveal sensitive information to the end user.
    3.  Should NOT use exceptions for application logic.
    4.  Log SUFFICIENT detail from exceptions.

Authentication & Authorization Module Design

Authentication is not a mandate requirement and should be done if the Business Layer is to be used by several clients.  An easier said – public web services need authentication, but an application oriented service does not.

Consider IP filtering to restrict hacks and unauthorized usage or to have access only through the presentation layer.

For business decisions –role based or claim based authorization needs to be implemented.

Impersonation can screw-up your performance. So prefer avoiding it.

Business Components & Entities

Keep them light and encapsulated.  Do not mix data access logic and business logic. Break them into two assemblies. Volatile business rules ought to be kept in rules engine (Workflow, DROOLS.NET, etc)

Use ONLY CUSTOM objects as Business Entities, even if it means encapsulating only a string object.

Choose between the three patterns while designing these entities-

  • Table Module Pattern – this is typically used when database tables can represent entities.  This model is suited for large database applications or applications that use LINQ to SQL.
  • Domain Module Patter – this pattern is widely used for stateful application that has complex business rules.
  • XML – this is used for relatively smaller applications.

Serialize your objects if it requires passing between network boundaries.


Caching and Concurrency

Appropriate caching mechanism can speed up your performance by leaps and bounds by avoiding duplicate processing.  To avoid client delays, caching should be a background process.

Cache the data (non-sensitive ONLY) in a ready-to-use format.  In other words, data taken from cache should not necessarily require processing before use.  Caching resources should avoid locks due to threading.

Use connection based transactions to access single data source. Which means – a rollback should let you get back to previous state. When a rollback or commit cannot be applied (for processes that are long-running), then compensating methods should be in place. 

Logging and Audit Mechanism

Logging and Auditing cannot be compromised at an enterprise level application.  It can open doors to threats without getting noticed.  Auditing, if generated at granular level, can let us know precise time, IP, location of resource access.

One can use Enterprise Library or any other component to implement logging mechanism – but it needs to be centralized.   However unexpected failure of this centralized block should not cause stop the business functionalities.

Workflows

 

Windows Workflow is a great-gift by Microsoft to the technologies. Workflows – state machine or sequential – should be initiated on a separate thread for long-running process.  Faulty conditions should be handled as exceptions. 

Deployment

Towards the end, an incorrect deployment will surely not deliver excellent results. Use TCP protocol and SSL to support remote business layer in a safe manner.

 

The next to come in this series will be a post on what not to do in Silverlight while developing an application. This will focus on best practices that a developer needs to take care of.

 

Silverlight Best Practices (Part 3 of 4)

November 10, 2011 Silverlight, Visual Studio , , ,

[Republished after additions]

This is in continuation to my previous post Silverlight Best Practices – II, where I talked about Business Layer Design Considerations.  This post, the area of concentration, will be a list of to-do’s while developing a Silverlight Application.

Development Tactics and Practices

Defacing Errors

One of the regular application development exercise is debugging and debugging errors in Silverlight applications can be really tough job if your default browser is Chrome. I’m not sure whether there is problem with Chrome, or with Silverlight IDE, or something else – but until today, the breakpoint will not be hit in Chrome. Hence, prefer using Internet Explorer.

Using Team Foundation Servers (TFS)

Silverlight developers often struggle setting up a source-safe (read TFS) within a team. To enable TFS, install VS 2010 and Silverlight Tools on Team Build Server machine.

First-class rule

Ideally, for a file Page.xaml, the first class definition in the Page.xaml.cs should be Page class.  This otherwise has known issues related to code refactoring.

Locally defined StaticResource fails to load

When a StaticResource object is both defined and referenced inside the same element, the Preview Window will fail to load with an error “The type StaticResource was not found.”

Hence, it is advisable to keep Static Resources in App.xaml file. This also helps usage of these resources across the modules in the application.

Share a Brush than copying it

Instead of defining Brush in XAML, define it as StaticResouce and reference it. This creates only one instance and then reuses it.

A Generic TODO list

This is more of a compilation of single-liners that aptly fit in the TODO list of a Silverlight developer.

  • Naming Convention – Casing:
    • Pascal Casing and not Camel Casing is preferred (unlike in C#). myButton is wrong in Silverlight though it is correct in C#. The correct version is MyButton.
    • Use x:Name instead of Name as x:Name is generic and can be used for all elements.
  • Indentation:
    • Place first attribute in-line with the element name like.

<StackPanel  DockPanel.Dock=”Top” Orientation=”Horizontal”>

  • Choose a StaticResource over DynamicResource. For further read, click here
  • Resources should be placed at one location, preferably at Application Level in App.xaml file. This will avoid reloading of resources over and again when objects are created and destroyed.
  • SnapsToDevicePixels – Using graphic objects can appear nice on some monitors, while it may fade on others.  It is preferred to use a Style resource in such scenarios. For more read, click here
  • Define a definite folder structure before starting application development
    • Services – to have WCF service references
    • Images – to store application images and videos
    • Resources – platform specific APIs
    • Data – to store XML, text files
  • Remove the Object Handlers when not in use.  Not removing object handlers may keep the object alive, which may degrade the performance. RegisterClassHandler is called on every instance of object creation, which may cause performance problems
  • Frozen objects over Non-frozen:
    • Frozen objects occupy lesser memory space and are fast in execution.
    • Consider the example on MSDN–  Prefer VirtualizingStackPanel (40mSec) over a simple StackPanel (takes 3000mSec for same UI) to speed up the execution time.
    • Avoid using a TextBlock in FlowDocument
    • Since Label.Content property is slow in execution, TextBlock.Text should be used. (This is one reason why Label is not a part of Silverlight framework, and it is part of WPF)
    • Show underline in Hyperlink only on MouseOver events.  TextDecoration is performance intensive.
    • Bind an IList to an object, not an IEnumerable to avoid an automatic wrapper creation.  This will enhance your performance.
  • Proper node at proper place:
    • While the tree is developed, there can be two approaches – bottom-up or top-down. A top-down approach is 10 times faster. This is because when a node is added or removed from the logical tree, property invalidations are raised on the node’s parent and all its children.

Best practices generally evolve as a result of implementations and errors/observations. So this post remains unconcluded for the users to add in their inputs and make it extensive guide. Keep adding to it

Note: The next in this series is the Data Access Layer Guidelines.

Silverlight Best Practices (Part 1 of 4)

November 9, 2011 Silverlight, Visual Studio , , ,

I have been working on Designing and Development of Rich UI applications on Silverlight, and Windows Phone platforms and high performing applications as middleware components for Trading Applications.  One of the biggest issues I have seen is non-adherence to standards causing slowness in applications, or a red-mark in Audits due to mis-fit of technology stack. To help developers decide whether to opt for Silverlight and when designing what should be taken care of, this series of articles are written.  Wherever required, I would direct you to appropriate sites, books and links to have a further read to avoid duplicacy of text on two websites. 

 

 

This article has been edited and republished on demand.

Silverlight – yes or no?

This decision is very vital decision as you are pressing your money, time and your resources behind application development. Choose Silverlight only when

  1. Your clients hardware/software supports RIAs
  2. A good network bandwidth to download XAP components
  3. Sections that have more visualizations than that provided by HTML and ASP.NET markups
  4. High-streaming of video/audio is required.
  5. Best for single-screen applications; but can be extended to multi-screens.

Where not to choose Silverlight? Say NO when

  1. Pages are highly complex
  2. Multi-page user interfaces
  3. Browser specific programming is required (though you actually can do it, you must prefer not to use platform-specific-APIs)

Design your application such a way that plug-in installation is non-interruptive 

Data Accessibility

Accessing business logic directly from a Silverlight Application is not advisable.  It is better to encapsulate such logic in Web Services (read: WCF services), just like any other Web Application.  For security reasons, do not put highly sensitive unencrypted business logic on the client. Transferring logic to UI-layer (Silverlight) is preferred only when the performance is a huge hit, but this is done as a trade-off between performance and security.  Put your business validation/rules in a separate assembly so that it can updated independently when rules change.

Data store (DB, XML, etc), obviously, will be accessed through these services.  Do not attempt to use local client databases.  Minimize number of round-trips by filtering data at server rather than client end. 

Accessing local resources of client machine (in client-server arch) will be possible in limits only. So define the scalability of application and request appropriate space from user for your application. Avoid unhandled exceptions by checking if Storage Space is sufficient or not. The .NET cryptography APIs are available in Silverlight and should be utilized when storing and communicating sensitive data to the server if not already encrypted using another mechanism.

Application Performance Methods

 

Use appropriate methodologies to boost the application performance.  Ensure that your application has a lightweight foot-print so that users don’t spend too much time in downloading XAP file.  Initially load only code stubs which can lazy-load other modules.  Prefer using inbuilt RIA controls or trusted 3rd party controls offered by Telerik, Infragistics, Visifire, etc.

Cache your business logic and divide your modules very intelligently. Cache objects that not likely to change during a session.

Validate the data before call is given to Web Services. This will reduce the number of trips and make the system more responsive.  If validation logic is too large, consider putting it into a separate assembly. 

Communication

Prefer allocating data pull calls to background worker processes or in separate threads.  If your web service is slow in response, make sure that you keep polling it regularly (say every 5 minutes in a separate thread) to retrieve data.  Long-running processes should be executed in a separate thread to avoid blocking of UI.

Ensure that cross-domain configuration is done aptly to have communication with services hosted in other domains.  Consider using Sockets over Web Services when high-amount of information needs to be pushed/pulled to/from server. Example: Rich gaming sites, Stock-trading sites, etc.

Check out alternatives such as Nirvana for light weight push mechanism

 

Exception Handling & Logging


Using Exception Handling to control business logic is not advisable.  Catch internal exceptions and decide an appropriate exception propagation strategy – bubbling up to boundary layers.  Provide appropriate notification services for critical errors.

Logging component in Silverlight has several limitations. Hence, log errors at client-end and transfer them to server. If using services to implement logging, consider the increased overhead. The added overhead may also change message behavior on the server thus making it harder to use logging to troubleshoot message timing issues.

Mobility

Check if the plug-in has reduced functionalities for Mobile devices or the same.  If required, incorporate device specific features to improve user experience. Re-examine UI layout using simulators for a smaller screen size.  

Deployment

 

Design several modules (XAP-files) instead of a single-large XAP-file, so that individual modules can be downloaded and cached as and when required.  This will also ensure extensibility and modularity in the architecture.  Prefer to have a separate Web Application Server and a Database Server.  A Web Farm can be configured to improve response time.  However, cross domain policies should be implemented and tested. To avoid hardware failures, clustering should be done.

Version your components and label them in Source-Safe.

Provide Internet and Intranet links to manually download and install the plug-in if automatic installation cannot be done.

Ensure that your DLLs are obfuscated before deployed to any server.

Well, that’s for the first time. I’ll add more to this soon.. Please add in your expertise by commenting to this blog.

ASP.NET Best Practices (for Webforms)

March 10, 2009 ASP.NET, CSharp, Visual Studio , , ,

This has been pending since long. People have been requesting this information and I’ve not been able to find time to write on Best Practices. And this fine day, finally I pen this down.

I hope this helps to you.  These best practices are direct-from-real-world i.e. noted down as observations from live projects.

String Concatenation

Use of StringBuilder is preferred over String.Concat or use of operator ‘+’

It is observed that when number of strings to be concatenated is greater than 3, StringBuilder does it much faster than String.Concat. For lesser number of strings, String.Concat can also be used.

Avoid round trips to server

  • Usage of Ajax UpdatePanel is preferred to avoid full postback to the server.
  • Client side scripts for validations should be used.
  • Check Page.IsPostBack at Page Load to ensure that only page initialization logic is performed when a page is loaded the first time and not in response to client postbacks.

ViewState & HiddenFields

  • ViewState is valid only for postback of same pages – as data is passed to client & returned in a hidden field
  • Keep minimal data in ViewState – higher the data, slower the system
  • Disable ViewState at PageLevel using EnableViewState

Session Variables

  • Not more than 20 session variables should exist in application context.
  • Keep Session TimeOut
  • Disable Session State, if you are not using in particular Page/Application.

Server.Transfer vs Response.Redirect

  • Use Server.Transfer to redirect between pages of same application.
  • Use Response.Redirect to redirect to external page or when new context needs to be started.

Use DataReader for data binding

  • If application does not demand caching, DataReader can be used. Use DataReader to retrieve data & then load it in a DataSet
  • Don’t pass this DataSet across layers. Pass custom serialize-able entities across layers.

Grid Pagination at SQL end

  • Pagination logic can be written @ SQL end, than writing it at Grid level.
  • Send Page Number, number of records to Stored Procedure to retrieve records from DB
  • Sorting should also be implemented @ DB.
  • Check for SQL Injection.

Close resources

  • Close the connections when not in use – improves security & enhances the performance.
  • Such closures should be done in finally block or in using block

Optimize loops

  • Avoid foreach – use for, while loops
    foreach degrades the performance. It is better to use for loop instead of a foreach
  • While deleting records/rows from a collection, iterate backward (counter=Max to 1). This will avoid Stack Overflow exceptions
  • Avoid try-catch in for loops – it degrades performance.

Variable Initialization @ right place

  • Initializing variable @ start & using it at a later stage will cause many PUSH/POP operations. Hence initialize variables at right place.
  • Integer variables need not to be initialized to ZERO. They are automatically initialized; String variables need to be initialized explicitly.

Use Fiddler to intercept HTTP requests.

  • Use Fiddler to intercept the HTTP requests and to know which request is consuming more time.
  • Also find out the exceptions caused during each HTTP request.

URL Rewriting

  • For URLs that have confidential information, it is advisable to implement URL Rewriters.
  • URLs should be consistent

Caching Mechanism

  • Cache static content for longer period – use high value for Expires property
  • Use Friendly folder structure – contentimagesheader.gif, etc.
  • Minimize use of SSL as SSL is not cached
  • Use IIS HTTP Headers to configure static caching.

Application Settings

  • Content-Length should be fixed. This keeps the connection open for limited time & closes automatically when the content length is greater than declared one.
  • Encrypt connection strings on server.
  • Make sure all the reference DLLs are present in GAC
  • Disable tracing and debugging
    Set <deployment retail=”true” /> in machine.config file – it forces debug to be false, disables output tracing, and redirects to custom error page rather than the actual error page.

Progressive UI

  • Progressive UI enables fast & smooth surfing – load/visible the DIV tags only when required.

Web Services

  • Prevent overloading of web services through DoS (Denial of Service) attacks. Check if it is the First time visit, or repeated visit for the same function from same IP.
  • Use trusted SQL connections in Web Services
  • Make sure there are asynchronous calls to web services

Exception Handling

  • Log the exceptions & display appropriate message to user.
  • Define a base class say : MyException
  • This class should have following information for display to user
    • What Happened
    • What has been affected
    • What actions to do
    • Support Information
  • This class should have following information for logging purpose
    • Server Name
    • Instance id
    • User Id
    • Call Stack
    • Assembly Name & Version
    • Exception Source, Type & Message
  • Redirect as per the Error-Level
  • Application Level: Catch errors in global.asax in Application_Error function.
  • Page Level: Use Page_Error function to log errors.

Deployment – IIS

  • Create separate application pool for your site
  • Use App_Offline.htm file. This will help you take your application offline by displaying user friendly message while fixing issues.
  • Automate the build process for
    • Development
    • Production environments
  • Make sure application is not built in DEBUG mode.
  • Load test application.
Please leave your comments on the article to help improving it

Silverlight 2.0 – Advantages, Limitations & Tools

June 19, 2008 CSharp, Silverlight, Visual Studio ,

  • Advantages of Silverlight:
  • Rich UI applications using WPF (similar to Desktop applications)
  • Cross-browser, cross-platform plug-in
  • Rich Media experience. Possible to collaborate Media objects such as Video Streaming, Animations, etc.
  • Search-engine friendly
  • Application is firewall-compatible
  • Socket/TCP programming for multi-player networking support
  • Overlaying of Silverlight controls is possible as each Silverlight components is rendered in HTML DIV tags.

Limitations:

  1. No support for auto-content scrolling of a container.
  2. Silverlight 1.0 : Doesn’t include any input controls of its own. If you need user input in your Silverlight controls, you either need to create the control manually via XAML layout and event handling (for key and mouse events, etc.) or you can use HTML controls for capturing input and passing the content to the Silverlight control. Silverlight 2.0 allows this.
  3. Silverlight 2.0 :
    1. The relative positing is not currently supported in Silverlight (Fix: we need to specify the Canvas.Top for each and every controls.)
    2. Debugging with Firefox browser is not so good: VS 2008 can’t attach the firefox automatically when we run the application. so, we have to manually attach the firefox browser from Visual Studio.
    3. Exception handling is not very good so far: Exceptions in XAML file do not show on the browsers and it will just show the emply canvas which is not good.
    4. No build-in silverlight controls available in Silverlight Alpha.
    5. The support of WPF is currently very limited.

Tools:

  • Visual Studio 2008 : Writing C# code
  • Expression Design : To Convert a design into its XAML file.
  • Expression Blend : For designing purpose.
  • Silverlight 2.0 SDK : Help
  • Silverlight Tools for VS : VS2008 extensions.

Best Practices:

Look out for the best practices on:

  1. http://www.ganshani.com/2009/07/09/silverlight-2-best-practices-i/
  2. http://www.ganshani.com/2009/07/10/silverlight-2-best-practices-ii/
  3. http://www.ganshani.com/2009/07/10/silverlight-2-best-practices-iii/
  4. http://www.ganshani.com/2009/07/13/silverlight-2-best-practices-iv/
Follow on Feedly