Design a service override and plan its registration

Add behavior behind a narrow interface, register it in the supported composition root, and verify the resolved service. Avoid a broad replacement whose scope is unknown.

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

Define the smallest owned behavior

Begin with a single decision that is not client policy, such as rejecting a blank external reference. Keep the platform service call outside the example until the concrete extension seam is reviewed.

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; } }
}

Register at the intended boundary

Find the project's real composition root and determine whether it supports replacement, decoration, or additive registration. Put the registration in one obvious location. Do not construct the service with new at call sites because that bypasses lifecycle and test seams.

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

The interface in this recipe is application-owned. It is safe to name, version, and unit-test because its contract is defined here. The registration is a concrete Autofac pattern used by Znode 9 custom projects: RegisterType<T>().As<TInterface>().InstancePerRequest() and a custom registration order of 1. When replacing a platform service, substitute the actual installed platform interface and custom class in that same registration shape.

When an override calls platform behavior, prefer delegation over replacement. Define which inputs the override validates, which behavior it leaves to the base implementation, and which errors it returns unchanged. Test registration ordering with the real container, then regression-test a request that should retain base behavior. That prevents a narrow rule from accidentally replacing authorization, caching, or other surrounding 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.