func (c *configuration) ClientConnector() ClientConnector {
	return newClientConnector(c.instantiateFactory)
}
ClientConnector is the interface that connect to grpc client
it can be injected to struct at runtime
package grpc
import (
	"google.golang.org/grpc"
	"google.golang.org/grpc/health"
	pb "google.golang.org/grpc/health/grpc_health_v1"
	"hidevops.io/hiboot/pkg/app"
	"hidevops.io/hiboot/pkg/factory"
	"hidevops.io/hiboot/pkg/utils/cmap"
	"hidevops.io/hiboot/pkg/utils/reflector"
	"reflect"
)
const (
	Profile = "grpc"
)
type configuration struct {
	app.Configuration
	Properties *properties
	instantiateFactory factory.InstantiateFactory
}
func newConfiguration(properties *properties, instantiateFactory factory.InstantiateFactory) *configuration {
	c := &configuration{Properties: properties, instantiateFactory: instantiateFactory}
	var dep []string
	for _, srv := range grpcServers {
		if srv.svc != nil {
			dep = append(dep, srv.name)
		}
	}
	c.RuntimeDeps.Set(c.ServerFactory, dep)
	return c
}
type grpcService struct {
	name string
	cb   interface{}
	svc  interface{}
}
var (
	grpcServers []*grpcService
	grpcClients []*grpcService
	clientMap cmap.ConcurrentMap
	registerHealthCheckService = false
)
func RegisterServer(register interface{}, server interface{}) {
	svrName := reflector.GetLowerCamelFullName(server)
	svr := &grpcService{
		name: svrName,
		cb:   register,
		svc:  server,
	}
	app.Register(server)
	grpcServers = append(grpcServers, svr)
}
var Server = RegisterServer
func registerClient(name string, clientConstructors ...interface{}) {
	for _, clientConstructor := range clientConstructors {
		svr := &grpcService{
			name: name,
			cb:   clientConstructor,
		}
		grpcClients = append(grpcClients, svr)
		typ, ok := reflector.GetObjectType(clientConstructor)
		if ok {
			metaData := &factory.MetaData{
				MetaObject: reflect.New(typ).Interface(),
				DepNames:   []string{"grpc.clientFactory"},
			}
			app.Register(metaData)
		}
	}
	app.Register(new(grpc.ClientConn))
}
func RegisterClient(name string, clientConstructors ...interface{}) {
	if !registerHealthCheckService {
		registerHealthCheckService = true
		app.Register(NewHealthCheckService)
	}
	_, ok := clientMap.Get(name)
	if !ok {
		clientMap.Set(name, true)
		clientConstructors = append(clientConstructors, pb.NewHealthClient)
	}
	registerClient(name, clientConstructors...)
}
var Client = RegisterClient
func init() {
	clientMap = cmap.New()
	Server(pb.RegisterHealthServer, health.NewServer)
	app.Register(newConfiguration, new(properties))
}