Home » Configuration » Turn the Key to Open the Door on Possibilities using the Key Attribute with the Sitecore Configuration Factory

Turn the Key to Open the Door on Possibilities using the Key Attribute with the Sitecore Configuration Factory

Sitecore Technology MVP 2016
Sitecore MVP 2015
Sitecore MVP 2014

Enter your email address to follow this blog and receive notifications of new posts by email.

So I wanted to dig a little bit further into some code I had shared on a previous post which taps into functionality of the Sitecore Configuration Factory which you may/may not be aware of but I’ll discuss it regardless as someone might benefit from this (I’m not aware of another post discussing this but if you know of one, drop a link to it in the comments below so we can web them together).

Btw, don’t fret — this will be one of my shortest blog posts in history, so you’ll be able to finish it over a coffee break. 😉

The gist of this post is that you can leverage the Sitecore Configuration Factory to help you populate a Dictionary instance where you set the key and value pair in your Sitecore Configuration patch file — I’m sure there are other possiblies on using this feature but populating a Dictionary is where i have used this most often.

Wait, key attribute? What are you talking about Mike?!

The Sitecore configuration Factory looks specifically for an attribute named “key” in child elements of a parent element where either hint=”list:SomeMethod” or “hint=”raw:SomeMethod” are defined in your configuration; I’m sure you’ve used both hint=”list” and/or hint=”raw” for setting Lists in your class instances but this is a bit different. Let’s see how.

When using hint=”list:SomeMethod” with the “key” attribute set on child xml nodes, your method signature should look like this when you are just retrieving a string value from a child element:

void SomeMethod(string key, string value) // hey, this looks like we are set up to populate a Dictionary

If you are creating a key/value pair with a value which is more complex (i.e. you set the type attribute with the fully qualified type of some object on the child element, it should look like this:

void SomeMethod(string key, SomeClassYouDefined someObject) // no way, this also looks like we are set up to populate a Dictionary!

When using hint=”raw:SomeMethod”, your signature would look similarly to other methods you would define with “raw” but with the addition of the key string:

void SomeMethod(string key, XmlNode someNode) // wait, another method which could set us up for populating a Dictionary?!

Let’s look at the code you might have missed in that previous post where I had use this; you might have to go re-read it — or maybe just read it 😉 — to fully understand some of the other objects/classes being used below. I’m not going to explain what this interface and its class are for as I had done this in my previous post but will add code comments describing how this Configuration Factory feature works.

Consider the following interface:

using Foundation.Kernel.Models.Client;

namespace Foundation.Kernel.Services.Client
{
	public interface IClientCommandService
	{
		string GetClientCommand(string name, params string[] arguments);

		Command GetCommand(string name);
	}
}

Here’s the implementation of the interface above:

using System.Collections.Generic;

using Foundation.DependencyInjection;
using Foundation.DependencyInjection.Enums;

using Foundation.Kernel.Models.Client;

namespace Foundation.Kernel.Services.Client
{
	[ServiceConfigObject(ConfigPath = "moduleSettings/foundation/kernel/clientCommandService ", ServiceType = typeof(IClientCommandService), Lifetime = Lifetime.Singleton)]
	public class ClientCommandService : IClientCommandService
	{
		private readonly IDictionary<string, Command> _commands = new Dictionary<string, Command>();

		/* This method will be referenced in the configuration file below, and the Configuration Factory will call it */
		protected void AddClientCommand(string key, Command command)
		{
			if(string.IsNullOrWhiteSpace(key) || command == null)
			{
				return;
			}

			_commands[key] = command; // I'm adding the object instantiated by the Configuration Factory in a Dictionary on this class
		}

		public string GetClientCommand(string name, params string[] arguments)
		{
			string commandFormat = GetCommandFormat(name);
			if(string.IsNullOrWhiteSpace(commandFormat))
			{
				return string.Empty;
			}

			return string.Format(commandFormat, arguments);
		}

		protected virtual string GetCommandFormat(string name) => GetCommand(name)?.CommandFormat;

		public Command GetCommand(string name) => _commands[name];
	}
}

Here’s the Sitecore Configuration patch file which ties this all together (there are xml comments discussing how this ties to the subject of this blog post):

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
<sitecore>
	<services>
		<configurator type="Foundation.Kernel.Configurators.KernelConfigurator, Foundation.Kernel"/>
	</services>
	<moduleSettings>
		<foundation>
			<kernel>
				<clientCommandService type="Foundation.Kernel.Services.Client.ClientCommandService, Foundation.Kernel" singleInstance="true">
					<!-- the AddClientCommand(string key, Command command) method will be invoked -->
					<Commands hint="list:AddClientCommand">
						<!-- I set a key attribute with a type attribute so the Configuration Factory will expect a method of this signature:

							AddClientCommand(string key, Foundation.Kernel.Models.Client.Command command)

							A Commmand instance will be created for the object defined below by the Configuration Factory, and passed to the AddClientCommand method on the ClientCommandService instance above.
						-->
						<command key="item:load" type="Foundation.Kernel.Models.Client.Command, Foundation.Kernel">
							<Name>$(key)</Name> <!-- don't be thrown off by this $(key) here as it's just a context token where its value is put on an instance of Foundation.Kernel.Models.Client.Command, and not related to the Configuration Factory feature being discussed here -->
							<CommandFormat>item:load(id={0})</CommandFormat>
						</command>
					</Commands>
				</clientCommandService>
			</kernel>
		</foundation>
	</moduleSettings>
</sitecore>
</configuration>

Let me know if you have questions/comments/good movie recommendations 😉

Until next time, have a Sitecoretastic day!


Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.