In my previous post, I showed how you can leverage Sitecore’s Configuration Factory to inject dependencies into properties of class instances — this is known as Setter injection in the Dependency injection world — and thought I would share another way you can inject dependencies into instances of classes defined in configuration: through class constructors (this is known as Constructor injection).
Suppose we have the following interface for objects that perform some kind of operation on parameters passed to their DoSomeOtherStuff() method:
namespace Sitecore.Sandbox.Pipelines.SomePipeline { public interface ISomeOtherThing { void DoSomeOtherStuff(SomeProcessorArgs args, string someString); } }
The following dummy class implements the interface above — sadly, it does not do anything:
namespace Sitecore.Sandbox.Pipelines.SomePipeline { public class SomeOtherThing : ISomeOtherThing { public void DoSomeOtherStuff(SomeProcessorArgs args, string someString) { // TODO: add code to do some other stuff } } }
In my previous post, I defined the following interface for objects that “do stuff”, and will reuse it here:
namespace Sitecore.Sandbox.Pipelines.SomePipeline { public interface ISomeThing { void DoStuff(SomeProcessorArgs args); } }
I have modified the SomeThing class from my previous post to consume an instance of a class that implements the ISomeOtherThing interface above along with a string instance:
using Sitecore.Diagnostics; namespace Sitecore.Sandbox.Pipelines.SomePipeline { public class SomeThing : ISomeThing { public SomeThing(ISomeOtherThing someOtherThing, string someString) { Assert.ArgumentNotNull(someOtherThing, "someOtherThing"); Assert.ArgumentNotNullOrEmpty(someString, "someString"); SomeOtherThing = someOtherThing; SomeString = someString; } public void DoStuff(SomeProcessorArgs args) { SomeOtherThing.DoSomeOtherStuff(args, SomeString); } private ISomeOtherThing SomeOtherThing { get; set; } private string SomeString { get; set; } } }
The Sitecore Configuration Factory will magically create instances of the types passed to the constructor of the SomeThing class defined above, and you can then assign these instances to members defined in your class.
As far as I know — I did a lot of digging in Sitecore.Kernel.dll for answers, and some code experimentation — the Sitecore Configuration Factory will only magically inject instances of class types and strings: it will not inject .NET primitive types (if I am incorrect on this, please share in a comment).
I have reused the SomeProcessor class from my previous post — I did not change any code in it:
using Sitecore.Diagnostics; namespace Sitecore.Sandbox.Pipelines.SomePipeline { public class SomeProcessor { public void Process(SomeProcessorArgs args) { DoSomethingWithArgs(args); } private void DoSomethingWithArgs(SomeProcessorArgs args) { Assert.ArgumentNotNull(SomeThing, "SomeThing"); SomeThing.DoStuff(args); } private ISomeThing SomeThing { get; set; } // is populated magically via Setter injection! } }
We can then piece everything together using a Sitecore patch configuration file:
<?xml version="1.0" encoding="utf-8" ?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <pipelines> <somePipeline> <processor type="Sitecore.Sandbox.Pipelines.SomePipeline.SomeProcessor, Sitecore.Sandbox"> <SomeThing type="Sitecore.Sandbox.Pipelines.SomePipeline.SomeThing, Sitecore.Sandbox"> <param hint="1" type="Sitecore.Sandbox.Pipelines.SomePipeline.SomeOtherThing, Sitecore.Sandbox" /> <param hint="2">just some string</param> </SomeThing> </processor> </somePipeline> </pipelines> </sitecore> </configuration>
You must define <param> elements in order to pass arguments to constructors. The “hint” attribute determines the order of the parameters passed to the class constructor, though I believe using this attribute is optional (if I am wrong on this assumption, please share in a comment below).
If you have any thoughts on this, please drop a comment.
[…] Leverage the Sitecore Configuration Factory: Inject Dependencies Through Class Constructors […]
Hi Mike,
Not sure why my earlier comment does not show up, where I mentioned that the “hint” attribute is actually not needed. The order of parameters is defined by the order of the nodes in the config file.
The comment you are referring to did not come through.
I had mentioned that these attributes are optional at the bottom of this post.
[…] are a lot of fans of using the Sitecore API as the IoC – Mike Reynolds has written about it, Leverage the Sitecore Configuration Factory: Inject Dependencies Through Class Constructors and Leverage the Sitecore Configuration Factory: Populate Class Properties with Instances of Types […]
[…] Use Sitecore’s inbuilt Configuration Factory. This was described in great detail by Mike Reynolds in his blog Leverage the Sitecore Configuration Factory: Inject Dependencies Through Class Constructors. […]