Design a service override and plan its registration

Define a small policy interface, register its implementation in Znode 9, and verify the actual resolved service before extending platform behavior.

Znode 9GuideIntermediateGCG engineering guide
In this guide
  1. consumer
  2. interface
  3. custom implementation
  4. composition root
  5. resolved instance
The composition root chooses the implementation once; callers depend on the interface.

Define the smallest owned behavior

Start with a small application rule: an external reference must contain non-whitespace text and be at most 40 characters after trimming. IExternalReferencePolicy names that rule, and ExternalReferencePolicy implements it without depending on a platform service model.

DependencyRegistration tells Znode's Autofac container how to supply the policy when a caller requests IExternalReferencePolicy. This example adds your own service. Replacing a Znode service requires its actual installed interface and the custom implementation of that contract.

ExternalReferencePolicy.cs csharp

using System;
using Autofac;
using Znode.Libraries.Framework.Business;

public interface IExternalReferencePolicy
{
    bool IsAcceptable(string value);
}

public sealed class ExternalReferencePolicy : IExternalReferencePolicy
{
    public bool IsAcceptable(string value)
    {
        return !string.IsNullOrWhiteSpace(value) && value.Trim().Length <= 40;
    }
}

public sealed class DependencyRegistration : IDependencyRegistration
{
    public void Register(ContainerBuilder builder)
    {
        builder.RegisterType<ExternalReferencePolicy>()
            .As<IExternalReferencePolicy>()
            .InstancePerRequest();
    }

    public int Order
    {
        get
        {
            return 1;
        }
    }
}

IsAcceptable(' REF-001 ') returns true, while whitespace-only text and a trimmed value longer than 40 characters return false. The method validates but does not return normalized text, so the caller must apply its chosen trimming policy when saving. InstancePerRequest shares the resolved policy within the request lifetime.

Register at the intended boundary

Find the composition root, the startup code where the application registers services. Merge this registration into the custom project's supported registration path and preserve the expected ordering after base registrations. Inject IExternalReferencePolicy into the request handler that needs it.

Resolve the interface through the real application container to confirm which class is used. Constructing ExternalReferencePolicy directly at each call site bypasses the container and can hide a registration mistake.

Prove resolution before behavior

Write one focused test that resolves the interface through the application container and confirms the expected implementation type. Then test accepted, blank, and too-long values. Finally exercise the concrete request that calls the policy, because a passing unit test does not prove the override was wired into the application path. A common failure is a valid class that is never registered, leaving the base service active without an error.

Distinguish your interface from the platform seam

For a platform override, substitute the installed Znode service interface and your implementation in the RegisterType/As registration. Preserve the supported lifetime and verify ordering in the target container; this application-owned policy interface alone does not replace vendor behavior.

Keep the change narrow. Delegate unchanged work to the supported base implementation where the extension model allows it, and verify a request that must retain its original authorization, caching, and calculation behavior.

References and further reading

Bring your next engineering question.

Need an extension seam reviewed before implementation?

Explore how GCG can help

Independent guidance from GCG. Znode is a trademark of its owner. Examples use fictional data and are not official platform documentation. Suggest a correction.

Previous
Previous

Separate dropdown options from localized attribute labels

Next
Next

Read a Store attribute through a typed adapter