June 2008 - Posts
ASP.NET Server Side State Management – Session State
In this post I’ll introduce the session state technique.
You can read my previous posts in the state management subject in
the following links:
What is session state?
The session state is a global storage mechanism that is
accessible from all the web pages that were requested by a
single web browser session. The storage is perfect for storing specific
information that is connected to a specific user. That means that every
user of the web application will have a separate session state.
The session has a timeout period and after the timeout the session data
is lost and a new session will be created for the user. The timeout occurs
when the user is no longer active for a period of time. Like the application
state, the session storage is implemented as a key/value dictionary which is
represented by an instance of the HttpSessionState object.
The session is used for the following scenarios:
- Uniquely identify a client requests and therefore you can track
users by the their sessions. - Raise session management events. The Global.asax file has
session management events like Session_Start that helps to do
useful things regarding the session events (for example – counting how
many users are currently connected to your site). - Store session specific data.
The session is being tracked by the ASP.NET_SessionID cookie. That
cookie is constructed whenever a new session is created for a user.
Regardless to say that if cookies are disabled then the session cookie won’t
be available.
Using Session State Data
The use of the session dictionary is very simple. for example:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["FirstPageLoadEventTime"] == null)
{
// put the date time of the first page load in the
// session
Session["FirstPageLoadEventTime"] = DateTime.Now;
}
DateTime firstPageLoadEventTime =
(DateTime)Session["FirstPageLoadEventTime"];
}
In the example I put the time of the first page load in the session
and then insert it to a variable called firstPageLoadEventTime. In the
next time that the Page_Load event will be called the session will hold
the first time that the Page_Load method was called. This is only an
example and probably I won’t do such a thing in an application.
Disabling Session State
There are two ways to disable the session state:
Session Management Events
You can use the session management events like you use the
application state management events. In the Global.asax file
There are two events that you can use:
- Session_Start – raised whenever a session is starting.
- Session_End – raised whenever a session is ending.
Cookieless Session State
As written earlier the session state is managed by a cookie.
What can we do if the user disabled cookies?
There is a cookieless configuration that put the session id in
the page’s Url instead of a cookie. To enable this behavior
use the following code in your web.config:
<configuration>
<system.web>
<sessionState cookieless="true" regenerateExpiredSessionId="true">
</sessionState>
</system.web>
</configuration>
Session State Mode
There are several storage options for session data:
- InProc – Session state is saved in memory. The session is discarded
when the application restart. The session is enabled only
for the current server and not supported in a web farm.
This is the default. - StateServer – Session state is saved in a dedicated
ASP.NET state server. The session is saved when application restart
and also available to multiple web server in a web farm.
You pay in performance in this choice. - SQLServer – Session State is saved in Sql server database.
The session is available to multiple web servers in a web farm.
Also the session state is saved whenever the application restart.
You pay in performance in this choice. - Custom – A custom session storage provider that you build.
- Off – Disable session state.
The session mode is specified in the web.config file.
The following example specify an InProc mode in the
web.config:
<configuration>
<system.web>
<sessionState mode="InProc">
</sessionState>
</system.web>
</configuration>
Modes other then Off and InProc need other parameters to
be enabled like sqlConnectionString for the SQLServer mode for
example.
Summary
To sum up the post, I introduced the session state technique.
The technique is widely used in ASP.NET and sometime over used.
Sometimes I find that developers put almost everything in the session
even things that should be managed by client side techniques.
You need to find the balance between server and client side techniques
in order to build a good web application. The next post in the server side
state management will be the last in the series and will introduce the
profile properties technique.
Unity Application Block Basics
This post will help you to start working with the Unity
application block. I’m going to show some basic examples of how
to use Unity API. You can read the previous post in this
subject in order to get an introduction to Unity.
Setting Up a Unity Container
In order to start working with Unity the first thing we have to do
is to set up a Unity container. The Unity container is the basic
object of Unity. The container is populated with the registered mappings
and help us to resolve registered mappings.
There are three ways to set up a container:
- By registering types in the container using the container methods.
- By XML format configuration file which use the unity schema.
- By using the container configuration API to configure the container.
The Unity container has two main methods to register types:
- RegisterType – The type is registered in the container and the
container is responsible to initialize it when appropriate. - RegisterInstance – An instance of a type is registered in the container
with a lifetime which you can include. During the registered lifetime
the container will return the instance when needed.
After the registration of the types you will be able to use the Unity
container’s Resolve method in order to get the relevant type.
The following example shows how to register a mapping
between an interface of ILogger to a FileLogger concrete class:
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, FileLogger>();
In order to register a mapping from an ILogger interface to more then
one concrete class you can use a name for the concrete like in this
example:
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, FileLogger>("FileLogger");
container.RegisterType<ILogger, DatabaseLogger>("DBLogger");
In some cases you already have an existing object and you want to
use it. The Unity container enables us to register an instance with the
RegisterInstance method of the container.
When registering an instance, the default container behavior will
be to return the same instance every time it is needed when the Resolve
method is called. The object will act as a singleton.
IUnityContainer container = new UnityContainer();
container.RegisterInstance<ILogger>(new FileLogger());
In the example I pass the FileLogger instance to the RegisterInstance
method. You can override the singleton behavior by passing the
ExternallyControlledLifetimeManager class as a second parameter
in the RegisterInstance.
Resolve an Object
After registering the types in the Unity container you’ll want to use
them. How do you do it? The answer is the Resolve method of
the container. The following example is the first example that I
showed including the use of the Resolve method:
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, FileLogger>();
ILogger logger = container.Resolve<ILogger>();
As you can see the Resolve method will return an ILogger
which as expected will be of type FileLogger under the hood.
The Unity container will instantiate the FileLogger and will
return a new instance of that class as an ILogger interface.
If you registered more then one concrete class you can use the
Resolve method overload that gets a name of the mapping to return
the relevant mapped class or use the ResolveAll method to get
an IEnumerable collection of the registered types:
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, FileLogger>("FileLogger");
container.RegisterType<ILogger, DatabaseLogger>("DBLogger");
var logger = container.Resolve<ILogger>("FileLogger");
var loggers = container.ResolveAll<ILogger>();
Summary
To sum up the post, I showed the basics of using the Unity
application block. I showed how to set up a Unity container
using the Unity API and how to resolve the Unity mappings from
the container. These are very basic operations. In the next posts in this
subject I’ll explain other aspects of Unity like using Unity with
configuration files.
Command Pattern
Today’s post will explain what is the command pattern and how to
use it in C#.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern
Creational patterns
Singleton pattern
Abstract Factory pattern
Prototype pattern
Factory Method pattern
Builder pattern
Behavioral Patterns
Strategy pattern
Iterator pattern
Template method pattern
Command Pattern
The command pattern is a very useful pattern.
The main role of the pattern is to encapsulate a request in an
object. By encapsulating the request we gain the following support if
needed:
- Redo and Undo operations.
- Requests can be specify, queue and executed when needed.
- Logging requests can be handled.
- Composition of transactions inside an object that include the
transaction atomic operations.
The pattern is used a lot in .Net framework.
System.Data.SqlClient.SqlCommand is an example of the use of command
in ADO.NET. The SqlCommand encapsulate the internal issues of how to
do database operations and give a simple API to execute methods such as
ExecuteScalar, ExecuteNonQuery and etc. Every data access class that
uses the SqlCommand is the command invoker.
Use Cases for the Command Pattern
You should use the pattern in the following cases:
- You need support for logging of the changes performed by
commands. - You need redo or undo support.
- You have commands that different clients can handle in different
ways. - You have a set of atomic operations that you want to include in
a transaction.
UML Diagram
Example in C#
#region Command
interface Command
{
void Execute();
}
#endregion
#region Concrete Command
class ConcreteCommand : Command
{
#region Members
private readonly Receiver _receiver;
#endregion
#region Ctor
/// <summary>
/// Construct a new ConcreteCommand with the
/// given receiver
/// </summary>
/// <param name="receiver">The given receiver</param>
public ConcreteCommand(Receiver receiver)
{
_receiver = receiver;
}
#endregion
#region Command Members
void Command.Execute()
{
_receiver.Action();
}
#endregion
}
#endregion
#region Receiver
class Receiver
{
public void Action()
{
// write whatever action you need
}
}
#endregion
#region Invoker
class CommandInvoker
{
#region Members
private readonly Command _command;
#endregion
#region Ctor
/// <summary>
/// Construct a new Command Invoker with
/// the given command
/// </summary>
/// <param name="command">The given command</param>
public CommandInvoker(Command command)
{
_command = command;
}
#endregion
#region Methods
public void ExecuteCommand()
{
_command.Execute();
}
#endregion
}
#endregion
The example is very simple. I use a Command interface to hold
the command API that I need. The ConcreteCommand class
implement the interface and holds the receiver of the command
which implement the action of the command. The command itself
is invoked by the CommandInvoker class.
Redo and Undo Code Example
A request for an example of how to make a redo and undo operations
in the pattern was issued in the comment section. The following example
is a very simple example of how to make a redo and undo operations:
#region Command
interface Command
{
void Execute();
void Undo();
void Redo();
}
#endregion
#region Concrete Command
class ConcreteCommand : Command
{
#region Members
private readonly Receiver _receiver;
#endregion
#region Ctor
/// <summary>
/// Construct a new ConcreteCommand with the
/// given receiver
/// </summary>
/// <param name="receiver">The given receiver</param>
public ConcreteCommand(Receiver receiver)
{
_receiver = receiver;
}
#endregion
#region Command Members
void Command.Execute()
{
_receiver.Action();
}
public void Undo()
{
_receiver.UndoAction();
}
public void Redo()
{
_receiver.RedoAction();
}
#endregion
}
#endregion
#region Receiver
abstract class Receiver
{
#region Methods
public abstract void Action();
public abstract void UndoAction();
public abstract void RedoAction();
#endregion
}
#endregion
#region Concrete Receiver
class ConcreteReceiver : Receiver
{
#region Consts
private const int NUMBER_TO_ADD = 1;
#endregion
#region Members
private int _nCurrentState;
private int _nOldState;
#endregion
#region Methods
public override void Action()
{
// save the current state
_nOldState = _nCurrentState;
// do the action of string concat
_nCurrentState += NUMBER_TO_ADD;
Console.WriteLine("Current state {0}",
_nCurrentState);
}
public override void UndoAction()
{
// Return the old state to be the current state
_nCurrentState = _nOldState;
Console.WriteLine("Undo Current state back to {0}",
_nCurrentState);
}
public override void RedoAction()
{
// Redo calls the action again to redo
// the adtion
Action();
}
#endregion
The example is based on the code that was showed earlier in
the post. The only difference is that I added the redo and undo
operations and added a ConcreteReceiver that handles the redo and
undo operations. The example is simple and the undo operation only
saves the last action state. Also, the redo performs the action again
as indicated from a redo operation.
Summary
To sum up the post, I introduced the command pattern.
The pattern is widely used in the .Net framework and is very helpful
once you know how to use it. It can simplify the way you build requests
in the systems that you develop.
The next stop in the tour of behavioral patterns will be the chain
of responsibility pattern.
ASP.NET Server Side State Management – Application State
In this post I’ll introduce the application state technique as the first
ASP.NET server side state management techniques.
You can read my previous posts in the state management subject in
the following links:
What is application state?
Application state is a global storage mechanism that saves data
that can be accessed from every web page in a web application.
The data that is saved in the Application is maintained between
every request that is sent to the server. The application state is
maintained in the HttpApplicationState class which is implemented
as a dictionary. The Application is a good place to hold data which
is global for the web application and isn’t connected to a specific user.
By placing the data in the application state you gain a single access point
for shared application data. The data that you save in the application state
isn’t permanent and is cleaned whenever the application restarts.
Application Events
There are three main events in the application state life cycle which
can be customized. The events are:
- Application_Start
- Application_End
- Application_Error
The events occur as indicated by their names – at the application start, at the
application end and when an unhandled error is raised in the application.
The events can be implement in the Global.asax file:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// Put here global initialization code for the web
// application
}
protected void Application_End(object sender, EventArgs e)
{
// Put here global clean up code for the web application
}
protected void Application_Error(object sender, EventArgs e)
{
// Handle the error that was unhandled in the application
// This is the last point in web applications to handle
// errors
}
}
How to Use Application State Data?
As written earlier the
application state storage is an
instance of the
HttpApplicationState class. The
HttpApplicationState class is implemented as a dictionary and therefore the use of it is simple.
The only problem with the
Application is that it can be updated from
multiple web pages. Therefore, you have to lock the
Application object
before you make any update to data that it holds.
An example of how to update an
Application variable:
Application.Lock();
Application["Variable"] =
(string.Format("{0} is a string",
(string) Application["Variable"]));
Application.UnLock();
In the example you can see that I concat a string to a stored variable.
Before doing the operation I use the Lock method of the
Application object to lock the object. After the operation I use the UnLock method
of the
Application object. You don’t have to lock the
Application when
initializing variables in the
Application_Start event.
Remember to use locking whenever you update a record or else if the record
can be updated from another page the web application can become inconsistent.
The example above showed how to read a value (which need to be cast)
and how to write a value to the
Application storage.
Summary
To sum up the post, the application state enable us to store global
data for our application. Even though, I prefer to use that storage with
caution because if it is over used it can have a major impact on the
memory usage of the application. The next stop in this series will be the
session state technique.
ASP.NET Server Side State Management
In this post I’ll make an introduction for
the ASP.NET server side state management.
You can read my previous posts in the state management subject in
the following links:
Server Side State Management
Whenever a client side state management isn’t appropriate the
server side state management is getting into action. The server side
includes three main techniques in order to save state – application
state, session state and profile properties. All these techniques enables
us to save data on the web server and therefore available only when
a round trip to the server occurred. Using the server side techniques
consume server resources and therefore you should always think before
you use one of those techniques.
Server Side Techniques
The followings are the server side state management techniques:
- Application state – a global storage mechanism that is
accessible from all the web pages in the web application.
The data is stored in the Application dictionary.
The data of the application state is stored until the application
is restarted.
- Session state – a storage mechanism that is accessible
from all the web pages that where requested by a single web
browser. User specific data should be saved in the session state.
The data is preserved until the user’s session expires.
- Profile properties – a storage mechanism that stores user specific
data that isn’t lost when the user session expires. The technique
uses the Profile feature of ASP.NET 2.0.
When to Choose Server Side State Management I wrote the following text in the introduction for client side
state management:
”Choose server side for better security and to reduce bandwidth
and web page's size.
Server side state management is more secure.
The state is saved on the server and therefore isn't delivered to the client.
Confidential state data shouldn't be used with
client side
state
management.
Server side reduces the traffic to and from the client
because data isn't sent to the browser and it's saved on the server.
You should always remember that using client side
state management sends
data to the user's browser and that data is sent back to the server
every time. This situation increases bandwidth usage and therefore your
application will be less responsive and you'll suffer from performance issues.”
Summary
To sum up the post, I introduced the ASP.NET server side state
management topic. In the next post in this series I’m going to
explain what is application state and how to use it.
ASP.NET Client Side State Management – Control State
In this post I'm going to explain what is the control state and how to use
it as a part of the ASP.NET client side state management.
You can read my previous posts in the state management subject in
the following links:
What is Control State?
The control state is a way to save a control’s state information when the
EnableViewState property is turned off. Unlike ViewState a developer
can’t turn off control state. The control state can be implemented
only in controls that you implement.
How to Use Control State?
Control state implementation is easy.
First, override the OnInit method of the control and add
the call for the Page.RegisterRequiresControlState method with
the instance of the control to register. Then, override the
LoadControlState and SaveControlState in order to save the
required state information.
The next example shows a simple implementation for a control that
saves a string as a state information:
public class ControlStateWebControl : Control
{
#region Members
private string _strStateToSave;
#endregion
#region Methods
protected override void OnInit(EventArgs e)
{
Page.RegisterRequiresControlState(this);
base.OnInit(e);
}
protected override object SaveControlState()
{
return _strStateToSave;
}
protected override void LoadControlState(object state)
{
if (state != null)
{
_strStateToSave = state.ToString();
}
}
#endregion
}
You need to remember only one thing – the control state
takes away the choice to disable ViewState. You should
only use it whenever you have to keep a state information that
without it your control won’t work.
Summary
To sum up the post, I showed what is the control state and
how to enable it in your controls. The control state takes away the
decision of a developer whether to use ViewState or not.
Whenever you want to use the control state you should think whether
to implement it or give the decision of how to save the state information
to the developers that use your control. I prefer the second choice.
In the next post in this series I’ll start to explain the server side state
management.
Template Method Pattern
In this post I’ll reveal another useful pattern in the world of
design patterns – the template method pattern.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern
Creational patterns
Singleton pattern
Abstract Factory pattern
Prototype pattern
Factory Method pattern
Builder pattern
Behavioral Patterns
Strategy pattern
Iterator pattern
Template Method Pattern
The template method pattern is used to defer steps of an algorithm
to a class subclasses. The structure of the algorithm doesn’t change
only the “holes” that the pattern leaves (the template method) can defer
from subclass to subclass.
Use Cases for the Template Method Pattern
You should use the pattern in the following cases:
- You have common behavior in an algorithm and
other parts that can be changed. Using the pattern will
help to avoid code duplication. - To enable “hook” operations at specific points in your class.
By doing so you can control the extensions of your class.
UML Diagram
Example in C#
#region Abstract Class
abstract class Abstract
{
public abstract void Step1();
public abstract void Step2();
/// <summary>
/// The template method which call the
/// algorithm parts.
/// </summary>
public void TemplateMethod()
{
Step1();
Step2();
}
}
#endregion
#region Concrete Classes
class Concrete1 : Abstract
{
#region Methods
public override void Step1()
{
Console.WriteLine("Step one was called");
}
public override void Step2()
{
Console.WriteLine("Step two was called");
}
#endregion
}
class Concrete2 : Abstract
{
#region Members
private int _calculation;
#endregion
#region Ctor
/// <summary>
/// Construct a new Concrete2 object
/// </summary>
public Concrete2()
{
_calculation = 0;
}
#endregion
#region Methods
public override void Step1()
{
_calculation++;
Console.WriteLine("calculation is {0}",
_calculation);
}
public override void Step2()
{
_calculation--;
Console.WriteLine("calculation is {0}",
_calculation);
}
#endregion
}
#endregion
The example is self explanatory. The algorithm
has two steps that every concrete class decide how to
implement them.
“Hook” Operation Example
The following example shows how you can “hook” operation
like creating a data accessor object in a derived class of
BaseDataAccessor:
public abstract class BaseDataAccessor
{
#region Members
protected object _dataAccessor;
#endregion
#region Ctor
public BaseDataAccessor()
{
InitDataAccessor();
}
#endregion
#region Methods
protected abstract void InitDataAccessor();
#endregion
}
public class SqlDALComponent : BaseDataAccessor
{
#region Properties
public System.Data.SqlClient.SqlCommand DataAccessor
{
get
{
return ((System.Data.SqlClient.SqlCommand)_dataAccessor);
}
}
#endregion
#region Methods
protected override void InitDataAccessor()
{
_dataAccessor = new System.Data.SqlClient.SqlCommand();
}
#endregion
}
The InitDataAccessor is the “hook” operation that is implemented
in the subclasses and creates the data accessor.
Pay attention that it is only an example and not the way I would
implement a data accessor creation!
Summary
To sum up the post, I introduced the template method pattern.
The template method pattern helps me a lot as a infrastructure
developer to enable “hook” operations to control the extensions
of the classes I build. The template method pattern resemble the
strategy pattern. The only difference between them is that template
method use inheritance to vary part of an algorithm and strategy use
delegation instead.The next post in this series will describe the command
pattern in details.
Unity Application Block
A new release of enterprise library was published few weeks ago.
In the new release the ObjectBuilder subsystem was replaced with
the new Unity application block. In this post I’ll describe what is the
Unity application block and when to use it.
What Is The Unity Application Block?
The Unity application block is described as a lightweight,
extensible dependency injection container. Unity enables
constructors, properties or method calls injections.
The main reason to use Unity is to design and build loosely coupled
applications. By doing so the application will be more flexible and
maintainable. Dependency injection is a technique for building a
loosely coupled applications. It decouples the dependencies between
objects and abstract their connections. For example a scenario of a
person class that use a validation object which validate it’s properties
and a data access object which holds the person’s database operations.
The dependency injection techniques help to the person class to
instantiate and populate those objects and also help to decouple those
objects from the person class.
Advantages Of Using Unity
- Simplifies object creation.
- Abstraction of requirements – dependencies are specified
in runtime or by configurations. - Increased flexibility by deferring component configuration to the
container. - Service location capability – clients can store or cache the
dependencies container.
When To Use Unity?
- You have dependencies between objects.
- The dependencies are complex and you need a way to abstract
them. - You want to be able to change your dependencies at runtime.
- You want to be able to persist your dependencies in web
applications. - You want to use constructors, properties or method calls injections.
Summary
In this post I explained what is the Unity application block,
why to use it and when to use it. In the next posts in this subject I’ll explain
how to use Unity in more details.
Iterator Pattern
The next stop in the tour of the behavioral patterns is a very
commonly used pattern - the iterator pattern.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern
Creational patterns
Singleton pattern
Abstract Factory pattern
Prototype pattern
Factory Method pattern
Builder pattern
Behavioral Patterns
Strategy pattern
Iterator Pattern
The iterator pattern’s role is to provide a way to access aggregate
objects sequentially without the knowledge of the structure of the
aggregate. The pattern is widely used in C# and in .Net framework we
have the IEnumerator and IEnumerable interfaces to help us to
implement iterators for aggregates. When you implement your own
aggregate object you should implement these interfaces to expose a
way to traverse your aggregate.
Use Cases for the Iterator Pattern
You should use the pattern in the following cases:
- You need a uniform interface to traverse different aggregate
structures. - You have various ways to traverse an aggregate structure.
- You don't won't to expose the aggregate object's internal
representation.
UML Diagram
Example in C#
#region Aggregate Item
class AggregateItem
{
#region Properties
/// <summary>
/// The AggregateItem's data
/// </summary>
public string Data { get; set; }
#endregion
#region Ctor
/// <summary>
/// Construct a new AggregateItem with
/// the given data
/// </summary>
/// <param name="data">The given data</param>
public AggregateItem(string data)
{
Data = data;
}
#endregion
}
#endregion
#region Aggregate Object
interface Aggregate
{
Iterator GetIterator();
}
class AggregateImpl : Aggregate
{
#region Members
private readonly List<AggregateItem> _aggregate;
#endregion
#region Properties
/// <summary>
/// The number of items in the
/// aggregate
/// </summary>
public int Count
{
get
{
return _aggregate.Count;
}
}
/// <summary>
/// The indexer for the aggregate
/// </summary>
public AggregateItem this[int index]
{
get
{
return _aggregate[index];
}
set
{
_aggregate[index] = value;
}
}
#endregion
#region Ctor
/// <summary>
/// Construct a new AggregateImpl
/// </summary>
public AggregateImpl()
{
_aggregate = new List<AggregateItem>();
}
#endregion
#region Aggregate Members
/// <summary>
/// Returns the Iterator for this aggregate
/// object.
/// </summary>
/// <returns>Iterator</returns>
public Iterator GetIterator()
{
return new IteratorImpl(this);
}
#endregion
}
#endregion
#region Iterator
interface Iterator
{
object First();
object Next();
bool IsDone();
object Current();
}
class IteratorImpl : Iterator
{
#region Memebrs
private readonly AggregateImpl _aggregate;
private int _nCurrentIndex;
#endregion
#region Iterator Members
/// <summary>
/// Return the first object of the iterator.
/// </summary>
/// <returns>First object of the iterator</returns>
public object First()
{
return _aggregate[0];
}
/// <summary>
/// Return the current object in the iterator and
/// advance to the next one.
/// </summary>
/// <returns>The next object in the iterator</returns>
public object Next()
{
object result = null;
if (_nCurrentIndex < _aggregate.Count - 1)
{
result = _aggregate[_nCurrentIndex];
_nCurrentIndex++;
}
return result;
}
/// <summary>
/// Returns true if the iteration is done.
/// </summary>
/// <returns>True if the iteration is done</returns>
public bool IsDone()
{
return _nCurrentIndex >= _aggregate.Count;
}
/// <summary>
/// Return the current object in the iterator.
/// </summary>
/// <returns></returns>
public object Current()
{
return _aggregate[_nCurrentIndex];
}
#endregion
#region Ctor
/// <summary>
/// Construct a new IteratorImpl with the given
/// aggregate.
/// </summary>
/// <param name="aggregate">The given aggregate</param>
public IteratorImpl(AggregateImpl aggregate)
{
_nCurrentIndex = 0;
_aggregate = aggregate;
}
#endregion
}
#endregion
There are 5 players in the example. The first player is an aggregate
item which is a simple data structure. We also have an aggregate
interface which has a GetIterator method that returns the iterator.
There is an Iterator interface that gives the guidelines of the
iterator behavior. I used the two interfaces to implement an
aggregate and an iterator.
The IEnumerator and IEnumerable Interfaces
The IEnumerator and the IEnumerable are the ways to implement
the iterator pattern in C#. The IEnumerable interface exposes the
enumerator, which supports a simple iteration over a non-generic or
generic collection. It is used in the collection itself to expose the functionality
of enumerator. The IEnumerable is widely used in LINQ and
it is the building block to expose LINQ functionality. The IEnumerator
interface supports a simple iteration over a non-generic or generic collection.
The enumerators are a read only way to traverse a collection.
You should use these interfaces in order to implement the iterator pattern
in C#. The way to implement them is close to the implementation that
I provided earlier for the iterator pattern.
Simple Traverse Example
Even though it is more preferable to use a foreach loop you
can traverse collections with the IEnumerator interface
like in the following example:
// build a new string list
var strList = new List<string>
{
"str1",
"str2",
"str3"
};
// get list enumerator
IEnumerator<string> enumerator = strList.GetEnumerator();
// use the enumerator to traverse the list
// and output the list's items to console
string str;
while (enumerator.MoveNext())
{
str = enumerator.Current;
if (!string.IsNullOrEmpty(str))
{
Console.WriteLine("{0}", str);
}
}
Summary
To sum up the post, we are widely using the iterator pattern even if
we don’t know it. Whenever you run a foreach loop the iterator
pattern is used underneath the hood. The LINQ extensions are built
upon the IEnumerable interface which is a part of the iterator pattern
implementation in .Net framework.
In the next post I'm going to explain in details the use of the template
method pattern.
היום אני חורג ממנהגי ואני לא רושם פוסט טכני/מקצועי וגם רושם בעברית.
אני רוצה לשתף אתכם בסיבה לכך שלא רשמתי פוסטים בשבוע וחצי האחרונים
על מנת שלא תגיעו למצב שאליו הגענו משפחתי ואני.
ביום שני שעבר אורון, הבן שלי, בלע נעץ בעת שהיה במשפחתון.
כתוצאה מכך הוא עבר ניתוח חירום מציל חיים בבית חולים אסף הרופא.
אלו היו 50 הדקות הכי ארוכות בחיים שלי ואני לא מאחל את זה לאף אחד.
הניתוח עבר בהצלחה אבל הוא חובר למכונת הנשמה והיה מורדם במשך
24 שעות. את הימים שלאחר הניתוח העברנו אשתי ואני בטיפול נמרץ בעקבות
בצקת בגרון וחשד לזיהום עקב שהייה של עצם זר בגרון.
אלו היו ימים קשים ביותר שבהם קיבלנו תמיכה חמה מהמשפחה, מחברים
ומצוות העובדים של חברת SRL.
אתמול בצהריים שוחררנו הביתה לאחר 6 ימים בבית החולים.
אורון נמצא כרגע בטראומה קשה והוא אינו מתנהג כבעבר אבל לפחות
הוא בבית עם ההורים שלו שמטפלים בו בחום ואהבה עד שיחלים.
אתם מקבלים רק תקציר של האירוע אבל בכל זאת אני מרגיש חובה כהורה
מודאג לספר את הסיפור שלי על מנת שאם אתם הורים לילדים תבדקו שבעתיים
את הגן שהילד שלכם נמצא בו. המצאות של נעצים באיזור סטרילי כמו איזור
שבו נמצאים פעוטות היא רשלנות של הגננת/מטפלת.
אני למדתי את זה בדרך הקשה ואני מקווה שלכם זה לא יקרה.