Kiwi Ingenuity

Thoughts from another perspective

Implementing a Custom IProxyFactory using the DSA deployed by SCSF

When deploying WCF security, for a Smart Client Service Factory (SCSF) solution the documentation encourage the developer to deploy an EndPointCatalog.  I found this to be a lot of coding when all I wanted to do was simply pass a username and password to the proxy so that it would call the service with the correct credentials.

My workaround is to not create a “EndPoint” section in your client app.config but instead override the GetOnlineProxy Method in the Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory class.

Assuming you have a Service Agent (or similar) Module in your SCSF solution create a new class that inherits the WCFProxyFactory class mentioned above.

using System;
using System.Net;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.Practices.SmartClient.EndpointCatalog;
using Microsoft.Practices.SmartClient.DisconnectedAgent;
namespace MyNamespace
{
   public class WCFProxyFactory : Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory
               where TChannel : class
   {
      public override object GetOnlineProxy(Request request, string networkName)
      {
         Guard.ArgumentNotNull(request, "request");
         ClientBase proxy = (ClientBase)Activator.CreateInstance(request.OnlineProxyType);
         // Set the credentials
         ClientCredentials clientCredentials = proxy.ClientCredentials;
         clientCredentials.UserName.UserName = "myusername";
         clientCredentials.UserName.Password = "mypassword";
         return proxy;
      } 
   }
}

You will need to create a Guard Class which you can simply copy from the source code that comes with SCSF (i.e. Microsoft.Practices.SmartClient.DisconnectedAgent.Guard) and then your solution should successfully compile.

Lastly you need to change the default offlinebehavoir of your Agent which was generated by the Disconnected Service Agent. Look for the GetAgentDefaultBehavior method

public static OfflineBehavior GetAgentDefaultBehavior()
{
   OfflineBehavior behavior = new OfflineBehavior();
   behavior.MaxRetries = 3;
   behavior.Stamps = 1;
   behavior.Expiration = DateTime.Now + new TimeSpan(1, 0, 0, 0);
   // behavior.ProxyFactoryType = typeof(Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory);
   behavior.ProxyFactoryType = typeof(MyNamespace.WCFProxyFactory);
   return behavior;
}

Compile and start your application and it will now pass the credentials on to your service.