Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET 4.5
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Amazon Web Services
Analysis Services
Android
Architecture
Arduino
ASP .NET Web API
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
BDD
Big Data
Bing
BizTalk
Book Excerpts
Build and Deploy
Business Intelligence
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE Framework Info - non Technical
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Debugger
Design Patterns
Development Process
Display Technologies
Distributed Computing
Document Database
DotNetNuke
DSL
Dynamic Languages
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
HTML 5
Internet Explorer 8.0
Interviews
IOS
iPhone
Iron Ruby
Java
Java Script
JavaScript
jQuery
JSON
Lightswitch
LINQ
Linux
LUA
Mac OS X
MDX
Messaging
Metro
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
MVVM
MySQL
Network
NHibernate
node.js
NOSQL
Nuget
Object Oriented Development
Objective C
Odata
OLAP
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
PHP
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Prolog
Python
Q&A
Rails
Rake
Razor
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Scheme
Search
Security
Services
SharePoint
SignalR
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server 2012
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
TFS
Tips
TypeScript
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 11
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2011
Visual Studio 2012
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WebMatrix
WF
Whitepapers
Windows 7
Windows 8
Windows Azure
Windows Live
Windows Phone 7
Windows Phone SDK
Windows Server
Windows Vista
WinForms
WinRT
Workflow
WPF
XAML
Xiine Documentation
XML
XNA
XSLT



Learn Now


rssbus
 


Xojo

Reader rating:
Click here to read 5 comments about this article.
Article source: CoDe (2008 Jan/Feb)


Article Pages:  1  2 3 4 - Next >


Design for Extensibility

Today’s clients seem to be getting more and more demanding regarding the flexibility of their applications and the speed in which modifications can be made. In this article, I will show you how to design applications with extensibility points so that they will grow with the clients’ needs as well as provide a way to “swap” functionality in and out as needed.

Throughout my years in software development, there have been many concepts and paradigms introduced in writing code as well as many methodologies for defining how software should be developed. For the most part, each has built on the previous, enhancing the development process each time. Object-oriented programming redefined how we think of entities within an application and communicate with them. SOA showed us how to expose object-oriented entities in a way that they can service similar and dissimilar clients. Several years ago, the design-pattern craze hit the industry with the publishing of the famous GoF book (see sidebar “Additional References”). All these things put together have inspired the creativity of many developers, including me. I’m going to show you how to use your existing OOP and pattern knowledge to develop applications in a way that they can be changed and/or enhanced with minimum effort and in a clean, elegant, and efficient manner.

Extensibility Patterns

Throughout the course of this article, I’m going talk about three different patterns that I use to make my applications extensible. None of these is absolutely defined in any patterns manual, though each bears resemblance to one or more patterns in the GoF catalog.

Providers

This pattern has its roots in the Strategy pattern and it lets you design your data and behavior in an abstraction so that you can swap out implementation at any time.

Plug-Ins

This builds on the same abstraction design I’ll use in writing providers and lets you build sections of your site in swappable modules. In a way they are similar to providers but where you generally use providers to obtain information, you use plug-ins typically to perform tasks; though many will argue quite successfully that their definitions can be interchangeable.

Modules

Modules have their roots in the Chain of Responsibility pattern and take plug-ins to the next level by allowing you to define many plug-ins within one class, thus centralizing your extensibility capability in your application.

To better illustrate how the three patterns I’m going to show you evolve, I’ll start by describing a very trivial 3-step process that I’ll build on as the article progresses. I’ll code this process concretely first, and then start applying my three patterns to it. The 3-step process will involve obtaining the name of a text file, reading in string data from it, and logging that data to another file.

Doing it Concretely

I’ll first start by writing a class that will house the functionality I want for my 3-step process. I’ll call this class FileReader.

Here’s the interface for the FileReader class. You can find the complete code in Listing 1.

In VB:

Public Function GetFileName() 
  As String
Public Function GetFileData(ByVal file 
  As StringAs String
Public Sub LogTextData(ByVal data 
  As String)

In C#:

public string GetFileName()
public string GetFileData(string file)
public void LogTextData(string data)

From what this code shows, the GetFileName method is returning the name of a file, which FileReader then sends into the GetFileData method to retrieve a string of data, which it then sends into the LogTextData method.

Now, say you were building an application that was going to run this little 3-step process. Integrating this into a form or a controller class of some kind would not be difficult at all and quite well accepted by most developers in the industry. Unfortunately, if anything ever changes with the way the application obtains a file name or the data, it would involve coming back into this code and changing it appropriately.

A client can use my FileReader class like so:

In VB:

Dim o_FileReader As FileReader = New 
   FileReader()

Dim s_File As String 
   o_FileReader.GetFileName()

Dim s_Data As String = _
   o_FileReader.GetFileData(s_File)

If s_Data <"" Then
    o_FileReader.LogTextData(s_Data)
End If

In C#:

FileReader o_FileReader = new 
   FileReader();

string s_File = 
   o_FileReader.GetFileName();

string s_Data = 
   o_FileReader.GetFileData(s_File);

if (s_Data != "")
{
    o_FileReader.LogTextData(s_Data);
}

So what I’m going to do is abstract the interface and separate it from the implementation. A client application, be it a class or a form, will then communicate only through the abstraction I’m about to design. In the interest of even greater flexibility, I’m going to generalize this process even further. I’m going to go from:

  1. GetFileName
  2. GetFileData
  3. LogTextData

to:

  1. GetSource
  2. GetData
  3. LogData

Notice the “from” can fit easily into the “to”, though not vice-versa.

I came up with this by pretending to be the client, and asking myself exactly what do I need; then coming up with a more generic process that still has the capability of feeding me exactly what I needed. Now all I need to do is turn this into a provider model.

&

By: Miguel Castro

Miguel is an architect with IDesign who specializes in architecture consulting and building .NET solutions. He is a Microsoft MVP and INETA speaker and has been a software developer for over 22 years. With a Microsoft background that goes all the way back to VB 1.0 (and QuickBasic in fact), Miguel jumped on .NET as soon as the first public Beta was released and has provided .NET solutions for clients around the country in a variety of industries. He considers himself to be a .NET Developer and Architect and has equal love for both VB and C#, and no tolerance for language bigotry. He’s spoken at numerous user groups around the country as well as developer conferences.

He’s the author of the CodeBreeze code-generator, which among things can be found on his Web site:

www.steelbluesolutions.com

Miguel currently lives in Lincoln Park, NJ with his wife Elena and his daughter Victoria.

subscriptions@infotekcg.com

Fast Facts

Extensibility modules are based on the same pattern used in HTTP modules.



Listing 1: FileReader class
In VB:

Public Class FileReader

    Public Function GetFileName() As String
        Dim s_Path As String = _
            ConfigurationManager.AppSettings("filePath")
        Dim o_Dir As DirectoryInfo = _
            New DirectoryInfo(s_Path)
        Dim o_Files() As FileInfo = _
            o_Dir.GetFiles("*.txt")
        If o_Files.Length Then
            Dim s_File As String = o_Files(0).Name
            Return s_Path & "\" & s_File
        End If
        Return ""
    End Function

    Public Function GetFileData(ByVal file As String)
    As String
        Dim o_Contents As StringBuilder = _
            New StringBuilder()
        Dim o_File As FileInfo = _
            New FileInfo(file)
        If o_File IsNot Nothing Then
            Using o_FileStream As FileStream = _
                o_File.Open(FileMode.Open)
                Using o_Reader As StreamReader = _
                    New StreamReader(o_FileStream)
                    While Not o_Reader.EndOfStream
                        o_Contents.Append(
                        o_Reader.ReadLine())
                    End While
                End Using
            End Using
        End If
        Return o_Contents.ToString()
    End Function

    Public Sub LogTextData(ByVal data As String)
        Dim s_Path As String = _
            ConfigurationManager.AppSettings("logPath")
        Dim s_File As String = _
            DateTime.Now.ToString("yyyyMMdd") & ".txt"
        Dim o_FileStream As FileStream = Nothing
        Dim o_File As FileInfo = _
            New FileInfo(s_Path & "\" & s_File)
        If o_File.Exists Then
           o_FileStream = o_File.Open( _
           FileMode.Append, FileAccess.Write)
        Else
           o_FileStream = o_File.Create()
        End If
        Using o_FileStream
            Using o_Writer As StreamWriter = _
                New StreamWriter(o_FileStream)
                With o_Writer
                   .WriteLine(DateTime.Now.
                    ToShortTimeString())
                   .WriteLine("")
                   .WriteLine(data)
                   .WriteLine("")
                   .Close()
                End With
                o_FileStream.Close()
            End Using
        End Using
    End Sub
End Class

In C#:

public class FileReader
{
    public string GetFileName()
    {
        string s_Path = 
           ConfigurationManager.AppSettings["filePath"];
        DirectoryInfo o_Dir = new 
        DirectoryInfo(s_Path);
        FileInfo[] o_Files = o_Dir.GetFiles("*.txt");
        if (o_Files.Length 0)
        {
            string s_File = o_Files[0].Name;
            return s_Path + "\\" + s_File;
        }
        return "";
    }

    public string GetFileData(string file)
    {
        StringBuilder o_Contents = new StringBuilder();
        FileInfo o_File = new FileInfo(file);
        if (o_File != null)
        {
            using (FileStream o_FileStream = 
               o_File.Open(FileMode.Open))
            {
                using (StreamReader o_Reader = 
                   new StreamReader(o_FileStream))
                {
                    while (!o_Reader.EndOfStream)
                    {
                        o_Contents.Append(
                        o_Reader.ReadLine());
                    }
                }
            }
        }
        return o_Contents.ToString();
    }

    public void LogTextData(string data)
    {
        string s_Path = 
           ConfigurationManager.AppSettings["logPath"];
        string s_File = 
           DateTime.Now.ToString("yyyyMMdd") + ".txt";
        FileStream o_FileStream;
        FileInfo o_File = new 
        FileInfo(s_Path + "\\" + s_File);
        if (o_File.Exists)
            o_FileStream = o_File.Open(
               FileMode.Append, FileAccess.Write);
        else
            o_FileStream = o_File.Create();
        using (o_FileStream)
        {
            using (StreamWriter o_Writer = 
               new StreamWriter(o_FileStream))
            {
                o_Writer.WriteLine(
                   DateTime.Now.ToShortTimeString());
                o_Writer.WriteLine();
                o_Writer.WriteLine(data);
                o_Writer.WriteLine();
                o_Writer.Close();
            }
            o_FileStream.Close();
        }
    }
}


Article Pages:  1  2 3 4 - Next Page: 'Providers' >>

Page 1: Design for Extensibility
Page 2: Providers
Page 3: Plug-Ins
Page 4: Extensibility Modules

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
4.2 out of 5

20 people have rated this article.

rssbus

      Sharepoint TechCon

 

Hacker Halted