func (h *ValidatingHandler) InjectDecoder(d *admission.Decoder) error {
	h.Decoder = d
	return nil
}
InjectDecoder injects the decoder into the ComponentValidatingHandler
package component
import (
	"context"
	"encoding/json"
	"fmt"
	admissionv1beta1 "k8s.io/api/admission/v1beta1"
	apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/util/validation/field"
	logf "sigs.k8s.io/controller-runtime/pkg/log"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	"sigs.k8s.io/controller-runtime/pkg/webhook"
	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
	"github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
)
type ValidatingHandler struct {
	Decoder *admission.Decoder
}
var validatelog = logf.Log.WithName("component validate webhook")
var _ admission.Handler = &ValidatingHandler{}
func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) admission.Response {
	obj := &v1alpha2.Component{}
	err := h.Decoder.Decode(req, obj)
	if err != nil {
		validatelog.Error(err, "decoder failed", "req operation", req.AdmissionRequest.Operation, "req",
			req.AdmissionRequest)
		return admission.Denied(err.Error())
	}
	switch req.AdmissionRequest.Operation {  
	case admissionv1beta1.Create:
		if allErrs := ValidateComponentObject(obj); len(allErrs) > 0 {
			validatelog.Info("create failed", "name", obj.Name, "errMsg", allErrs.ToAggregate().Error())
			return admission.Denied(allErrs.ToAggregate().Error())
		}
	case admissionv1beta1.Update:
		if allErrs := ValidateComponentObject(obj); len(allErrs) > 0 {
			validatelog.Info("update failed", "name", obj.Name, "errMsg", allErrs.ToAggregate().Error())
			return admission.Denied(allErrs.ToAggregate().Error())
		}
	}
	return admission.Allowed("")
}
func ValidateComponentObject(obj *v1alpha2.Component) field.ErrorList {
	validatelog.Info("validate component", "name", obj.Name)
	allErrs := apimachineryvalidation.ValidateObjectMeta(&obj.ObjectMeta, true,
		apimachineryvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
	fldPath := field.NewPath("spec")
	var content map[string]interface{}
	if err := json.Unmarshal(obj.Spec.Workload.Raw, &content); err != nil {
		allErrs = append(allErrs, field.Invalid(fldPath.Child("workload"), string(obj.Spec.Workload.Raw),
			"the workload is malformat"))
		return allErrs
	}
	if content[TypeField] != nil {
		allErrs = append(allErrs, field.Invalid(fldPath.Child("workload"), string(obj.Spec.Workload.Raw),
			"the workload contains type info"))
	}
	workload := unstructured.Unstructured{
		Object: content,
	}
	if len(workload.GetAPIVersion()) == 0 || len(workload.GetKind()) == 0 {
		allErrs = append(allErrs, field.Invalid(fldPath.Child("workload"), content,
			fmt.Sprintf("the workload data missing GVK, api = %s, kind = %s,", workload.GetAPIVersion(), workload.GetKind())))
	}
	return allErrs
}
var _ admission.DecoderInjector = &ValidatingHandler{}