Using Sitecore’s Configuration Factory for Dependencies in WFFM Save Actions

The last few days, following a discussion I had with Todd Mitchell (@agenttmi) and Martin English’s (@martinrenglish) talk on CRM and xDB at SUGCON a few weeks back, I’ve been working on integrating Dynamics CRM directly with xDB, bypassing Sitecore’s CRM Connectors entirely.  However, I wanted to be a little more abstract…

abstract-painting-Pablo-Picasso

Well, not quite that way, but in the software development sense…  I wanted to do everything through interfaces so that I could create an implementation for Dynamics CRM or an implementation for Salesforce, but leave my Sitecore events and processors oblivious and loosely coupled.

For example, I might have something like this:

public interface ICmsContext
{
   void GetCrmData(string identifier);
}

public class DynamicsCrmContext : ICmsContext
{
   public void GetCrmData(string identifier)
   {
      //...do some work to call Dynamics CRM
   }
}

I’m a big dependency injection fan.  It makes the design patterns and principles of unit testing and separation of concerns easier to realize.  In all of our Sitecore implementations at RBA, we’re using DI wherever we can.  However, one place we have come up short (so far) is being able to resolve dependencies directly from our IoC container in Pipeline Processors, WFFM Save Actions, etc…

On the heals of a discussion I had with Dan Solovay (@DanSolovay) (also at SUGCON – it was a great conference!), I started playing around with property injection using Sitecore’s Configuration Factory.  This has helped a lot with pipeline processors and event handlers (here’s one of Dan’s latests posts on passing parameters to an event handler through the configuration factory), but tonight, I needed to do the same with a custom Save Action for WFFM.  I needed to inject the current implementation of ICmsContext into my save action.  However, since we don’t define these save actions in config like we do with processors and event handlers, it was less clear to me on how I might accomplish that.

Enter the Sitecore Community over on slack (join the movement)!  Mike Reynolds (@mike_i_reynolds) pointed me to an older post of his explaining how I might specify my implementation of ICmsContext (via a config patch) in the Sitecore configuration, then use Factory.CreateObject() from Sitecore.Configuration in my Save Action.

So, here’s the result.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
   <sitecore>
      <ICrmContext type="CrmProject.DynamicsCrmContext, CrmProject" />
      <settings>
         <setting name="CrmContextKey" value="ICrmContext" />
      </settings>
   </sitecore>
</configuration>
public class MySaveAction : ISaveAction
{
   private ICrmContext _crmContext;

   public void Execute(ID formid, AdaptedResultList fields, params object[] data)
   {
      Assert.IsNotNull(Tracker.Current, "Tracker was null");
      Assert.IsTrue(Tracker.IsActive, "Tracker is not active");
         
      var key = Settings.GetSetting("CrmContextKey");
      Assert.IsNotNullOrEmpty(key, "The CrmContextKey setting was not found");

      _crmContext = Factory.CreateObject(key, true) as ICrmContext;
      Assert.IsNotNull(_crmContext, "You must specify a CrmContext in your config that implements ICrmContext");
   }
}

Now, I have a handle on the current implementation of ICrmContext and can move along!

A couple of things to note, since I have not fully flushed this out:

  • What happens if more than one <ICrmContext> is specified in config?  Do I get the first one or the last one?  Is this a poor design?
  • I need to refactor my execute method so that it’s testable and not tightly coupled to Sitecore.Configuration.Settings and Sitecore.Configuration.Factory

I welcome feedback on this approach.  🙂

Happy Sitecore trails, my friends!

  One thought on “Using Sitecore’s Configuration Factory for Dependencies in WFFM Save Actions

  1. Umesh
    November 10, 2016 at 8:10 am

    Hi Jason Wilkerson,

    Thanks for the Post. It was very much useful for me.
    I am facing an issue with this only when I include an Captcha Field.
    If we remove captcha, it works fine, but when we add Captcha, Its not working.

    Please help.

    Regards,
    Umesh

    Like

Leave a comment