Simple parallel programming

0

Posted on : 18-05-2009 | By : matteosp | In : .Net Programming, ParallelProgramming, Threading

While waiting for Parallel Extensions (wikipedia), that will be shipped with next .Net Framework release, I designed a couple of class that allow to quickly (and easily!) write code that make use of multi-threading and, therefore, speed-up many tasks. What I show here is a simple class able to collect pieces of code (in form of delegate) to be executed concurrently, and parallelize and synchronize the execution. The main goals I kept in mind while realizing the solution were:

  • Ease of use, minimal requirement in terms of multi-threading skills
  • Allowing single-threaded code to be ported to multi-threading with few changes
  • Code readability
  • Support for exception management

Here what I came up with:

The API exposes one class, ParallelExecutor, and one interface, IExecutionResult (plus a generic specialization of the interface and the necessary implementations). Before seeing the internals of the solution, I want to show the ease of use of the API.
Let’s start with this example:

   1:  void SerialExecution()
   2:  {
   3:      Uri uri; int value;
   4:  
   5:      CallWebService(uri);
   6:      PerformComputation(value);
   7:  }

CallWebService() and PerformComputation() represent the most classic example of methods that can (and should!) run in parallel as they perform respectively I/O and CPU computation. But usually programmers haven’t enough confidence with multi-threading execution and synchronization to do things in the right way. In any case they shouldn’t care about this stuff, they should focus on coding logic, and not on coding about how the logic get’s executed. Let’s see how ParallelExecutor comes in help:

   1:  void ParallelExecution
   2:  {
   3:    Uri uri; int value;
   4:  
   5:    ParallelExecutor executor = new ParallelExecutor();
   6:  
   7:    executor.Add(CallWebService, uri);
   8:    executor.Add(PerformComputation, value);
   9:  
  10:    executor.WaitAll();
  11:  }

Not too bad, right? With a couple of lines I got the two methods run concurrently. This is pretty simple: the Add() method takes as arguments the method to invoke and the arguments of that method. The WaitAll() causes the calling thread to wait for all the methods passed to Add() to complete. Take a (partial) look to the ParallelExecutor definition:

   1:  public class ParallelExecutor
   2:  {
   3:    public IExecutionInfo<object> Add(Action workItem)
   4:    public IExecutionInfo<object> Add<T>(Action<T> workItem, T arg)
   5:    //overloads for other Action versions 
   6:  
   7:    public IExecutionInfo<TResult> Add<TResult>(Func<TResult> workItem)
   8:    public IExecutionInfo<TResult> Add<T, TResult>(Func<T, TResult> workItem, T arg)
   9:    //overloads for other Func versions 
  10:  
  11:    public bool WaitAll():
  12:  }

As you can see, method to be parallelized are passed to Add() in form of variations of Action and Func generics delegate (there are also overloads that take MethodInfo and the standard Delegate). But what about the Add() return type, IExecutionResult? Let’s see the interface declaration:

   1:  public interface IExecutionInfo
   2:  {
   3:    object[] Args { get; }
   4:  
   5:    Exception Exception { get; }
   6:  
   7:    object Result { get; }
   8:  }
   9:  
  10:  public interface IExecutionInfo<TResult> : IExecutionInfo
  11:  {
  12:    TResult Result { get; }
  13:  }

At every invocation of the Add() method an instance of a class implementing IExecutionResult is created, and its Args property is filled with method invocation arguments. After the invocation completes, the Result and Exception property are filled too (in both case, if any). And the magic of generics allow the code to be type safe. So, returning to the example, if CallWebService() has a return value and if you want to check for exceptions, you can write:

   1:  void ParallelExecution
   2:  {
   3:    Uri uri; int value;
   4:  
   5:    ParallelExecutor executor = new ParallelExecutor();
   6:  
   7:    IExecutionInfo<int> execution = executor.Add<Uri, int>(CallWebService, uri);
   8:    executor.Add(PerformComputation, value);
   9:  
  10:    executor.WaitAll();
  11:  
  12:    if (execution.Exception != null)
  13:        ManageException(execution.Exception);
  14:    else
  15:        Console.WriteLine("Result: {0}", execution.Result);
  16:  }

Another couple of properties exposed by ParallelExecutor allow you to control when the execution starts (immediately after Add() or when WaitAll() gets called) and the aggressiveness of the threading policy (one new Thread for every method passed to Add() or threads got from ThreadPool).

Obviously this is a very simple implementation, far away from what Parallel Extensions will be. But its simplicity may suite well some implementation with no heavy requirements.

Source Code.

Dynamics CRM as development platform: transparent substitution of CrmService with Filtered Views.

1

Posted on : 06-04-2007 | By : matteosp | In : .Net Programming, Microsoft CRM 3.0, Sql Server

In my last post I suggested not to directly use, in your code, the CrmService proxy class. I quickly mentioned some enhancements you can gain from this, let’s focus on substituting web service calls with database access on filtered views. Even if limited to read operations, this can increase a lot the performances of your system.

As we want the callers not to be aware of the way we retrieve data, we have to passing back data to them in the form they expect it: “BusinessEntity” derived classes or collection of them. This may seems hard, but it isn’t. You can build the statement in way that it will produce data in XML, in a format that can be directly deserialized in entity instances.

So, let’s view how we can:

  • Compose the SQL statements in such a way the will produce the xml we need
  • Deserialize the data from xml to entities

Take a look at this query:

WITH XMLNAMESPACES
(
  'http://www.w3.org/2001/XMLSchema' as xsd
, 'http://www.w3.org/2001/XMLSchema-instance' as xsi
, 'http://schemas.microsoft.com/crm/2006/WebServices' as crm
)
SELECT name as 'crm:name'
     , accountid as 'crm:accountid'
     , donotphonename as 'crm:donotphone/@name'
     , donotphone as 'crm:donotphone'
     , address1_shippingmethodcodename as 'crm:address1_shippingmethodcode/@name'
     , address1_shippingmethodcode as 'crm:address1_shippingmethodcode'
     , modifiedbyname as 'crm:modifiedby/@name'
     , modifiedbydsc as 'crm:modifiedby/@dsc'
     , modifiedby as 'crm:modifiedby'
     , createdbyname as 'crm:createdby/@name'
     , createdbydsc as 'crm:createdby/@dsc'
     , createdby as 'crm:createdby'
     , statuscodename as 'crm:statuscode/@name'
     , statuscode as 'crm:statuscode'
     , statecodename as 'crm:statecode/@formattedValue'
     , statecode as 'crm:statecode'
  FROM Filteredaccount
   FOR XML PATH ('account')

The WITH XMLNAMESPACES, the field aliases and the FOR XML PATH do the magic, and we get data in this format:

<account xmlns:crm="http://schemas.microsoft.com/crm/2006/WebServices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <crm:name>Adventure Works Ltd.</crm:name>
  <crm:accountid>E85D1177-EE17-DB11-87E4-0000E2998A6B</crm:accountid>
  <crm:modifiedby name="CRM Administrator" dsc="0">89A611D4-C7BD-DB11-A4E3-005056A80A71</crm:modifiedby>
  <crm:createdby name="CRM Administrator" dsc="0">89A611D4-C7BD-DB11-A4E3-005056A80A71</crm:createdby>
  <crm:statuscode name="Active">1</crm:statuscode>
  <crm:statecode formattedValue="Active">Active</crm:statecode>
</account>
<account xmlns:crm="http://schemas.microsoft.com/crm/2006/WebServices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <crm:name>Contoso Inc.</crm:name>
  <crm:accountid>A00ED7BB-9D0D-DB11-9073-000C293F9D57</crm:accountid>
  <crm:donotphone name="Allow">0</crm:donotphone>
  <crm:modifiedby name="CRM Administrator" dsc="0">89A611D4-C7BD-DB11-A4E3-005056A80A71</crm:modifiedby>
  <crm:createdby name="CRM Administrator" dsc="0">89A611D4-C7BD-DB11-A4E3-005056A80A71</crm:createdby>
  <crm:statuscode name="Active">1</crm:statuscode>
  <crm:statecode formattedValue="Active">Active</crm:statecode>
</account>

That is exactly what you need to obtain, with the help of XmlSerializer, a collection of accounts:

XmlReader xmlReader = cmd.ExecuteXmlReader();
xmlReader.Read();

while (xmlReader.ReadState != ReadState.EndOfFile)
{
    xml = xmlReader.ReadOuterXml();
    StringReader reader = new StringReader(xml);

    account acc = serializer.Deserialize(reader) as account;
    accounts.Add(acc);
}

// convert accounts in a BusinessEntitesCollection...

Note that:
- the standard SQL syntax for a property is:

, property ascrm:property

- properties expressed by CRM object model in form of “Lookup” are splitted, on the views, in three columns:

, propertyname ascrm:property/@name
, propertydsc ascrm:property/@dsc
, property ascrm:property

- properties expressed by CRM object model in form of “Picklist” and “CrmBoolean” are splitted, on the views, in two columns:

, propertyname ascrm:property/@name
, property ascrm:property

- StatusCode and StateCode are the only further singularity.

Given these rules isn’t hard to build a class able to generate statements for any entity type. For an hard-core solution, add something able to translate a QueryExpression in SQL statements…

Quiz #1

0

Posted on : 15-03-2007 | By : matteosp | In : .Net Programming, C#, Quiz

Modify this apparently thread-safe event raiser in such a way it becomes truly thread-safe without changing signature nor implementation.

protected void OnMyEvent(MyEventArg e)
{
   MyEventHandler handler = MyEvent;

   if (handler != null)
      handler (this, e);
}

Inspired by this post by Pierre Greborio.

Quiz Sharp #0

1

Posted on : 09-03-2007 | By : matteosp | In : .Net Programming, C#, Quiz

This is my first quiz, and is the result of a beatiful and long chat with my good friend Adrian Florea. Here the Italian version on his blog.

Look at this snippet:

struct Foo
{
	public static implicit operator bool(Foo value)
	{
		return value != null;
	}
}

static void Main(string[] args)
{
	if (new Foo())
	{
		Console.WriteLine("Hello word!");
	}
}

What will you get? And, first of all, why?

a) nothing

b) “Hello word!”

c) a compiler error

d) a runtime error

System.Diagnostics.Trace is not safe.

0

Posted on : 22-02-2006 | By : matteosp | In : .Net Programming

I always thought that methods exposed by System.Diagnostics.Trace class did something like dispatching messages to the OS and/or to the trace listeners configured for the application. And by dispatching I mean a sort of asynchronous and safe (from exceptions in the listeners if any) delivering of messages.

I don’t know exactly why I had this idea in my mind, but in any case it was a wrong idea. The execution of method like Trace.WriteLine(”my message”) is synchronous, and may generate an exception if something goes wrong in one of the trace listeners currently registered.
I think that this can occurs easily because:
- trace listeners can be simply registered by editing the configuration file.
- you can pass to Trace class methods messages in form of objects, not only strings.
- if your are programming a component you may not have envision of the environment in which your code will run.

I have to start enclose calls to those methods in try – catch blocks. I would like to know: does someone (if there is someone that use this class) already do it?

Custom collections and databinding, part 2: filtering.

0

Posted on : 08-11-2005 | By : matteosp | In : .Net Programming

In my last post I presented myimplementation of a class that incapsulates the
logic for supporting the databing of a generic custom collection.

Now I want to discuss the way I implemented the capability to filter data presented the consumers of my class. What I was looking for and I obtained is the possibility to apply a filter in the way of a complex filter expression like ” AnyProperty = ‘AnyValue’ AND AnotherProperty > = ‘AnotherValue’ AND NOT ThirdProperty LIKE ‘%ThirdValue%’ “.

I’m going to present my solution and I hope to read your comments, opinions,
and so on. Remember that my class, CollectionView
, accept as source any class that implements ICollection and that consequently
I must be able to apply that kind of filter expression to any kinf of object.

Consider the example:

ArrayList list = new ArrayList();list.Add(new Blogger(”Albert Einstein”, “blogs.genies.org/albert”, 45));

list.Add(new Blogger(”Jack Keruoac”, “blogs.beatfoundation.org/jk”, 24));

list.Add(new Blogge(”Henry Miller”, “blogs.lesparisiennes.fr/henry”, 36));

CollectionView view = new CollectionView(list);

view.FilterExpression = “Age >= ‘36′ AND BlogUrl LIKE ‘blogs.beatfoundation%’ AND NOT Name LIKE ‘Alb%’”;


in which Blogger is a very simple class with only 3 properties:
public int Age,
public string BlogUrl and
public string Name.

I divided the logic needed to apply the filter into 3 classes: CollectionViewFilter,
ConditionEvaluator, ExpressionEvaluator.
All these 3 classes are declared internal in my class library as the only
property CollectionView exposes for applying the filter is a string FilterExpression {get; set;}.
Let’s examine these classes.

CollectionViewFilter.

This class is the entry point for the filtering process. It contains the
routines needed to extract from the filter expression the tokens that represent
the single conditions. The filter expression needs to be passed to constructor
and the tokens extraction is done with the help of a regular expression. So
considering the example above, it split that filter expression in these 3
tokens:

  • Age >= ‘36′
  • BlogUrl LIKE ‘blogs.beatfoundation%’
  • Name LIKE ‘Alb%’

The class exposes only one public method that is: public bool MatchObject(object obj). The purpose of this method is obviouisly returning a bool value that indicates if the object in argument meet all the conditions (expressed by the 3 tokens) or not. I do this by extracting from every token the property name (i.e.: BlogUrl), the operator (LIKE) and the property value (’blogs.beatfoundation%’). I delegate the process of verifying if the property BlogUrl of any instance of the Blogger class is LIKE ‘blogs.beatfoundation%’ to the ConditionEvaluator class.

ConditionEvaluator.

This logical task accomplished by this class is quite simple, I will not discuss over it’s implementation. It accept in the constructor the property name, the operator and the property value that CollectionViewFilter class extracts from each token, then it performs these steps:

  • Discover via reflection the property descriptor for the specified property
    name.
  • Receive the instance of the object that needs to be matched with the condition
    (the same instance received by CollectionViewFilter
    in MatchObject()
    method, in the case of my example an instance of the Blogger class.)
  • Perform the necessary comparison based on: the property type, the specified
    operator and the jollychars if any in the value.
  • Returns a bool value indicating if the passed instance meets the condition
    (BlogUrl LIKE ‘blogs.beatfoundation%’).

CollectionViewFilter repeats the operation for each token it extracted from the filter expression. So it use ConditionEvaluator for evaluate on the instance passed to MatchObject() method all the conditions expressed by the 3 tokens. This will cause the original filter expression

Age >= ‘36′ AND BlogUrl LIKE ‘blogs.beatfoundation%’ AND
NOT Name LIKE ‘Alb%’
“;

to be translated is a string like:

true AND true AND NOT true” (the case of
new Blogger(”Albert Einstein”, “blogs.genies.org/albert”, 45)
).

ExpressionEvaluator .

Now, how can I simply translate a string like the one obove (or a more
complex one) in single evalutaed bool value? Why the magic C# team didn’t
implemented an Eval function like the one JScript has? And the I told to my
self: “Hey! wait a moment. As I can compile some JScript statement I can get
the Eval function in my C# runtime!!”

And I did it this way in my ExpressionEvaluator class,
look at this snippet:
private static object evaluator = null;private static Type evaluatorType = null;

private static readonly string jsSource =

@”package ExpressionEvaluator

{

class Evaluator

{

public function Eval(expr : String) : String

{

return eval(expr);

}

}

}”;

static ExpressionEvaluator()

{

ICodeCompiler compiler = new JScriptCodeProvider().CreateCompiler();

CompilerParameters parameters = new CompilerParameters();

parameters.GenerateInMemory = true;

CompilerResults results = compiler.CompileAssemblyFromSource(parameters, jsSource);

Assembly assembly = results.CompiledAssembly;

evaluatorType = assembly.GetType(”ExpressionEvaluator.Evaluator”);

evaluator = Activator.CreateInstance(evaluatorType);

}
The JScript statement contained in jsSource is compiled only once in the
static constructor (need a reference to microsoft.jscript.dll) and is available
for functions like:
public static bool EvalToBoolean(string statement){

object o = EvalToObject(statement);

return bool.Parse(o.ToString());

}

public static object EvalToObject(string statement)

{

BindingFlags flags = BindingFlags.InvokeMethod;

object[] args = new object[] { statement };

return evaluatorType.InvokeMember(”Eval”, flags, null, evaluator, args);

}
This made my class CollectionViewFilter able to
simply resolve “true AND true AND NOT true” into “false”.The entire process is launched by CollectionView whenever
it has to build is inner source from the ICollection
passed in his constructor or when is property FilterExpression
changes to determine which of the elements in the source collection should be
passed to the dataconsumer.

UPDATE: I forgot a little thing: in order to make a string like
“true AND true AND NOT true” evaluable by the JScript routine you have to
replace the logical operators, in particular you must replace “AND” with
“&&”, “OR” with “||”, “NOT” with “!”.

Custom collections and databinding.

0

Posted on : 05-11-2005 | By : matteosp | In : .Net Programming

I always prefer custom business objects to .Net Datasets and Datatables when I write data representation logic for my web apps. So data abstraction layers I write are plenty of classes representing business entities and type-safe custom collections for entities enlisting. While collecting instances in a custom collection is not an hard task at all, provide to a collection functionalities like complex databinding, sorting and filtering is a little bit harder. Furthermore incapsulating such as capibilities in only one generic class requires a bit of time… But now I got it! I have this generic class (I call it CollectionView) that:

  • accepts as source any class implementing ICollection interface
  • generates a set of bindable columns based on the Type of the objects collected by the source.
  • allows the manipulation of the columns set (reordering, visibility, etc)
  • supports sorting and filtering
  • is a valid datasource for .Net WebControls

Let’s take a look to how I did this. First of all class signature and construtors:

public class CollectionView : ITypedList, IEnumerable, ICollection { public CollectionView(ICollection collection) { m_collection = collection; } public CollectionView(ICollection collection, Type collectionItemsType) { m_collection = collection; m_collectionItemsType = collectionItemsType; } // }

CollectionView implements 3 interfaces: ITypedList, IEnumerable, and ICollection. IEnumerable is obviously required for a complex databinding and ICollection (through Count property) allows operation such as paging. ITypedList allows to notify the dataconsumer (the web control that CollectionView will be bound to) which are the properties of the source collection items we want to be considered in the binding process. To be more precise: during the databinding process the dataconsumer invokes the GetItemProperties() method on ITypeList and receive the collection of property descriptors that it will use to bind it’s items (i.e: DataGrid items) to the collection items. Here ITypedList declaration:

public interface ITypedList { PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors); string GetListName(PropertyDescriptor[] listAccessors); }

Looking at the constructors you can understand that as the source collection is referenced through ICollection is possible to specify as source almost all the kind of collection you can have in the Framework. Optionally, also the Type of objects the source contains can be explicitly declared. This optional declaration is important because influences the way CollectionView builds the set of bindable columns and in turn this columns set can influence the PropertyDescriptorCollection instance returned by the GetItemProperties() method we’ve just seen. It will soon be more clear as I’m going to explain it. The return value of GetItemProperties() could have been exactly the result of a query for the public properties exposed by items in the source collection. But I decided to add the possibility, for the caller of CollectionView, to reorder these properties or to hide some of them. So what I’ve done is:

  • I created a class named CollectionViewColumnSet that is a type-safe collection (another one!) of CollectionViewColumn objects and that is exposed by CollectionView through the Columns property.
  • This column set is generated (the first time the Columns property is accessed) querying the public properties of the items in the source collection and every CollectionViewColumn will map one of these properties.
  • CollectionView callers are able to reorder the columns or hide some of them through properties such as Visible (bool) and Ordinal (double) exposed by CollectionViewColumn class.
  • When the dataconsumer calls GetItemProperties() the PropertyDescriptorCollection to be returned is build reflecting the state of each column in the column set.

Here the 2 routines I wrote to query the properties of the items in the source collection (DiscoverPropertyDescriptors) and to build the column set (EmitColumnsFromProperties):

private PropertyDescriptorCollection DiscoverPropertyDescriptors() { if (m_collectionItemsType != null) return TypeDescriptor.GetProperties(m_collectionItemsType); else { // if caller has not explict declared the Type of the items in the source collection // I try to discover if by my self: object item = GetAnyItemFromTheSourceCollection(); if (item != null) return TypeDescriptor.GetProperties(item); else { // in this case the dataconsumer will not be able to complete the binding process // but I can’t do anything abount that. May be I should throw an exception… PropertyDescriptor[] properties = new PropertyDescriptor[0]; return new PropertyDescriptorCollection(properties); } } } private CollectionViewColumnSet EmitColumnsFromProperties() { CollectionViewColumnSet cols = new CollectionViewColumnSet(); PropertyDescriptorCollection descriptors = DiscoverPropertyDescriptors(); foreach (PropertyDescriptor propertyDesc in descriptors) { CollectionViewColumn col = new CollectionViewColumn(propertyDesc.Name, propertyDesc); col.Ordinal = cols.Count; cols.Add(col); } return cols; }

Now you can understand what I meant when I was saying that the optional explicit declaration (with the second overload of the constructor) of the Type of the items in the source collection is important: in the case in which the Type is declared I call TypeDescriptor.GetProperties() passing it as argument, in the second case I have to try to find an item in the collection and use this as argument. Is important to know that: taken an instance of any class fooInstance the results of TypeDescriptor.GetProperties(fooInstance) and TypeDescriptor.GetProperties(fooInstance.GetType()) can be different. In fact, and I report what the Framework documentation says, the properties for a component can differ from the properties of a class, because the site can add or remove properties if the component is sited.

To complete the column set life-cycle, this is the implementation of ITypedList.GetItemProperties() method in which I reflect the column set state to the properties returned to the dataconsumer:

public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) { return ReflectPropertiesFromColumns(); } private PropertyDescriptorCollection ReflectPropertiesFromColumns() { ArrayList descriptors = new ArrayList(); foreach (CollectionViewColumn col in this.Columns) { if (col.Visible) descriptors.Add(col.PropertyDescriptor); } PropertyDescriptor[] properties = new PropertyDescriptor[descriptors.Count]; descriptors.CopyTo(properties, 0); return new PropertyDescriptorCollection(properties); }

I have another couple of interesting things to tell about managing the properties-columns and about filtering the source collection, but it’s 4.00 AM so: to be continued…

Provider model everywhere

0

Posted on : 22-10-2005 | By : matteosp | In : .Net Programming

Today I developed a small and simple web control (on1.1) that represents a navigation bar. The goal was realize this navigation bar with Microsoft CRM “look and feel” as it would to be inserted on a CRM integration project.

I started with 3 classes: NavigationBar, NavigationBarItem and NavigationBarItemCollection. NavigationBar and NavigationBarItem inherit from WebControl. I wrote all common properties and methods you usually have to implement (or to override) to manage the ViewState, the DataBinding process, ect. I think I wrote some nice code on IEnumerable, IListSource, IList and ITypedList interfaces to accept as datasource as many types as possible. But this is not what I want to talk about, may be I will do it in another post.

After that I reached the rendering phase and I realized: “I don’t want a control with a CRM look and feel. I want a control that is flexible enought for rendering its content in many ways, and sometimes in the CRM look and feel way.” And I proceeded this way:

1)I defined a new abstract class named NavigationBarRenderingProviderBase that requires an instance of NavigationBar (the control to be rendered) to be passed in the constructor, exposes this instance in a protected readonly property and defines 3 abstract methods. Here this class code:

public abstract class NavigationBarRenderingProviderBase { private NavigationBar navigationBar; protected NavigationBarRenderingProviderBase(NavigationBar navigationBar) { this.navigationBar = navigationBar; } protected NavigationBar NavigationBar { get { return navigationBar; } } public abstract void RenderNavigationBarStart(HtmlTextWriter writer); public abstract void RenderNavigationBarEnd(HtmlTextWriter writer); public abstract void RenderNavigationBarItem(HtmlTextWriter writer, NavigationBarItem navigationBarItem); }

As their names say, the 3 abstract methods will handle the begin of the rendering process, the rendering of every item in the NavigationBar and the end of the process.

2) I developed a basic specialization of this class, named NavigationBarRenderingProvider. And I wrote the code needed for the standard rendering of my control.

3) I developed a further specialization of this class, named CrmNavigationBarRenderingProvider. And I wrote the code needed for rendering my control in the CRM look and feel.

4) I defined a property in NavigationBar throught which is possible to define the rendering provider to use. This property returns the standard rendering provider (NavigationBarRenderingProvider ) if no one has been set.

public NavigationBarRenderingProviderBase RenderingProvider { get { if (m_RenderingProvider == null) m_RenderingProvider = new NavigationBarRenderingProvider(this); return m_RenderingProvider; } set { m_RenderingProvider = value; } }

5) I overrode the render method to obtain the delegation of the rendering process to the rendering provider.

protected override void Render(HtmlTextWriter writer) { this.RenderingProvider.RenderNavigationBarStart(writer); foreach (NavigationBarItem item in this.Items) { this.RenderingProvider.RenderNavigationBarItem(writer, item); } this.RenderingProvider.RenderNavigationBarEnd(writer); }

Done. I have a WebControl that: – incapsulates all the logic needed to support DataBinding and to manage then ViewState. – exposes the rendering algorithm(s) trought a standard interface to allow different behaviours.I’m now thinking about making possible to configure the default rendering provider in web.config file. This will allow to easily change the rendering behaviour of my control in the entire web application. But I’m still not sure…

But, what about this implementation? Can I think to it as a to provider model implementation even if isn’t strictly related to data management? I think so, and you?