8

I've got a Sitecore Rule, based on WhenCondition<T> where T : RuleContext

Is there a way to use dependency injection on a sitecore rule?

Currently having to use service locator pattern within

protected override bool Execute(T ruleContext)

:/

//Clarification//

This is for Sitecore 8.1 update 3, but I'd be interested to know if was possible in future versions also.

  • 1
    what is the version of sitecore? you have to use service locator in sc 8.1 and older, but may be v8.2 supports it. – Daniil Nov 18 '16 at 13:55
  • For 8.1 update 3, updated. – Ian Nov 18 '16 at 13:57
  • 1
    then I believe the answer is No. You cannot even use sitecore factory for rules. But it will be nice to see answer with 'yes'. Actually I suppose 'No' is often wrong answer in software development. – Daniil Nov 18 '16 at 13:58
  • Have you tried this? stackoverflow.com/questions/38133076/… – josedbaez Nov 18 '16 at 16:48
2

I do not know of any version of Sitecore that supports Dependency Injection for Rules out of the box. Using dotPeek against 8.2 Sitecore.Kernel.dll it looks like you can override the default RuleFactory but you cannot in earlier versions.

My suggestion would be to use the Service Locator pattern and overload the constructor.

 public class AccountHasProduct<T> : WhenCondition<T>
    where T : RuleContext
 {
    [NotNull]
    private readonly ICustomerContextFactory _customerContextFactory;

    public AccountHasProduct()
        : this(null)
    {}

    public AccountHasProduct([CanBeNull] ICustomerContextFactory customerContextFactory)
    {
        _customerContextFactory = customerContextFactory ?? Ioc.Resolve<ICustomerContextFactory>();
    }
    ...

** Important note: Rule objects are NOT transient, meaning they are pulled across requests so whatever you inject must NOT have user/session/request specific state.

|improve this answer|||||
  • That's the approach I have taken as well when dealing with DI-unfriendly entities. By the way, wouldn't it be more readable if you passed the dependency directly into the other constructor? I.e. :this(Ioc.Resolve<ICustomerContextFactory>()) – Dmytro Shevchenko Nov 25 '16 at 15:08
  • I agree. : this(Ioc.Resolve<ICustomerContextFactory>() would be cleaner. – Joe Bissol Nov 25 '16 at 15:19
1

Unfortunately no, in my opinion. At the moment you can only use for events and pipelines. Like described here - https://stackoverflow.com/questions/38133076/sitecore-inject-dependency-into-sitecore-components. What you could use is resolve the dependency via property in your rule class. Something like:

public class MyRule  
{  
    public virtual IMyDependency MyDependency  
    {  
        get { return IocContainer.Resolve<IMyDependency>(); }  
    }  
}  

It is not the most elegant way but it works. If it is virtual then you can also mock this property in your tests.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.