View-Post.ascx is the user control responsbile for displaying a post, and it basically just hands the work off to the class, EntryViewContainer. Here is a snippet of EntryViewContainer:
One of the interesting things here that I won’t really go into is the use of a BlogPostQuery object to pass parameters that essentially end up as parameters for stored procedures. This is a nice way to package up parameters as opposed to having several overloads of GetPosts that take varying parameters.
As you can see, EntryViewContainer just grabs the BlogID and PostID along with a few defaults and calls WeblogPosts.GetPosts to go get the post to be displayed. It actually returns a PostSet object, which is basically a thread of posts – the main post and the flow of comments to the post.
Here is where the caching is done as well as where we start to see the data providers coming into action. WeblogDataProvider is an abstract class with not much more than a single method, Instance(), that grabs the concrete data provider class that handles the storage operations for blogs. The concrete class returned is the class that actually carries out the operation to get the post and its comments from data storage. Here is some of the code in WeblogDataProvider:
The main work happens in the CreateDefaultCommonProvider method. It goes out and grabs the configuration information which contains the name of the concrete class that will be handling the data storage and retrieval of blog posts. This information is tucked away in a config file, called communityserver.config, that has the following entry:
There is the concrete class that will actually be handling the blog storage and retrieval: WeblogSqlDataProvider. You can guess that we will need to dynamically create this class during runtime. This is the job of the DataProviders class, which is just a set of helper functions for just that thing:
The CreateInstance method is the work horse that uses reflection to create an instance of the concrete class, WeblogSqlDataProvider, that will eventually get returned to the controller class, WeblogPosts.
As you can see below, WeblogSqlDataProvider is making use of the BlogPostQuery object to pass out the values for the parameters and essentially just calling the stored procedure that returns a few resultsets of data to be passed back as a PostSet.
When you break down the source code like this it becomes pretty clear how all these fundamental OOP techniques come into play . There are a few other goodies in Community Server that are probably worth talking about at a later time, too.
That is very nice, David!
Quick question: how do you get the source code? I downloaded the project as well from their site. But only ASPX files and DLLs, there has no source code for those DLLs.
the Instance() method is often referred to as a Factory Method. It essentially hides the actual class that is being instantiated from the client code.
There is no requirement that the concrete class being created is done via reflection or not.
Enterprise Library and Community Server use reflection only to support instantiating classes in 3rd party assemblies. This creates more of a true plug-in framework.
The Abstract Factory Pattern has to do with creating families of classes, which is not what is being done here.
A good series of articles on design patterns would be a phenomenal contribution to the developer community. So many things to talk about, so little time
I may be a little confused about Abstract Factory… I thought you could do it without the reflection stuff, but now that I think about it, (and read your first post) I see that this is standard.
This is a nice explanation. I’ve not delved this deep into the actual data provider implementation yet, but I have a question for you..
Is this a variation on the Abstract Factory pattern? If so, what is the benefit of doing it this way? With a traditional AF pattern you wouldn’t need the Activator.CreateInstance stuff, which is does have performance issues.
I’m sure there are very good reasons for doing it this way – a “method to the madness.”
Community server is a pretty large app.. there are all kinds of neat things to see once you get under the covers, huh?
Very appreciate, David! It is very interesting to look at the source code. The first time I saw this Provider Pattern was from Rainbowportal.
Here is the link to download the community server source code for version 1.0:
http://www.telligentsystems.com/Solutions/license.aspx?File=cs_1.0_src.exe
That is very nice, David!
Quick question: how do you get the source code? I downloaded the project as well from their site. But only ASPX files and DLLs, there has no source code for those DLLs.
“With a traditional AF pattern you wouldn’t need the Activator.CreateInstance stuff, which is does have performance issues.”
Since it looks like the instance will only ever be created once, this isn’t really an issue.
Hey Brendan,
There is no abstract factory pattern used in the above example.
In this piece of code:
WeblogDataProvider wdp = WeblogDataProvider.Instance();
the Instance() method is often referred to as a Factory Method. It essentially hides the actual class that is being instantiated from the client code.
There is no requirement that the concrete class being created is done via reflection or not.
Enterprise Library and Community Server use reflection only to support instantiating classes in 3rd party assemblies. This creates more of a true plug-in framework.
The Abstract Factory Pattern has to do with creating families of classes, which is not what is being done here.
A good series of articles on design patterns would be a phenomenal contribution to the developer community. So many things to talk about, so little time
I may be a little confused about Abstract Factory… I thought you could do it without the reflection stuff, but now that I think about it, (and read your first post) I see that this is standard.
This is a nice explanation. I’ve not delved this deep into the actual data provider implementation yet, but I have a question for you..
Is this a variation on the Abstract Factory pattern? If so, what is the benefit of doing it this way? With a traditional AF pattern you wouldn’t need the Activator.CreateInstance stuff, which is does have performance issues.
I’m sure there are very good reasons for doing it this way – a “method to the madness.”
Community server is a pretty large app.. there are all kinds of neat things to see once you get under the covers, huh?