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.

SCSF - View Removal and Disposal

There are instances where on closing a Work Item View, you would also like to dispose of the footprint.  Here is how it done.

Change the OnCloseView of the Presenter as follows:

#region Closing the View
/// <summary>
/// Close the view
/// </summary>
public void OnCloseView()
{
   base.CloseView();

   // If this presenter has created any workspaces
   // be sure to remove them first.
   // e.g. if (WorkItem.Workspaces.Contains(WorkSpaceName))
   //         WorkItem.Workspaces.Remove(WorkItem.Workspaces[WorkSpaceName]);

   // Remove the View from the SmartParts Collection
   this.WorkItem.SmartParts.Remove(View);

   // As we are closing and re-creating this view
   // several times, we need to Dispose the view.
   if (View is IDisposable)
      ((IDisposable)View).Dispose();

}
#endregion

Open the code behind the  that the presenter controls and add the following Code snippet.

#region Closing the View
void ParentForm_FormClosed(object sender, FormClosedEventArgs e)
{
   _presenter.OnCloseView();
}
#endregion

Finally on the same page change the OnLoad Method so it reads:

protected override void OnLoad(EventArgs e)
{
   _presenter.OnViewReady();
   base.OnLoad(e);

   // Capture the Form Close Event, because we want to destroy 
   // the view on Closing the form

   this.ParentForm.FormClosed += new FormClosedEventHandler(ParentForm_FormClosed);
}

 

And that’s it.   Each time you close the view it will be destroyed and the memory released.