Click here to Skip to main content
15,883,901 members
Articles / Programming Languages / C#
Article

Understanding and Implementing Proxy Pattern in C#

Rate me:
Please Sign up or sign in to vote.
4.79/5 (21 votes)
11 Nov 2012CPOL5 min read 133.4K   2.8K   53   14
This article talks about Proxy pattern, when should we use proxy pattern and what are the benefits of using the Proxy pattern.

Introduction

This article talks about Proxy pattern, when should we use proxy pattern and what are the benefits of using the Proxy pattern. This article also presents a small rudimentary implementation of Proxy pattern to illustrate the pattern.  

Background  

There is sometimes scenarios where we need to access the objects that are either a part of the separate application, separate domain or perhaps are installed on the other part of the world. 

If we need to access such objects of functionality we need to handle the communication logic between applications too. i.e. If we need to talk to separate application on same machine then we need IPC. If we need to talk to an application of other machine on same network then Socket programming is needed. If we need to access the application located on the internet then perhaps we need SOAP mechanism to access it.  

The whole point of the above scenario illustration is to understand that along with the code/logic to cater to the real functionality/data we need to put in the logic to handle the communication logic too. If we put these two type of logic in same object then this will lead to unmaintainable software. Also, it is little error prone too.

The whole idea of a proxy pattern is to have a local module that will mimic the functionality of the real module. This way the application will deal with this local module as if it only contains the real functionality. All the logic for communicating to the remote module can be put inside this local module i.e. Proxy.

GoF define proxy pattern as "Provide a surrogate or placeholder for another object to control access to it." 

To illustrate this design pattern, first look at the class diagram for the pattern. 

Image 1 

Let us try to understand each of them one by one

  • Subject: This class provides and interface that both actual class and proxy class will implement. this way the proxy can easily be used as substitute for the real subject.
  • Proxy: This class will be used by the applications and will expose the methods exposed by the Subject. the application will use this class and this class will internally take care of talking to the RealSubject and get the data to the local application.
  • RealSubject: This is the real object that contains the actual logic to retrieve the data/functionality. This is the class that the proxy represents at application end.

Earlier we have seen some superficial categorization for the scenarios where Proxy will be needed. If we need to identify the type of proxies based on the scenarios then we could have three type of proxies. 

  • Remote proxies: They are responsible for representing the object located remotely. Talking to the real object might involve marshalling and unmarshalling of data and talking to the remote object. All that logic is encapsulated in these proxies and the client application need not worry about them.
  • Virtual proxies: These proxies will provide some default and instant results if the real object is supposed to take some time to produce results. These proxies initiate the operation on real objects and provide a default result to the application. Once the real object is done, these proxies push the actual data to the client where it has provided dummy data earlier.
  • Protection proxies: If an application does not have access to some resource then such proxies will talk to the objects in applications that have access to that resource and then get the result back.

Using the code

Now let us go ahead and try to work out a simple example to see how this pattern can be implemented. We will try to implement a simple application that tries to get the up to date prices of commodities and Dollar value from a remote server. The local application will use a Proxy class that provides simple methods to get these  values. The proxy class will internally talk to the server and get the values. 

The server for this scenario will typically be a webservice returning values from some database. For the sake of simplicity, I have written the server as a simple application returning hard coded values. The communication between client and server is simple socket programming. 

Let us start by looking at the Subject interface which provides a common interface for proxy and RealSubject

C#
interface IActualPrices
{
    string GoldPrice
    {
        get;
    }
 
    string SilverPrice
    {
        get;
    }
 
    string DollarToRupee
    {
        get;
    }
}

Now we have the Subject class ready lets see the implementation of our RealSubject.

C#
class ActualPrices : IActualPrices
{
    public string GoldPrice
    {
        get
        {
            // This value should come from a DB typically
            return "100";
        }
    }
 
    public string SilverPrice
    {
        get
        {
            // This value should come from a DB typically
            return "5";
        }
    }
 
    public string DollarToRupee
    {
        get
        {
            // This value should come from a DB typically
            return "50";
        }
    }
}

These are contained in the server application. The communication logic for the server application is written in the Main function of server application but this could very well be embedded inside a separate skeleton class to provide more modularity. For now lets assume the Main function as a part of skeleton class only. 

C#
static void Main(string[] args)
{
    IPAddress ip = IPAddress.Parse("127.0.0.1");
    TcpListener listener = new TcpListener(ip, 9999);
 
    while (true)
    {
        listener.Start();
        Console.WriteLine("Waiting .....");
        Socket s = listener.AcceptSocket();
 
        byte[] b = new byte[100];
 
        int count = s.Receive(b);
 
        string input = string.Empty;
 
        for (int i = 0; i < count; i++)
        {
            input += Convert.ToChar(b[i]);
        }
 
        IActualPrices realSubject = new ActualPrices();
        string returnValue = string.Empty;
 
        switch (input)
        {
            case "g":
                returnValue = realSubject.GoldPrice;
                break;
            case "s":
                returnValue = realSubject.SilverPrice;
                break;
            case "d":
                returnValue = realSubject.DollarToRupee;
                break;
        }
 
        ASCIIEncoding asen = new ASCIIEncoding();
        s.Send(asen.GetBytes(returnValue));
 
        s.Close();
        listener.Stop();
        Console.WriteLine("Response Sent .....");
    }
}

Now we have the server side part of the application ready. Let us now look at the Proxy class that will talk to the RealSubject

C#
class ActualPricesProxy : IActualPrices
{
    public string GoldPrice
    {
        get
        {
            return GetResponseFromServer("g");
        }
    }
 
    public string SilverPrice
    {
        get
        {
            return GetResponseFromServer("s");
        }
    }
 
    public string DollarToRupee
    {
        get
        {
            return GetResponseFromServer("d");
        }
    }
 
    private string GetResponseFromServer(string input)
    {
        string result = string.Empty;
        using (TcpClient client = new TcpClient())
        {
            client.Connect("127.0.0.1", 9999);
 
            Stream stream = client.GetStream();
 
            ASCIIEncoding asen = new ASCIIEncoding();
            byte[] ba = asen.GetBytes(input.ToCharArray());
 
            stream.Write(ba, 0, ba.Length);
 
            byte[] br = new byte[100];
            int k = stream.Read(br, 0, 100);
 
            
 
            for (int i = 0; i < k; i++)
            {
                result += Convert.ToChar(br[i]);
            }
 
            client.Close();
        }
        return result;
    }
}

The important thing to note here is that the Proxy exposes the same interface as the real subject and encapsulate the communication, marshalling and unmarshalling details in it. This make the client code cleaner and simpler as if it is using the real application. 

So if we look at the client application code: 

C#
static void Main(string[] args)
{
    IActualPrices proxy = new ActualPricesProxy();
 
    Console.WriteLine("Gold Price: ");
    Console.WriteLine(proxy.GoldPrice);
 
    Console.WriteLine("Silver Price: ");
    Console.WriteLine(proxy.SilverPrice);
 
    Console.WriteLine("Dollar to Ruppe Conversion: ");
    Console.WriteLine(proxy.DollarToRupee);
}

Now if we run the Client application (provided the server application is running already), we can see the output as:

Image 2 

So we can see that the Proxy class fetches the results from the RealSubject located in another application and the client application remain oblivious of the fact that the application exist somewhere else. Before wrapping lets look at the class diagram of our application and compare it with the GoF diagram. 

Image 3

Point of interest

In this article we have tried to see what is Proxy pattern, when could we find it useful. We also saw a rudimentary implementation of proxy pattern in C#. This pattern sometimes looks very similar to decorator and  adapter pattern but its not. Decorator adds additional functionality on an object by wrapping the object, the  adapter provides a changed interface for the object whereas the proxy pattern provides the same interface as the original object but wraps it to hide the communication and marshalling/unmarshalling details.  This article has been written from a beginner's perspective. I hope this has been informative.

History

  • 12 November 2012: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India

I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems. IMO, C# is the best programming language and I love working with C# and other Microsoft Technologies.

  • Microsoft Certified Technology Specialist (MCTS): Web Applications Development with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Accessing Data with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Windows Communication Foundation Development with Microsoft .NET Framework 4

If you like my articles, please visit my website for more: www.rahulrajatsingh.com[^]

  • Microsoft MVP 2015

Comments and Discussions

 
QuestionCreate Proxy of web service Proxy Pin
Member 1230011013-Mar-18 23:45
Member 1230011013-Mar-18 23:45 
QuestionGood explanation Pin
Member 1289552522-Dec-16 9:46
Member 1289552522-Dec-16 9:46 
PraiseVery nice explanation Pin
pacomendez1221-Oct-16 7:41
pacomendez1221-Oct-16 7:41 
Bugzip files are broken Pin
Member 114845822-Sep-16 2:55
Member 114845822-Sep-16 2:55 
QuestionCan i use this if i need support of dynamic ip in my app? Pin
Member 1260481526-Jun-16 13:03
Member 1260481526-Jun-16 13:03 
QuestionMissing Concrete Actual Price class in the proxy Pin
Member 1253478019-May-16 19:31
Member 1253478019-May-16 19:31 
PraiseRe: Missing Concrete Actual Price class in the proxy Pin
Lorenzo Brito Morales22-Sep-17 20:05
Lorenzo Brito Morales22-Sep-17 20:05 
QuestionPrices type Pin
Deny Dimitrova14-Oct-15 5:48
Deny Dimitrova14-Oct-15 5:48 
GeneralMy vote of 5 Pin
D V L18-Sep-15 21:51
professionalD V L18-Sep-15 21:51 
GeneralMy vote of 4 Pin
cjb11012-Nov-12 1:41
cjb11012-Nov-12 1:41 
GeneralRe: My vote of 4 Pin
Klaus Luedenscheidt12-Nov-12 19:07
Klaus Luedenscheidt12-Nov-12 19:07 
GeneralRe: My vote of 4 Pin
cjb11012-Nov-12 21:08
cjb11012-Nov-12 21:08 
AnswerRe: My vote of 4 Pin
Rahul Rajat Singh14-Nov-12 17:10
professionalRahul Rajat Singh14-Nov-12 17:10 
AnswerRe: My vote of 4 Pin
Rahul Rajat Singh14-Nov-12 17:09
professionalRahul Rajat Singh14-Nov-12 17:09 
The best way to do that would be to have separate assembly and put the common code inside that. This assembly can then be used by server and all the clients that implement the proxies.
Every now and then say, "What the Elephant." "What the Elephant" gives you freedom. Freedom brings opportunity. Opportunity makes your future.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.