The high cost of developing and integrating Domain-Specific Languages (DSLs) in an existing system narrows down its applicability in other domains. In this frequently changing world, the abstraction of a domain also undergoes change, which makes the maintainability of an existing DSL costly as it is change-susceptible. To overcome the problem attached to the integration, maintainability and adaptability of DSLs, the authors promote a dynamic interpretation model that allows the adaptation of the program’s execution without any syntactic change to the DSL with respect to the varying context by decoupling the semantics of the DSL from its implementation.
To support this dynamic interpretation model, the authors propose adopting a component based model where the generic interpreter coordinates with the different runtime components to interpret the language specification. The dynamic reconfiguration of these components with respect to the varying context allows for context-sensitive semantics of the same language specification. Thus, the model can be discerned as a function that takes three inputs in form of – a language definition, components and context information and outputs a dynamic configuration that reflects the specified context. By using polymorphic counterpart, a generic interpreter can reinterpret a language types of non-functional behavior can also be accommodated in the components’ implementation, thus conforming to a particular context to support these non-functional aspects. Therefore, it is evident that this model enables dynamic customization of the language semantics based on the context and various changing requirements which, in turn, makes the DSLs highly adaptable.
Provider design pattern of .Net Framework 2.0 facilitates an approach to design components in a decoupled and extensible manner. In this post, we investigate this design pattern, and show how we can utilize it to make components decoupled while providing extension points for configuration. To do so, we present the outline of today’s discussion as follows-–
Provider pattern is a way in .Net Framework 2.0 to design extensible and decoupled Component. Ron Howard mentioned –
“A provider is simply a contract between an API and the Business Logic/Data Abstraction Layer. The provider is the implementation of the API separate from the API itself.”
Provider pattern is a way to get rid of the coupling among the components while making the components extensible. Main reason for our today’s discussion on Provider Pattern is its wonderful ability to publish the API and at the same time make the API pluggable; that is– it gives us the flexibility to choose the API that is best suited for the application rather than the one developed by API developer. And from an API developer perspective, it allows them to create an extension point for the API where clients of the framework can extend the functionality in their own way.
In the next section, we walk-through an example, which builds a component using provider design pattern.
Provider Pattern in Action
The basic idea behind the provider pattern is to have multiple ConcreteProviders and selecting one of them depending on configuration (just a change in ‘*.config file can lead to completely different provider to perform the operation) at the runtime by avoiding writing huge amount of code and coupling among the components. Provider pattern completely abstract the decision of which provider to use out of programming interface. That way we can say that, it has some kind of dependency injection/inversion flavor, but it does not use any kind of container like Windsor or Spring.net.
We first consider a simple and contrived problem (designed only for illustrative purpose), which is used throughout today’s discussion. We have the following simple domain object: User and we need a persistence media to store(/Save) and retrieve(/Get) it.
This class is responsible for communicating with the physical persistence media. PersistenceManager has only two jobs.
public static void Save<T>(T obj)
public static T Get<T>()
Consider that this implementation as of now only supports two persistence media: SQL Server2005 and Xml (via File system). Depending on the clients’ need, we will be using any one of them at the runtime, keeping in mind that in future client might use some other persistence media like Oracle, mySql or whatever.
If we are not familiar with provider pattern, we would solve this problem using any dependency injection container (e.g. Windsor/Spring.Net/Unity), or introducing factory method to instantiate the desired component at the runtime; that is, either we had to introduce new code (write and manage) or new vocabulary to grasp (with dependency injection container) while providing custom solution. Truly that would be an overhead if we would like to solve only this problem. Then, why do we not use something from .Net2.0 when it is providing it (e.g. as in Asp.net Membership)?
A solution with .Net provider design pattern consist of following basic parts–
API class (PersistenceManager) to publish API(save and get). It is also responsible to instantiate a ConcreteProvider depending on the configuration.
Domain specific Abstract Provider (PersistenceProviderBase) a.k.a. Application ProviderBase inherited from ProviderBase class of System.Configuration.Provider namespace.
ConcreteProviders (XmlPersistenceProvider and SqlPersistanceProvider) inherited from domain specific Abstract Provider.
Custom Configuration Section to configure the Providers and a class inherited from ConfigurationSection to represent it in .Net.
The following diagram shows different parts of provider design pattern that we intend to discuss one by one.
We begin with a custom Configuration section.
Custom Configuration Section
In order to make the provider pattern pluggable and flexible, evidently we have to devise a wat to configure the providers at the runtime. Application configuration via .config is probably the best approach to link communication between the available providers and configuration.
To achieve this, we need to add a class inherited from ConfigurationSection to handle the configuration of providers:
Following is an example of the custom section for the Persistence Provider.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Defined to provide extra information needed to the Concrete Provider. For example , XmlPersistenceProvider will save the information about the domain object in the path specified and SqlPersistenceProvider use the value specified as the connection string to the database.
We can also define other attributes as required, which can be used to initialize the ConcreteProvider (e.g. logFilePath). Benefit of such approach is that we can return to this custom configuration, and change ConcreteProvider at the runtime.
Next we move on to explore the PersistenceManager class whose responsibility is to initialize the ConcreteProvider depending on the configuration section and publish the APIs.
PersistenceManager
PersistenceManager is the major gateway to the concrete provider as I mentioned earlier that it communicates directly with the underlying persistence media using one of the concrete provider to perform the operation (e.g. Save/Get) that it exposes.
Save method of PersistenceManager is outlined as follows.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Get method of PersistenceManager is described next.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
If we look at the PersistenceManager closely, the static Instantiate method, that instantiate the provider based on the Configuration from PersistenceProviderConfigSection. In order to do that, we use a built-in support feature of the .Net Framework2.0, which is core to this desing pattern: we will use ProvidersHelper class of System.Web.Configuration namespace. The ProvidersHelper.InstantiateProviders method initializes the ConcreteProviders by calling the Intialize() method of the ConcreteProviders (we come back to this point in the next section again).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Therefore, the DefaultProvider property in PersistenceManager always refers to the default ConcreteProvider specified in the configuration. Another alternative is to use reflection to instantiate ConcreteProvider.
Now, we describes the details of the ConcreteProvider, and how it gets initialized when we call ProvidersHelper.InstantiateProviders(config.Providers, Providers, typeof(PersistenceProviderBase)).
Application ProviderBase and Concrete Providers
In short, Application ProviderBase class or Domain-specific ProviderBase provides the abstract version of the functionality exposed by the API class, and the responsibilities of the ConcreteProviders is to implement those API in their own way. As we can see next figure, our Application ProviderBase- PersistenceProviderBase implements IPersistenceProvider, which describes the API exposed by PersistenceManager class.
ProviderBase class belongs to System.Configuration.Provider namespace, which contains all the member to be implemented by the ConcreteProviders. It contains properties to describe ConcreteProviders, such as, Name and Description. Initialize() is used to initilize providers. PersistenceProviderBase is the mirror of API or services that ConcreteProvider facilitates.
As shown below, two ConcreteProviders extends PersistenceProviderBase and provides implementation of Save and Get specific to the context of a particular provider.
In addition to that, in Initalize() method, concrete providers also initialize associated properties configured through web.config. For instance,
_PersistenceMediaPath of the concrete providers will be initialized with the value ofPersistenceMediaConnectionString from web.config.
Name and Description will be initialized.
Following code outlines the initialization process of SqlPersistenceProvider.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
To illustrate initilization of a ConcreteProvider, we show following snapshot taken from the debug-mode.
After initialization, we are only left with the Provider-specific implementation of the abstract functionality of the PersistenceProviderBase, i.e., Save/Get. Every provider will implement in their own way. For instance, if we consider XmlPersistenceProvider, it will implement the Save/Get method as follows, whereas, SqlPersistenceProvider typically stores and retrieves from Sql Server.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Why would we adopt provider design pattern?– To create loosely coupled components that are extensible from an application perspective.
Revisiting custom ConfigurationSection we have implemented, we set XmlPersistenceProvider as the default PersistenceProvider. If we want to use SqlPersistenceProvider we can simply change in the value of the defaultProvider in the web.config file and our client can start using the SqlPersistenceProvider at runtime.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
If requires, any additional provider can simply be added by extending any ConcreteProvider, or by implementing IPersistenceProvider, as shown below.
As in other providers, this new provider can also be configured during run-time as follows.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In this post, we have shown how we can utilize .net provider design pattern to make a component loosely couple and extensible. Note that in the example implementation, we have used ProvidersHelper class of System.Web,Configuration while building the component. However, we can easily get rid of adding reference to System.Web namespace, by implementing ProvidersHelper class; alternatively reflection can be used during instantiation of concrete providers.
We highly appreciate any question or query regarding this post. Thanks!
Revision
[R-1: 04-04-2013] Porting this blog-post from its weblogs.asp.net page.
By definition immutable object is the object whose state can not be changed after it is created. That means, after creating the object, its publicly exposed members can not be changed from their initial assigned values. On the contrary, mutable objects are objects whose state can be changed at any point of time.
Every developer has to take a important decision whether to make a class mutable or immutable while designing the domain model.
While taking this decision, careful considerations can make us avoid the potential pitfall of using immutable object.Why & How using immutable .Net object – is our today’s discussion. Let’s begin with How part .
How to implement .Net Immutable Object?
The way I would implement an immutable .Net class –
–Make the fields privatereadonly. –Provide a Public property with get accessor. –If the class is no longer needed to inherited – making it sealed.
Like in the following example, I am implementing an immutable class UserContact which will be inherited in User –
Here is the Implementation of the Immutable classes –
publicclassUserContact
{
privatereadonlystring _Name;
publicstring Name
{
get { return _Name; }
}
privatereadonlystring _EmailAddress;
publicstring EmailAddress
{
get { return _EmailAddress; }
}
public UserContact( string name , string emailAddress)
{
_EmailAddress = emailAddress;
_Name = name;
}
}
UserContact get inherited by User as follows [Since User class is no longer inherited – we make it sealed] –
publicsealedclassUser : UserContact
{
privatereadonlystring _UserName;
publicstring UserName
{
get { return _UserName; }
}
public User(string name, string email, string userName)
: base(name, email) { }
}
So, isn’t it really easy to implement a Truly Immutable class in .Net framework? JNow the question pops into our mind – why we will be using immutable .net objects , what would be benefits of that ? Let’s explore that –
Why use immutable object?
Protection:
From the definition we know, Immutable objects can not be changed after its being initialized. So, while using inside application, immutable object can flow in different layers of the application without getting worried about being altered by different layers.
Performance:
Copying object will be much easier, we just need to copy the reference instead of copying the whole object. It would be much faster to copy reference than the whole object.
User user = newUser(“adil”, “adil.bd@hotmail.com”, “adak”); User userTemp = user;
In case of mutable object, we would need to create defensive copy of the object and in .Net term, we need to create a Deep Copy of object otherwise, changing a property in the actual mutable object would reflect everywhere where the object is referenced.For example, let’s consider User as mutable; then changing any thing in user object will have same impact on userTemp as well which is not intended.
To avoid this situation, in case of mutable object, we need to make a Deep Copy of the object which is a costly operation. However, for immutable object, copying the reference would be enough since its state can’t be changed.
Scalability:
Thread synchronization is an issue of concern while designing multithreaded application. Overhead of synchronizing immutable object is far less than mutable object. By default , an individual immutable object does not need to be synchronized as its state will be not be modified by any thread. However, since the immutable object will still be accessed thorough reference , it would require some synchronization. In complex sync scenarios, immutable object would perform far better then mutable version.
Consistency:
If we consider inheritance hierarchy, immutability provides a way for the sub-class to maintain consistency in inheritance hierarchy. Consider following mutable objects–
When we instantiate the StudentMutable object, the AccountType is automatically set to Student Account –
public StudentMutable(string name , string email , string userName ) : base(name ,email , userName,“Student Account”){}
Now, we can write following lines by which the AccountType property could be anything other than “Student Account” which is completely inconsistent –
But if we use Immutable object in inheritance – the object hierarchy will always be consistent.:)
What to consider while designing Immutable objects?
Intantiation of immutable object might be considered an operation that will be done more frequently. Then the allocation and freeing the resource for the immutable object would be the most recurrent opertaion which might result as performace overhead. Incase of regular objects , it seems that syncronization is far more costly operation from CPU perspective than allocating and freeing resource.
For objects that require significant time to initialize , we may consider to implement Object Pool or Flyweight pattern to enhance reusability.
Conclusion
So , We can achive much faster and efficient code if we use Immutable object. But by saying all this , definitly we need to design accordingly and carefully so that immutable object can perform to its best. In this article , we learn how to implement immutable object in .Net and what’s its benefits and what we need to consider while implementing immutable object. In my next post , I am thinking to write something about reusing the immutable object to enhance efficiency. Thanks for visiting the the blog. Let me know your comments and feedbacks. Bye J .