Bookmark Mashup 7.30.10

30. July 2010

As everyone else does, I run into several interesting articles, and tools throughout the week. I figured that every so often I would share the best of them. Without further ado…


short link to this post:

Bookmark Mashup , , , , ,

Custom (dynamic) configuration sections in .net

9. July 2010

Creating a custom configuration section can be done in 3 easy steps. However, accessing section with a ConfigurationElementCollection can be tedious. Let me explain.

Let’s pretend you have a section that looks like this:

<namedUrlSection favoriteUrl="CodeHarder">
  <namedUrls>
    <add name="Twitter" url="http://twitter.com"/>
    <add name="CodeHarder" url="http://codeharder.com"/>
    <add name="Stackoverflow" url="http://www.stackoverflow.com"/>
  </namedUrls>
</namedUrlSection>

And the accompanying code to read it:

public class UrlConfigSection : ConfigurationSection
{
    public static UrlConfigSection ConfigSection = ConfigurationManager.GetSection("namedUrlSection") as UrlConfigSection;

    [ConfigurationProperty("favoriteUrl")]
    public string Favorite
    {
        get
        {
            return this["favoriteUrl"].ToString();
        }
    }

    [ConfigurationProperty("namedUrls")]
    public NamedUrlCollection Urls
    {
        get
        {
            return this["namedUrls"] as NamedUrlCollection;
        }
    }
}

 

If you wanted to get the name of your favorite URL, it is very simple syntax.

string favUrlName = UrlConfigSection.ConfigSection.Favorite;

 

But, when you want to access one of the child namedUrl elements, it just doesn’t look very nice. Not ugly, just verbose. Wouldn’t you agree?

UrlConfigSection.ConfigSection.Urls["CodeHarder"].Url

 

I always wished I could just flatten it out to something like .CodeHarder. I don’t know why I didn’t think of this before, but with the new DynamicObject in .net4 I can! Creating a wrapper to give me that syntax is ~10 lines of code.

public class DynamicUrlConfig:DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = null;
        NamedUrl url = UrlConfigSection.ConfigSection.Urls[binder.Name];
                    
        if (url != null)
        {
            result = url.Url;
            return true;
        }
        return false;
    }
}

 

Now, when I want to get anything from the namedUrls section, I can use the syntax I always wanted.

dynamic urlSection = new DynamicUrlConfig();
string favUrl = urlSection.CodeHarder;

 

I know this isn’t new, and a quick google would probably give me several people who have done it before, but I was quite pleased and thought I would share.


short link to this post:

.net, Fun with .net , , ,

Modifying a WCF operation at runtime – part 3

6. July 2010

part 1: The client setup
part 2: The code setup

While at work the other day I was talking to my boss, and the subject of spoofing data came up. He mentioned that for our current project, it would be nice to be able to spoof data on a per-request basis. I thought it would be a fun challenge to tackle, so I spent a few hours last Saturday and came up with a pretty elegant solution.

Before I started, I had a few requirements:

  • It had to be completely config driven. The client and target WCF service were to have no idea what was going on.
  • It was to be on a per-user/per-request basis. What this means is any dev could turn it on/off and it would only affect him.
  • Extensible. If you didn’t like the data I mocked, or needed to be able to simulate slow network traffic, exceptions, large data, etc - you could.
  • I only had 5 hours to come up with a solution.

 

In part 2 I described how I structured our code so I could provide any ITypeFactory we wanted. With that out of the way, I was able to get back to some more of the fun stuff. Armed with  IOperationBehavior, IEndpointBehavior, BehaviorExtensionElement, IOperationInvoker, and ConfigurationSection I set out to finish this thing off.

One of my main goals was to make the entire thing config driven. I knew that when I saw the mockdata header I would want to grab what ITypeFactory to use from the config. I figured I would start there.

public class ServiceMockerConfigSection:ConfigurationSection
{
    public static ServiceMockerConfigSection ConfigSection = ConfigurationManager.GetSection("ServiceMockerConfigSection") as ServiceMockerConfigSection;
    static ServiceMockerConfigSection() { }

    [ConfigurationProperty("mockType",IsRequired=true)]
    public string MockFactoryType
    {
        get
        {
            return this["mockType"].ToString();
        }
    }
}

and the config:

<configSections>
  <section name="ServiceMockerConfigSection" type="VT.Lenio.ServiceMocker.ServiceMockerConfigSection, VT.Lenio.ServiceMocker"/>
</configSections>

<ServiceMockerConfigSection mockType="ServicesMocks.SimpleMockFactory,ServicesMocks"/>

 

Next up was the custom IOperationInvoker. This is the part that looks for the mockdata header. When found it creates a type specified in the config (in the case above, a SimpleMockFactory), and injects it into the given service.

public class MockServiceOperationInvoker : IOperationInvoker
{
    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        try
        {
            var headers = OperationContext.Current.IncomingMessageHeaders;
            
            if (headers.Any(h => h.Name == "mockdata"))
            {
                if (instance is ServiceBase)
                {
                    string mockTypeString = ServiceMockerConfigSection.ConfigSection.MockFactoryType;
                    Type mockType = Type.GetType(mockTypeString);
                    ITypeFactory mockFactory = Activator.CreateInstance(mockType) as ITypeFactory;
                    if (mockFactory != null)
                        ((ServiceBase)instance).TypeFactory = mockFactory;
                }
            }
        }
        catch
        {
            //swallow so we don't break anything
        }

        return Invoker.Invoke(instance, inputs, out outputs);
    }
}

 

The biggest problem I had with this entire process was getting this invoker attached to an operation. To make that happen you have to create an IOperationBehavior. When the behavior executes, you can add your invoker into the pipeline.

Every example I found showed it being done via a custom attribute. Unfortunately, that broke my #1 rule. How could I easily add/remove the behavior if it was coded into the service? Even after searching MSDN I had to come to the conclusion that the only way suggested would be to use that attribute. I wasn’t going to let that stop me!

Having already implemented a IEndpointBehavior, I had a hunch I could use it here as well. If so, it would allow me to add my IOperationBehavior to every operation in a given endpoint, and have it driven from the configuration.

public class MockOperationBehavior : BehaviorExtensionElement,  IOperationBehavior, IEndpointBehavior
{
    #region IOperationBehavior
    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        dispatchOperation.Invoker = new MockServiceOperationInvoker() { Invoker = dispatchOperation.Invoker };
    }
    #endregion

    #region IEndpointBehavior
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        foreach (var op in endpoint.Contract.Operations)
        {
            op.Behaviors.Add(this);
        }
    }
    #endregion

    public override Type BehaviorType
    {
        get {return typeof(MockOperationBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new MockOperationBehavior();
    }
}

 

Basically, when the IEndpointBehavior was executed it would loop through each operation in its contract and add itself as a behavior. (This works because MockOperationBehavior implements both IEndpointBehavior, and IOperationBehavior.) When the IOperationBehavior runs it sets the dispatchInvoker the the MockerOperationInvoker I created above.

The last step was add the configuration to the service host, and it was complete! To tie it together nicely, I added two bookmarklets to my browser. One wrote the cookie, and one removed it. With the click of a button I am able to switch from live data to spoofed data, and neither the client or the service knows it is happening.

What really excites me about this is not that I can spoof data anytime I want, but that WCF is really easy to extend. Go play around with it, I doubt you will regret it!

I tried to make this as clear as I could, but I could be taking some things for granted. If I confused you at all feel free to leave a comment, or contact me. I will try to make it more clear for you.


short link to this post:

asp.net, Fun with .net, wcf ,

Modifying a WCF operation at runtime – part 2

5. July 2010

Part 1: The client setup

While at work the other day I was talking to my boss, and the subject of spoofing data came up. He mentioned that for our current project, it would be nice to be able to spoof data on a per-request basis. I thought it would be a fun challenge to tackle, so I spent a few hours last Saturday and came up with a pretty elegant solution.

Before I started, I had a few requirements:

  • It had to be completely config driven. The client and target WCF service were to have no idea what was going on.
  • It was to be on a per-user/per-request basis. What this means is any dev could turn it on/off and it would only affect him.
  • Extensible. If you didn’t like the data I mocked, or needed to be able to simulate slow network traffic, exceptions, large data, etc - you could.
  • I only had 5 hours to come up with a solution.


 

In the previous post, I configured the client to write a header on any outgoing request if a specified cookie was found. I knew I could look for that header easily, but I had to find a way to change the behavior of a given operation.

I spent a while searching around for something that would let me do this, but I couldn’t find anything that would let me inject new type over an existing on a per-call basis. It may be that something like Ninject would have done this, but from what I understand (having never used it) it would replace all instances of a given type with a new one, not targeted instances. If I am wrong, please let me know.

Lucky for me, we had a nice little pattern going in our code. Each service was just a shell to call out into an appropriate controller, and the controller had all the meat and potatos. For example:

public class MyService : IMySerivce
{
    public void DoSomeWork()
    {
        MyServiceController controller = new MyServiceController();
        controller.DoSomething();
    }
}

 

I extended this by creating a custom ServiceBase class that any WCF service we wanted to be mockable would inherit from. It provided a single item.  (There was also a base that all of our controllers were to inherit from.)

public class AppBaseService
{
    protected ITypeFactory typeFactory=new DefaultTypeFactory();

    public virtual ITypeFactory TypeFactory
    {
        get { return this.typeFactory; }
        set { this.typeFactory= value; }
    }

}

public class ControllerBase
{
    protected ITypeFactory typeFactory;

    public ControllerBase(ITypeFactory typeFactory)
    {
        this.typeFactory= typeFactory;
    }
}

Now is a good time to note that the DefaultTypeFactory just newed up whatever type you provided it.

So, with these changes any service that was to be mockable would look something like this:

public class MyService : ServiceBase, IMySerivce
{
    public void DoSomeWork()
    {
        MyServiceController controller = new MyServiceController(this.TypeFactory);
        controller.DoSomething();
    }
}

//and the inners of the controller looked like:
public class MyServiceController : ControllerBase
{
    public MyServiceController(ITypeFactory typeFactory)
    {
        this.typeFactory = typeFactory;
    }
    
    public void DoSomething()
    {
        IDataAccessClass dataAccess = this.typeFactory.CreateType(typeof(MyConcreteDataClass)) as IDataAccessClass
        dataAccess.ExecuteSomething();
    }
}

 

This allowed me to set whatever ITypeFactory I want on a per call basis. Like I said above, the default one would just new up whatever type you gave it, but I could easily create one that would return a new type based on whatever you asked for. So in the example above, instead of returning a new MyConcreteDataClass, I could return a MyMockedDataClass (assuming that implement IDataAccessClass, of course!)

With the grunt work out of the way, part 3 will be the WCF extensions that tied all this together.


short link to this post:

wcf, asp.net, Fun with .net ,

Modifying a WCF operation at runtime – part 1

4. July 2010

I started to make this one big post, but it was a lot of information to try to pack into something readable. So I decided to split it up.

While at work the other day I was talking to my boss, and the subject of spoofing data came up. He mentioned that for our current project, it would be nice to be able to spoof data on a per-request basis. I thought it would be a fun challenge to tackle, so I spent a few hours last Saturday and came up with a pretty elegant solution.

Before I started, I had a few requirements:

  • It had to be completely config driven. The client and target WCF service were to have no idea what was going on.
  • It was to be on a per-user/per-request basis. What this means is any dev could turn it on/off and it would only affect him.
  • Extensible. If you didn’t like the data I mocked, or needed to be able to simulate slow network traffic, exceptions, large data, etc - you could.
  • I only had 5 hours to come up with a solution.

 

The concept I was striving for was being able to write a cookie or add a query string to your request, and be served up mock data instead of live data from dev. Previous to this, I hadn’t played with extending WCF very much, but it turns out everything was quite simple. I started by implementing an IClientMessageInspector. It had one job. Inspect every outgoing request, and add an additional header if the appropriate cookie/querystring was found.

public class MockClientMessageInspector : IClientMessageInspector
{
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        //check for the cookie/querystring 
        bool shouldMock = ...;

        if (shouldMock) 
        {
            request.Headers.Add(MessageHeader.CreateHeader("mockdata", "ns", true));
        }
        return null;
    }
}

 

To add this behavior to the client, I implemented an IEndpointBehavior, and a BehaviorExtensionElement to go with it.

public class MockClientEndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new MockClientMessageInspector());
    }

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

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    protected override object CreateBehavior()
    {
        return new MockClientEndpointBehavior();
    }

    public override Type BehaviorType
    {
        get
        {
            return typeof(MockClientEndpointBehavior);
        }
    }
}

 

Now all the client has to do is add the correct config entries, and he is all ready to go. Want to remove the capability? Remove the configuration. It is that simple.

<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="mockClientInspector" type="ServiceMocker.MockClientEndpointBehavior, ServiceMocker" />
    </behaviorExtensions>
  </extensions>

  <behaviors>
    <endpointBehaviors>
      <behavior name="MyBehaviorConfig">
        <mockClientInspector/>
      </behavior>
    </endpointBehaviors>
  </behaviors>

  <client>
    <endpoint
           address="..."
           behaviorConfiguration="MyBehaviorConfig"
           binding="basicHttpBinding"
           bindingConfiguration="..."
           contract="..."
           name="..." />
  </client>
</system.serviceModel>

 

Stay tuned for part 2 where I will talk about what happens in the service


short link to this post:

wcf, asp.net, Fun with .net ,