func (f *configurableFactory) Instantiate(configuration interface{}) (err error) {
	cv := reflect.ValueOf(configuration)
	icv := reflector.Indirect(cv)
	configType := cv.Type()
	pkgName := io.DirName(icv.Type().PkgPath())
	var runtimeDeps factory.Deps
	rd := icv.FieldByName("RuntimeDeps")
	if rd.IsValid() {
		runtimeDeps = rd.Interface().(factory.Deps)
	}
	numOfMethod := cv.NumMethod()
	for mi := 0; mi < numOfMethod; mi++ {
		method := configType.Method(mi)
		methodName := str.LowerFirst(method.Name)
		if rd.IsValid() {
			deps := runtimeDeps.Get(method.Name)
			metaData := &factory.MetaData{
				Name:       pkgName + "." + methodName,
				MetaObject: method,
				DepNames:   deps,
			}
			f.AppendComponent(configuration, metaData)
		} else {
			f.AppendComponent(configuration, method)
		}
	}
	return
}
Instantiate run instantiation by method
package autoconfigure
import (
	"errors"
	"hidevops.io/hiboot/pkg/at"
	"hidevops.io/hiboot/pkg/factory"
	"hidevops.io/hiboot/pkg/inject/annotation"
	"hidevops.io/hiboot/pkg/log"
	"hidevops.io/hiboot/pkg/system"
	"hidevops.io/hiboot/pkg/system/types"
	"hidevops.io/hiboot/pkg/utils/cmap"
	"hidevops.io/hiboot/pkg/utils/io"
	"hidevops.io/hiboot/pkg/utils/reflector"
	"hidevops.io/hiboot/pkg/utils/str"
	"os"
	"reflect"
	"strings"
)
const (
	System = "system"
	PropAppProfilesActive = "app.profiles.active"
	EnvAppProfilesActive = "APP_PROFILES_ACTIVE"
	PostfixConfiguration = "Configuration"
	defaultProfileName = "default"
)
var (
	ErrInvalidMethod = errors.New("[factory] method is invalid")
	ErrFactoryCannotBeNil = errors.New("[factory] InstantiateFactory can not be nil")
	ErrFactoryIsNotInitialized = errors.New("[factory] InstantiateFactory is not initialized")
	ErrInvalidObjectType = errors.New("[factory] invalid Configuration type, one of app.Configuration need to be embedded")
	ErrConfigurationNameIsTaken = errors.New("[factory] configuration name is already taken")
	ErrComponentNameIsTaken = errors.New("[factory] component name is already taken")
)
type configurableFactory struct {
	at.Qualifier `value:"factory.configurableFactory"`
	factory.InstantiateFactory
	configurations cmap.ConcurrentMap
	systemConfig   *system.Configuration
	preConfigureContainer  []*factory.MetaData
	configureContainer     []*factory.MetaData
	postConfigureContainer []*factory.MetaData
	builder                system.Builder
}
func NewConfigurableFactory(instantiateFactory factory.InstantiateFactory, configurations cmap.ConcurrentMap) factory.ConfigurableFactory {
	f := &configurableFactory{
		InstantiateFactory: instantiateFactory,
		configurations:     configurations,
	}
	f.configurations = configurations
	_ = f.SetInstance("configurations", configurations)
	f.builder = f.Builder()
	f.Append(f)
	return f
}
func (f *configurableFactory) SystemConfiguration() *system.Configuration {
	return f.systemConfig
}
func (f *configurableFactory) Configuration(name string) interface{} {
	cfg, ok := f.configurations.Get(name)
	if ok {
		return cfg
	}
	return nil
}
func (f *configurableFactory) BuildProperties() (systemConfig *system.Configuration, err error) {
	systemConfig = f.GetInstance(system.Configuration{}).(*system.Configuration)
	_ = f.InjectDefaultValue(systemConfig)
	profile := os.Getenv(EnvAppProfilesActive)
	if profile == "" {
		profile = defaultProfileName
	}
	f.builder.SetDefaultProperty(PropAppProfilesActive, profile)
	for prop, val := range f.DefaultProperties() {
		f.builder.SetDefaultProperty(prop, val)
	}
	_, err = f.builder.Build(profile)
	if err == nil {
		_ = f.InjectIntoObject(systemConfig)
		f.configurations.Set(System, systemConfig)
		f.systemConfig = systemConfig
	}
	allProperties := f.GetInstances(at.ConfigurationProperties{})
	log.Debug(len(allProperties))
	for _, properties := range allProperties {
		_ = f.builder.Load(properties.MetaObject)
	}
	return
}
func (f *configurableFactory) Build(configs []*factory.MetaData) {
	for _, item := range configs {
		if annotation.Contains(item.MetaObject, at.AutoConfiguration{}) {
			f.configureContainer = append(f.configureContainer, item)
		} else {
			err := ErrInvalidObjectType
			log.Errorf("item: %v err: %v", item, err)
		}
	}
	f.build(f.configureContainer)
	allProperties := f.GetInstances(at.ConfigurationProperties{})
	log.Debug(len(allProperties))
	for _, properties := range allProperties {
		_ = f.builder.Load(properties.MetaObject)
	}
}