Sunday, April 25, 2010

WCF 4.0 : File less activation and Custom service host

With WCF 4.0 comes a feature where in a developer will not required to have a .svc file physically. An svc file is required for the IIS or WAS so that the servicehost can instantiate a new service using IInstanceprovider and as specfied in svc markup.This can be circumvented in .NET 3.5 by writing a UrlReWrite module in IIS. But that gives you a new set of maintainability problems. This .svc file can be a bit painful in REST based services as it violates REST principles.But in .NET 4.0, dependency on ,.svc has been addressed and look how easy it is. Whats good is this can coupled with a custom service host. Lets look at the implemenation

I have a WCF service project configured as a virtual directory. My service class is "FileLessActivationTest1.Service1" where "FileLessActivationTest1" in the namespace. Open the web.config and enter the following.

Basically it says that if there is a request made for Service1.svc, use Service1 class. Basically that's what svc file did previously. Now you can delete .svc file and check out. Remember, service1.cs is still required.
Hold on, that wasnt the only thing .svc file achieved. It also had the option to specify a service host.
Lets define our custom service host as follows

 Now amend the service activation in the config as shown below.

Just like in .svc file, this has an attribute called factory and all we have to do is to supply the factory class name. Thats it. We have a WCF service with file less activation and with custom service host.

The sample is here

Sunday, April 18, 2010

WCF 4.0 : Routing Service(Content Based routing)

WCF 4.0 comes with whole lot of new features primarily aimed at enhancing Rapid application development.Features like svc less WCF service,enhanced and simplified config makes it even more productive to develop and deploy WCF services. One such feature is the WCF 4.0 routing service.

Lets assume a scenario where we have a customer processing service. We have one service that processes legacy customers(customers that are already part of business process). And another service that processes entirely new customers. In .NET 3.5, a WCF client would have to call the appropriate service based on the customer type. So the clients needs to aware of two endpoints. Teh service owner needs to apply security,configuration,transaction supports to each service individually.

To relieve the WCF clients pain of deciding the service to be called, we can have a WCF intermediary service whose endpoint is exposed to the client and the remaining services endpoints are exposed only to this intermediary service.But this requires the service developer to write an intermediary service which takes a lot of plumbing and therefore a lot of effort. Check this article by Michele Leroux Bustamante. WCF Routing .

But thats in .NET 3.5. Come WCF 4.0 and looks what feature has been added. We have something called as WCF routing service which takes care of the rotuing. All you need to code is the logic to route.

Our solution has five projects as shown below.One class library to hold the re usable contracts. Two services(new customer service and legacy customer) that use the contracts in the contract librayr project. One routin service and the console client. The WCF services have following service implementation



public string ProcessCustomer(CustomerInformation info)

{
return "Legacy customer processed";
}

Nothing fancy in there. Now lets turn our attention to the routing service.Remove all the auto generated stuff except for the svc file and the config. Even the code behind can deleted. In teh svc make sure your mark up is like this


And now to the web.config. Add the actual endpoint addresses of our legacy and new customer service.

<client>
<endpoint address="http://localhost:62662/NewCustomer.svc" binding="basicHttpBinding" contract="*" name="NewCustomerEP"></endpoint>
<endpoint address="http://localhost:62656/LegacyCustomer.svc" binding="basicHttpBinding" contract="*" name="LegacyCustomerEP"></endpoint>
</client>

Next we have to inform the routing logic and set up the routing filters as below.

<routing>
<namespaceTable>
<add namespace="http://schemas.datacontract.org/2004/07/ContractLibrary" prefix="custom"/>
</namespaceTable>
<filterTables>
<filterTable name="filterTable1">
<add filterName="LegacyCustomerFilter" priority="0" endpointName="LegacyCustomerEP" />
<add filterName="NewCustomerFilter" priority="0" endpointName="NewCustomerEP" />
</filterTable>
</filterTables>
<filters>
<filter name="LegacyCustomerFilter" filterType="XPath" filterData="//custom:CustomerType='LEGACY'"/>
<filter name="NewCustomerFilter" filterType="XPath" filterData="//custom:CustomerType='NEW'"/>
</filters>
</routing>
The above filter setup says that if CustomerType element in the message equals 'LEGACY' then route it to legacy service endpoint and if its 'NEW' then route it to new service endpoint.This is simplified using XPATH which is just one of the otions to filter. Its that simple!!But yes a bit of work might be needed to identify the XPATH query.

The Source Code is here

Sunday, March 14, 2010

Obsolete types and methods in .NET

With the release of .NET 4.0, there is lot of methods and types that are depracated for the better i guess. For example, the system.data.oracleclient namespace . Microsoft has been recommending to use third party providers to connect to oracle. The complete list of the obsolete types in .NET 4.0 can be found here .

Sunday, November 29, 2009

\m/\m/ Amon Amarth @ Bangalore

Atlast Amon amarth has set foot in India. This must be one of the most highly awaited Metal gigs in India. Adding to that excitement is my attendance.Lol.. Viking metal rulez!!And these are the gods of viking metal. If everything falls into place, i'll be at bangalore to attend the show. 5 days to go!!

Monday, November 23, 2009

At last i have my three medals in social msdn wcf forum

It feels great to have earned three medals in the msdn wcf forum. I am in the group of illustrious guys like Yaron naveh. I didnt mean to say that i am in the same league as Yaron. Hope nobody misinterprets this. He is a web services interoperability guru! I am still learning the technology everyday. But more importantly it feels great when somebody marks your answer. Yes it gives me 10 points :D. But the satisfaction derived out of the fact that you helped somebody today can be overwhelming. Hope this is a precursor for things to come.

Sunday, November 22, 2009

Single Winform Application

We wrote a production windows forms application. The requirement was that there can be only one instance of the application at any point in time. So we used Process.GetProcessByName as we knew the application name. We ran into the following problems :

1.)We didnt realize that there can be many processes with the same name. This can attributed to improper testing.
2.)Also GetProcessByName method needs admin access to execute.
3.)This is very costly method.

So what did we do?Use a named mutex. That too the name of the mutex that we chose had a GUID.If the application can acquire the named mutex with WaitOne, then it is the first instance running. If the application calls WaitOne and WaitOne returns false, another instance of the application is running and this one needs to exit.

This is what we did :


static class Program
    {

        private static string appGuid = new Guid().ToString();

        ///
        /// The main entry point for the application.
        ///

        [STAThread]
        static void Main()
        {
           
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Mutex mutex = new Mutex(false, appGuid);
            if (!mutex.WaitOne(0, false))
            {
                MessageBox.Show("Instance of applicationame is already running");
                return;
            }
            Application.Run(new Form1());
        }

Everything was good, until we deployed this in production. We were still able to create multiple instances but not as frequently as were able to do without the mutex. I am still trying to find out the reason behind this. So if anybody comes across this blog and has an answer to the above quetion please let me know.

We were able to solve the issue by keeping the mutex alive and disposing it off just before the application exits.

using (Mutex mutex = new Mutex(false, appGuid))
            {
                if (!mutex.WaitOne(0, false))
                {
                    MessageBox.Show("Instance already running");
                    return;
                }
                Application.Run(new Form1());
            }

Note that this is a local mutex and restricts creation of instances within the particular user session. To create a global mutex and make sure that there is only one instance across user sessions mutex needs to be created as following
using (Mutex mutex = new Mutex(false, @"Global\" + appGuid))

Wednesday, November 4, 2009

Reflection and Explicitly implemented interface members

I have an interface ISomeInterface that does something.

public interface ISomeInterface
{
void DoSomething();
}

And a class SomeClass that implements ISomeInterface explicitly.

public class SomeClass : ISomeInterface
{
#region ISomeInterface Members

void ISomeInterface.DoSomething()
{
throw new NotImplementedException();
}

#endregion
}

My goal was to reflect the members of SomeClass. So i went ahead and wrote this common code :

Type type = typeof(SomeClass);
MethodInfo[] methodInfo = type.GetMethods();

To my surprise methodInfo had only those methods provided by System.Object.



Hold on where's my interface method? Taking a second look at my SomeClass i found that explicitly implemented member was private to SomeClass. Ok So this brings BindingFlags into play. BindingFlags control the binding and specify the way search is conducted for types and members in reflection. Luckly GOOGLE did the trick again.

Type type = typeof(SomeClass);


MethodInfo[] methodInfo = type.GetMethods(BindingFlags.NonPublic
BindingFlags.Instance);