Strategy

December 14, 2010 Design Patterns 2 comments

“That’s simple as door” I wrote in Ukrainian, but I’m quite sure that in English another word combination is used to refer to express simple things. When it is raining outside you wear coat and take umbrella, and when it is sweltering you take T-shirt and sunglasses. But instead of taking a look outside to identify the weather and walk to wardrobe and take clothes and then, keeping in mind weather condition walk to bracket and take sunglasses or umbrella, YOU wake up and your wife (or husband, what is less likely) gives everything you need. In other words your wearing strategy for today has been given to you with one shot.

STRATEGY

Strategy – is design pattern that means having family of algorithms that can be used/changed by your code depending on situation.
Lets imagine that in class Myself we have some method GoOutside()  where we chose clothes and accessories and then walking outside.
Method could possibly look like below:
        public void GoOutside()
        {
            var weather = Weather.GetWeather();
            string clothes = GetClothes(weather);
            string accessories = GetAccessories(weather);
            Console.WriteLine("Today I wore {0} and took {1}", clothes, accessories);
        }

        private string GetAccessories(string weather)
        {
            string accessories;
            switch (weather)
            {
                case "sun":
                    accessories = "sunglasses";
                    break;
                case "rain":
                    accessories = "umbrella";
                    break;
                default:
                    accessories = "nothing";
                    break;
            }
            return accessories;
        }

        private string GetClothes(string weather)
        {
            string clothes;
            switch (weather)
            {
                case "sun":
                    clothes = "T-Shirt";
                    break;
                case "rain":
                    clothes = "Coat";
                    break;
                default:
                    clothes = "Shirt";
                    break;
            }
            return clothes;
        }
It doesn’t offend anyone, but once we will need to adapt to snow shower, we would need add one more case in 300 more places. From one point of view that is not difficult, but from another it “can get you” or maybe code with method GoOuside cannot be changed any longer. What’s then?
Hereabove I showed example with switch statement, since Strategy is the most elegant way to get rid of this monster.
    internal class Myself
    {
        private IWearingStrategy _wearingStrategy = new DefaultWearingStrategy();

        public void ChangeStrategy(IWearingStrategy wearingStrategy)
        {
            _wearingStrategy = wearingStrategy;
        }

        public void GoOutside()
        {
            var clothes = _wearingStrategy.GetClothes();
            var accessories = _wearingStrategy.GetAccessories();

            Console.WriteLine("Today I wore {0} and took {1}", clothes, accessories);
        }
    }
As we can see interface has two methods. They are shown below as well as SunshineWearingStrategy implementation:
    public interface IWearingStrategy
    {
        string GetClothes();
        string GetAccessories();
    }

    class SunshineWearingStrategy : IWearingStrategy
    {
        public string GetClothes()
        {
            return "T-Shirt";
        }

        public string GetAccessories()
        {
            return "sunglasses";
        }
    }

All left is to correctly chose strategy and set it for Myself instance. Hm! Anyway someone have to take a look on weather and put right strategy (wife, who woke up in the morning). But we can do this in one different place.

            var me = new Myself();
            me.ChangeStrategy(new RainWearingStrategy());
            me.GoOutside();

Output: “Today I wore Coat and took umbrella”

Yet another example would be changing sorting algorithm depending on list length. We all know that qsort is not best solution for small collections or superlarge, in one case we would use merge or other sorting and in another case we would use heapsort. Having sorting logic separately and changing it depending on the size of collection is good example of Stategy design pattern.

My design patterns table


2 comments


Microsoft SWIT 2010

December 12, 2010 Microsoft, Opinion 2 comments

image

This is going to be blog post about my trip to Microsoft conference in Kyiv. More than week passed since that time, but I still clearly remember that cool event. Just want to share my thoughts and impressions on the trip. Maybe some of you, Dear Readers, would love to hear more about the event. Please ask.

At the moment I’m in very comfortable train to Kyiv. I’ve never been in this kind of train. Finally they have established public transport at some good level. Train has personal lights, general lighting system, different indicators (e.g. indication if toilet isn’t occupied), well-working energy set, so I can plug in my laptop system. And the best – it is relatively quick train.” – I wrote at first night going to conference. Don’t know why would I be so impressed by train, wondering as monkey from zoo, but “hey there gonna be great day tomorrow”, thought I at that night. We were in Kyiv at 7:30 AM and freezing cold met us. It was about ‘–10’ by Celsius (14 by Fahrenheit). Not the best weather for conference and I got sick after those days and then two days in mountains at weekend.

Clouds – our future?

Conference started with kick-off speech from director of Microsoft Ukraine. This guy was extremely nice and knew how to keep audience attention. Main idea of his speech was CLOUD.

image Picture is taken from here: http://keddr.com/2010/12/microsoft-swit-2010-v-fotografiyah/ where you can see many other cool pictures including windows phone and Kinect (controller-girls only :) )

Small and cool gray could. Or even “home” could that can be kept in van where you plug electricity, network and cooling system – that is all you need, plus one cabin for controlling. Of course Microsoft itself has bigger toys, something like on picture below:

microsoft-chicago-containers[1] 

1) Windows Phone 7

The guy who talked about WinPhone 7 is Silverlight MVP Sergii Lutai. I liked the way he talked about the phone, and I would say that I already seen those slides presented here in my company by someone else. But slides doesn’t make difference, unless there is everything written and I read everything, but the presenter makes difference. Sergii knew the material and it was really pleasant to hear him. I listened to basics of WP7 once again – but this time I took a lot for myself.

Ukrainian MVP List

First of all I was surprised that even in Ukraine we have some MVPs (I thought there are only few). Actually I did research and it turns out that there are only/about 15 MVPs in Ukraine, follow this link to see whole list.

2) What’s new in ASP.NET 3.0

Definitely the most energized presentation – Dima as always was in good mood, not taking into account that he had lost his passport before. I really like the way he keeps contact with audience, but I often expect more constructive and detailed talks from him. He hates me for this :) … kidding… just kidding…

3) Entity Framework

CSDL (conceptual schema definition language) SSDL (store schema definition language) MSL (mapping specification language)” – wrote I when was there. It doesn’t make a lot of sense being detached from whole story, but I want to keep it as it was before… Hope many guys know what those things are. Sergiy is really cool and solid presenter, yeah.. he is not that young and fun guy as Dima, but it doesn’t impact his possibility to keep audience interested.

4) Developing web apps with ASP.NET AJAX and JQuery

I did not find this presentation to be as good as others. And topic is too jaded. But anyway it was good to listen to that. I know only this – “I love JQuery” :)

Hotel

Title “Hotel” doesn’t mean presentation, but it is about our hosting in hotel. It was the best hotel I ever been. Ok, that is only second time I was in hotel. imageI do not travel, my family did not have money for that and me either did not have money for trips or something. So maybe supercline, tidy bed, tv, refrigerator, awesome shower and rest room doesn’t make any kind of impression on people. Main thing that was there – wifi. He-he, I showed room to my girlfriend via Skype.

You know what happened after that? – We got drunk. I did not know that people can so phenomenally talk about immortal philosophical, slightly math-physical things after couple of glasses full of Whisky. Was extremely interesting and cognitive.

In the morning I felt myself crappy, but anyway went to the conference. It turned out that Kyiv is also traffic jam city.

5) Modeling UML in VS 2010

was interesting.. pity that it is only in Ultimate” – I thought at that time and still think so. It is really bad that lot of fascinating things live inside of Ultimate version of VS and it is that expensive. Building Sequence diagrams with one shot, keeping class diagrams all the time up to date, and elegant component diagrams – that is amazing.

6) F#

WoW!!! @ddtru you rock! That was really fascinating, hardcore, bit academic exciting presentation about functional programming language running on CLR. I’m not sure about this, but it sounds like he is or was teacher in some university. I would love to be one of his students. Actually if you understand Ukrainian you can go to this page and read about each of the presenters, him including.

7) Parallel programming/ Task Library

Young, bright (in both meanings) guy talked about how we came from “Thread.” to “Task.” and then he mentioned about async and await. Presentation was real threading hardcore – I love threading hardcore. Actually I had my Master Diploma related to multithreading, so I knew almost everything he talked about, but there were lot of things that were out of my attention, and now I refreshed that all in my mind. Also what I liked about this presentation is that it was in Ukrainian. It is really sad, that I live in Ukraine and most of the presentations were in Russian. I have nothing against this language, but I have a lot against ruining Ukrainian nation establishment as separate country. Honestly I see myself in this man, I would prepare similar presentation with same kind of hardcore, only maybe I feel more comfortable in front of big audience. This is something he lacked.

8-9) Testing with Visual Studio 2010

Again, Ultimate version of VS allows us create UI test scenarios, that can run automatically. We can also create multi-machine environment that can be reestablished at some moment of time, then our system deployed to it and completely tested. That is awesome.

Maybe I missed some of the presentations where I’ve been, but I put list of those where I’ve been and what I’ve remembered.

Photos

I found some photos from event, you can proceed to them by clicking on the image below. There is also small bug on the picture, try to find it (talking about myself).

And more photos here: http://msswit.cloudapp.net/Photo.aspx


2 comments


Chain Of Responsibility

December 7, 2010 Design Patterns 2 comments

Imagine that you went to cafe with your friends. Cafe is somewhat weird, there is not enough room, and you have to pass food to other person if it is not for you. Your best friend took place the most closed to end of the table, so he is first who gets order. Cause he slept not enough in the night he dies for at least one cap of something with coffee and a lot of meat, since he did not eat during the day. Next to your friend is you and then your girlfriend near the wall. You want soup and she wants cappuccino. She have none to pass food to.

Chain Of Responsibility

I hope that whole mechanics of the design pattern Chain Of Responsibility is understandable. We have some set or chin of handlers (visitors of cafe), that can handle command (food in our example). If handler cannot process command it passes it to its successor if it exists.

Handler

In our example general interface for handler could be following abstract base class:

    public abstract class WierdCafeVisitor
{
public WierdCafeVisitor CafeVisitor { get; private set; }

protected WierdCafeVisitor(WierdCafeVisitor cafeVisitor)
{
CafeVisitor = cafeVisitor;
}

public virtual void HandleFood(Food food)
{
// If I cannot handle other food, passing it to my successor
if (CafeVisitor != null)
{
CafeVisitor.HandleFood(food);
}
}
}

As we can see by default food is passed to next cafe visitor in chain, if it exists.

Lets now take a look on realization that is more suitable for your persnickety friend:

    public class BestFriend : WierdCafeVisitor
{
public List<Food> CoffeeContainingFood { get; private set; }
public BestFriend(WierdCafeVisitor cafeVisitor) : base(cafeVisitor)
{
CoffeeContainingFood = new List<Food>();
}

public override void HandleFood(Food food)
{
if(food.Ingradients.Contains("Meat"))
{
Console.WriteLine("BestFriend: I just ate {0}. It was testy.", food.Name);
return;
}
if (food.Ingradients.Contains("Coffee") && CoffeeContainingFood.Count < 1)
{
CoffeeContainingFood.Add(food);
Console.WriteLine("BestFriend: I have to take something with coffee. {0} looks fine.", food.Name);
return;
}
base.HandleFood(food);
}
}

Implementations of two other handlers – Me and GirlFriend probably are understandable, but anyway will show realization of GirlFriend visitor:

    public class GirlFriend : WierdCafeVisitor
{
public GirlFriend(WierdCafeVisitor cafeVisitor) : base(cafeVisitor)
{
}

public override void HandleFood(Food food)
{
if(food.Name == "Cappuccino")
{
Console.WriteLine("GirlFriend: My lovely cappuccino!!!");
return;
}
base.HandleFood(food);
}
}

That’s simple: girl wants cappuccino, but since she is last in chain she will not get it before friend will not have his cap of something with coffee.

Usage

Now lets take a look on usage. We create two cappuccinos, two soups and one meat. Then we pass those one by one into BestFriend hands: 

            var cappuccino1 = new Food("Cappuccino", new List<string> {"Coffee", "Milk", "Sugar"});
var cappuccino2 = new Food("Cappuccino", new List<string> {"Coffee", "Milk"});

var soup1 = new Food("Soup with meat", new List<string> {"Meat", "Water", "Potato"});
var soup2 = new Food("Soup with potato", new List<string> {"Water", "Potato"});
var meat = new Food("Meat", new List<string> {"Meat"});

var girlFriend = new GirlFriend(null);
var me = new Me(girlFriend);
var bestFriend = new BestFriend(me);

bestFriend.HandleFood(cappuccino1);
bestFriend.HandleFood(cappuccino2);
bestFriend.HandleFood(soup1);
bestFriend.HandleFood(soup2);
bestFriend.HandleFood(meat);

Output:

BestFriend: I have to take something with coffee. Cappuccino looks fine.
GirlFriend: My lovely cappuccino!!!
BestFriend: I just ate Soup with meat. It was testy.
Me: I like Soup. It went well.
BestFriend: I just ate Meat. It was testy.

As we can see from output girl got only second cappuccino and you have been forced to eat soup without meat :)

What is also interesting is that we can add another one handler after girlfriend, say bag for dog, and everything that none likes will go there.

My design patterns table


2 comments


Observer

November 30, 2010 Design Patterns No comments

Many people like watching box fights. But besides of this, someone have to pay for all of this, and most of the money come from people who put some money on boxers and then lose it. Or… maybe I’m wrong, but for this example, let it be so. Imagine that we have box fight tonight and there are two persons interested in game, so they OBSERVE fight and UPDATE their rates. One of them likes risks, so he always put money on boxer who has less chance to win, and other is very conservative and likes small bird in hand instead of big in the sky.

OBSERVER

Observer is design pattern, that allows automatically update many observers if there was change in state of some subject object.

So, each gambler (Player, Observer) likes to adjust his rates, that is why he has Update() method.

    public interface IObserver
{
void Update(ISubject subject);
}

public class RiskyPlayer : IObserver
{
public string BoxerToPutMoneyOn { get; set; }

public void Update(ISubject subject)
{
var boxFight = (BoxFight)subject;

BoxerToPutMoneyOn = (boxFight.BoxerAScore > boxFight.BoxerBScore) ? "I put on boxer B, if he win I get more!" : "I put on boxer A, if he win I get more!";


Console.WriteLine("RISKYPLAYER:{0}", BoxerToPutMoneyOn);
}
}

public class ConservativePlayer : IObserver
{
public string BoxerToPutMoneyOn { get; set; }

public void Update(ISubject subject)
{
var boxFight = (BoxFight)subject;

BoxerToPutMoneyOn = (boxFight.BoxerAScore < boxFight.BoxerBScore) ? "I put on boxer B, better be safe!" : "I put on boxer A, better be safe!";

Console.WriteLine("CONSERVATIVEPLAYER:{0}", BoxerToPutMoneyOn);
}
}

Here below we have subject which is observed by players:

    public interface ISubject
{
void AttachObserver(IObserver observer);
void DetachObserver(IObserver observer);
void Notify();
}

public class BoxFight : ISubject
{
public List<IObserver> Observers { get; private set; }
public int RoundNumber { get; private set; }

private Random Random = new Random();

public int BoxerAScore { get; set; }
public int BoxerBScore { get; set; }

public BoxFight()
{
Observers = new List<IObserver>();
}

public void AttachObserver(IObserver observer)
{
Observers.Add(observer);
}

public void DetachObserver(IObserver observer)
{
Observers.Remove(observer);
}

public void NextRound()
{
RoundNumber++;

BoxerAScore += Random.Next(0, 5);
BoxerBScore += Random.Next(0, 5);

Notify();
}

public void Notify()
{
foreach (var observer in Observers)
{
observer.Update(this);
}
}
}

Usage, or how we build one-to-many relationship by attaching observer-s:

            var boxFight = new BoxFight();

var riskyPlayer = new RiskyPlayer();
var conservativePlayer = new ConservativePlayer();

boxFight.AttachObserver(riskyPlayer);
boxFight.AttachObserver(conservativePlayer);


boxFight.NextRound();
boxFight.NextRound();
boxFight.NextRound();
boxFight.NextRound();

Output:

RISKYPLAYER:I put on boxer A, if he win I get more!
CONSERVATIVEPLAYER:I put on boxer B, better be safe!

RISKYPLAYER:I put on boxer B, if he win I get more!
CONSERVATIVEPLAYER:I put on boxer A, better be safe!

RISKYPLAYER:I put on boxer B, if he win I get more!
CONSERVATIVEPLAYER:I put on boxer A, better be safe!

RISKYPLAYER:I put on boxer B, if he win I get more!
CONSERVATIVEPLAYER:I put on boxer A, better be safe!

 

Been very short explanation. Just take closer look on interfaces in examples, this should be enough to understand everything.

My design patterns table


No comments


Exam 73-503: TS: Windows Communication Foundation – PASSED

November 27, 2010 Certification, Success, WCF 3 comments

I recent posts I mentioned that I read training kit for ms WCF exam. Of course I did this for some reason. I had this exam scheduled for yesterday as well as presentation on WCF for Thursday, which went extremely well. All that was scheduled because I decided to throw myself out of comfort zone. I now can ensure you that this approach indeed works. So, if you want to achieve something don’t hesitate – just go ahead and put some deadlines for yourself, and make them visible to others so this will be controlling your activity.

How did I prepare?

So I’m completely sure that positive result of this exam was guaranteed by my experience working with WCF. But anyway I read training kit, which brought many interesting aspects and some kind of hints for the exam. Third learning source (after experience and training kit) was MSDN and writing simple applications by my own. I do not like to use examples from training kit, also I found few mistakes in kit. Thursday’s presentation on WCF helped me as well, I strengthen my knowledge in transactions and instancing. Just before exam I tried MeasureUp demo test and got 6 out 6 – never got this at MeasureUp for other exams.

Passing Exam

Exam has 45 questions for 120 min. And I liked answering for them, since I faced dozen of questions related to what I do in my everyday work.

I PASSED EXAM with score 918, this means that I answered correctly on 41 questions. Woo hoo!

You can see my transcript using this information:
https://mcp.microsoft.com/authenticate/validatemcp.aspx
Transcript ID: 904316
Access Code: andriybuday


3 comments


.NET ROCKS said “Hello” to Andriy Buday

November 25, 2010 Personal No comments

As many of you know I listen to many of podcasts. Just use this link. One of my favorite of course is .NET ROCKS.

image

I new that they wanted to be at Sinergija10 so I asked my friend Dmitriy Maleev to take some cool pictures of them. But he did much more – he got this:
Richard Campbell from .NET Rocks greeting me:

NETROCKS_HelloToAndriyBuday_RichardCampbell

I probably have to tweet this hundred times :)
Thank you very much, Dima for this!


No comments


DevMeeting: WCF–Advanced-1

November 25, 2010 DevMeeting, Presentation, PublicTalks, WCF 2 comments

 

Today I performed meeting on WCF. It was continuation of this thread of meetings.

Couple of interesting facts about this presentation:

1) I started preparing at 3AM and continued doing this till actual presentation at 1 PM. (Yeah I of course responded to some of e-mails at work and did some other stuff, but anyway most time spent on preparation)

2) Also I want to my English teacher to forgive my absence on today’s English Lesson. Additional 1,5 hour really helped me. Guys, could you please ensure her that presentation cost all the money?

3) I took to much stuff to talk during 1 hour. Initially I prepared following list:

  • Basics overview
  • Sessions and Instances
  • Transactional Services
  • Concurrency
  • Security
  • Instrumentation
  • Most often troubles you might face using WCF

So I crossed some items, but it turned about that we had time only for two first items in bold.

Regardless of that many people, I’m sure, liked it very much.

4) I did a lot of coding during presentation, I hope guys liked this. Right?

5) I was forgetting about zooming and colors on projector. My bad.

6) There was not enough sit places for guys, many of them simply stand near the wall. Sorry for that. I hope managers will resolve this issue soon. He-he.

7) I kept them all interested in further presentation, since Security was not mentioned at all :-P

8) Main Links from this presentation:

9) You can go and download my presentation (I removed transactions to have something to show next time) using this link.

10) So mainly I talked on Sessions and Instances.

11) But, then I also talked on items listed below:

  • Throttling
  • Quotas
    • MaxReceivedMessageSize
    • ReaderQuotas
  • Demarcating
  • Instance Deactivation

12) Thank you!

Guys, I will appreciate your comments/suggestions/thoughts here!


2 comments


WCF: Sessions and Instances

November 25, 2010 WCF No comments

Sessions and Instances

Per Call*

On each request to service (each time we use service method) new instance of Service implementation will be generated. Often this is not suitable for us when we want some to keep track of actions (transactions) or when we access some critical resources.

image_thumb[11]

Per Session*

Is default Session mode. (BTW book on preparation to 70-503 has mistake mentioning that PerCall is default). In this case client knows that Service provides sessions. We can also highlight requirement of using sessions by marking contract with SessionMode.Required. Session is kept with identifier assigned to you proxy class, that you use at client. 

We also have possibility to share same instance of service by passing additional identifier in message header that goes from Client. For that we would need to implement IInstanceContextProvider.

image_thumb[12]

Singleton

Is more rarely used Session mode, but it might be useful when we access one super-critical resource. Plus to that that one plus in using this session mode – possibility to create instance of service even before service host has been created.

image_thumb[13]

* Pictures, but not text below, were taken from training kit book for ms exam 70-503: Link


No comments


Composite

November 23, 2010 Design Patterns No comments

Did you ever think why so many things around us have tree-similar structure? Top management of your company can delegate some work to middle management, and it can delegate it to your direct manager, who will ask you  and your colleagues do something. In one of your tasks you had to gather data for some customer into xml. XML has also tree-similar structure. Why? Because it is the best way to serialize data, that can have data, that can… You got that! Now imagine that you want to gather data for some document part by part.

 

COMPOSITE

Composite is design pattern that provides us tree-similar structural representing of classes, this allows us work uniformly with parents and Childs.
So interface that defines common requirements for parents and kids:

    public interface IDocumentComponent
    {
        string GatherData();
        void AddComponent(IDocumentComponent documentComponent);
    }

And here we see some leaf component implementation. It is Customer Component, which gathers some data about customer basing on id provided to the class.

    public class CustomerDocumentComponent : IDocumentComponent
    {
        private int CustomerIdToGatherData { get; set; }

        public CustomerDocumentComponent(int customerIdToGatherData)
        {
            CustomerIdToGatherData = customerIdToGatherData;
        }

        public string GatherData()
        {
            string customerData;
            switch (CustomerIdToGatherData)
            {
                case 41:
                    customerData = "Andriy Buday";
                    break;
                default:
                    customerData = "Someone else";
                    break;
            }

            return string.Format("<Customer>{0}</Customer>", customerData);
        }

        public void AddComponent(IDocumentComponent documentComponent)
        {
            Console.WriteLine("Cannot add to leaf...");
        }
    }

And not-leaf implementation of the component below. Please take into account that it simply loops through Childs and executes GatherData method.

    public class DocumentComponent : IDocumentComponent
    {
        public string Name { get; private set; }
        public List<IDocumentComponent> DocumentComponents { get; private set; }

        public DocumentComponent(string name)
        {
            Name = name;
            DocumentComponents = new List<IDocumentComponent>();
        }

        public string GatherData()
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.AppendLine(string.Format("<{0}>", Name));
            foreach (var documentComponent in DocumentComponents)
            {
                documentComponent.GatherData();
                stringBuilder.AppendLine(documentComponent.GatherData());
            }
            stringBuilder.AppendLine(string.Format("</{0}>", Name));

            return stringBuilder.ToString();
        }

        public void AddComponent(IDocumentComponent documentComponent)
        {
            DocumentComponents.Add(documentComponent);
        }
    }

Gluing parts to be some kind of document:

            var document = new DocumentComponent("ComposableDocument");
            var headerDocumentSection = new HeaderDocumentComponent();
            var body = new DocumentComponent("Body");
            document.AddComponent(headerDocumentSection);
            document.AddComponent(body);

            var customerDocumentSection = new CustomerDocumentComponent(41);
            var orders = new DocumentComponent("Orders");
            var order0 = new OrderDocumentComponent(0);
            var order1 = new OrderDocumentComponent(1);
            orders.AddComponent(order0);
            orders.AddComponent(order1);

            body.AddComponent(customerDocumentSection);
            body.AddComponent(orders);

            string gatheredData = document.GatherData();

            Console.WriteLine(gatheredData);

Output is somewhat similar to XML. At least I tried to keep it similar.

<ComposableDocument>

<Header><MessageTime>8:47:23</MessageTime></Header>

<Body>

  <Customer>Andriy Buday</Customer>

  <Orders>

   <Order>Kindle;Book1;Book2</Order>

   <Order>Phone;Cable;Headset</Order>

  </Orders>

</Body>

</ComposableDocument>

Also GoF guys suggest having Remove(Component) and GetChild(int) methods in your Component, so you might want to add them. Just don’t limit yourself with any kind of explanations. You might have some unique need.

My design patterns table


No comments


WCF: Instrumentation: Parameter Inspector

November 22, 2010 WCF 4 comments

Let’s take a look how we use one of the instruments of the WCF, called Parameter Inspector.
Here below we see how message request goes between Client and Service.
image
Let’s now imagine that we have some kind of calculator on service side, that has method string Execute(int a, int b, string operation). Client should be very careful in passing parameters to the service, because service is developed by some other team, and after you pass incorrect parameters it fails.
It turns out that with WCF services we are not required to implement such logic before calling method. It can be applied to your request when passing to service. Either just before passing it to channel stack at client or at dispatcher after it came from network on server.
On the picture below we see more closely what is at proxy layer, and 3 points where you can inject your logic.
image So moving forward I’m going to implement Parameter Inspection for my calculator example.
Here is implementation of my calc service. Please take a look that for this naive example, I’m killing process when operation is not available. Of course in standard situation with WCF we would probably throw fault exception and catch it on client side. But for now, lets assume that there is some super logic on service and we cannot change calculator code – it stops working is we pass wrong operation string.
    public class CalculatorService : ICalculatorService
    {
        public int Execute(int a, int b, string operation)
        {
            Console.WriteLine("Received request: ({0}{2}{1}=?)", a, b, operation);

            int result = -1;
            switch (operation)
            {
                case "+":
                    result = a + b;
                    break;
                case "-":
                    result = a - b;
                    break;
                case "*":
                    result = a * b;
                    break;
                case "/":
                    result = a / b;
                    break;
                default:
                    Console.WriteLine("Our calc executed hara-kiri.");
                    Process.GetCurrentProcess().Kill();
                    break;
            }
            return result;
        }
    }
Client is the most standard, that you can imagine, it asks calculator for answer by passing parameters entered in console in while loop.
                        var res = calculatorServiceClient.Execute(a, b, op);
                        Console.WriteLine(res);
Now let see how calc crashes on ‘@’ operation:
image We want to execute parameters verification before calling method on server, and if parameters do not satisfy us, we abort calling calculator. For this I simply surround call to the service in my client in following way:
                    try
                    {
                        var res = calculatorServiceClient.Execute(a, b, op);
                        Console.WriteLine(res);
                    }
                    catch (ArgumentException exception)
                    {
                        Console.WriteLine(exception.Message);
                    }
So how do we get ArgumentException on client? We add custom behavior to the client endpoint.
            using (var calculatorServiceClient = new CalculatorServiceClient("WS2007HttpBinding_ICalculatorService"))
            {
                calculatorServiceClient.Endpoint.Behaviors.Add(new CustomEndpointBehavior());

                calculatorServiceClient.Open();
                
                // ... 
So custom behavior allows us add operation, message and parameter inspectors. In my example I will only add parameter inspector. See below:
    public class CustomEndpointBehavior : IEndpointBehavior
    {
        public void Validate(ServiceEndpoint endpoint)
        {
            return;
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            return;
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            return;
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            foreach (var clientOperation in clientRuntime.Operations)
            {
                clientOperation.ParameterInspectors.Add(new OpParameterInspector());
            }
        }
    }

    public class OpParameterInspector : IParameterInspector
    {
        public object BeforeCall(string operationName, object[] inputs)
        {
            switch (operationName)
            {
                case "Execute":
                    VerifyExecuteParams(inputs);
                    break;
            }

            return null;
        }

        private void VerifyExecuteParams(object[] inputs)
        {
            if (new string[]{"+", "-", "*", "/"}.Where(x => x == (string) inputs[2]).Count() == 0)
            {
                throw new ArgumentException("Your operation should belong to folowing list: '+', '-', '*', '/'. Please verify and try again.");
            }
        }

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            return;
        }
    }
And as result of our work we got parameters validation, not completely in client code and not on server, but somewhere in the middle (yeah, it is still client, but validation is postponed to next step in WCF pipeline – Proxy).
image
While learning WCF I wonder how many different extensions and flexibility it allows. Not sure if it all is needed, but if you have doubts if WCF can or cannot do something, be sure – it can.


4 comments