2

I implemented a custom submit action and it works fine. But now I'm trying to store data to an external database using repository classes. For some reason it doesn't work if I add other interfaces in the constructor. Here is my code snippet:

public class CustomSubmitAction: SubmitActionBase<string>
{
    private readonly ImessagingServiceRepository _messagingServiceRepository;

    public CustomSubmitAction(ISubmitActionData submitActionData, ImessagingServiceRepository messagingServiceRepository) : base(submitActionData)
    {
        _messagingServiceRepository = messagingServiceRepository;
    }

    protected override bool TryParse(string value, out string target)
    {
        target = string.Empty;
        return true;
    }

    protected override bool Execute(string data, FormSubmitContext formSubmitContext)
    {
        Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));

        if (!formSubmitContext.HasErrors)
        {
            var formfields = formSubmitContext.Fields;
            ......
            // following code is mockup 
            // call repository using 
           _messagingServiceRepository.Save(model);
        }
     }
 }

In the log it shows this warning but when I try to step thru the code it won't even hit the breakpoint on constructor:

WARN  Could not find constructor in ReflectionUtil.CreateObject: Modules.ExperienceForm.CustomSubmitAction. The constructor parameters may not match or it may be an abstract class. Parameter info: Count: 1. Parameter types: Sitecore.ExperienceForms.Mvc.Models.SubmitActionData

If I leave constructor as default it works perfectly.

public CustomSubmitAction(ISubmitActionData submitActionData) : base(submitActionData)
{
}
4

Sitecore grabs the constructor with the signature it knows, i.e. the one with one parameter. If your submit-action doesn't have one, it'll fall back on the standard constructor of SubmitActionBase<string> that your custom submit-action is inheriting from.

You'll have to explicitly call the dependency injection library you use to get the implementation of ImessagingServiceRepository. You could do something like this to have the one-parameter constructor call your two-parameter constructor:

public CustomSubmitAction(ISubmitActionData submitActionData)
    : this(submitActionData,
      My.DependencyInjection.GetImplementation<ImessagingServiceRepository>())
{
}

public CustomSubmitAction(ISubmitActionData submitActionData, ImessagingServiceRepository messagingServiceRepository)
    : base(submitActionData)
{
    _messagingServiceRepository = messagingServiceRepository;
}

This way you can still have a two-parameter constructor that you call in your UnitTest with a Mock-implementation of ImessagingServiceRepository.

0

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.