diff --git a/examples/module/tls.go b/examples/module/tls.go index f5b7d09..156d326 100644 --- a/examples/module/tls.go +++ b/examples/module/tls.go @@ -9,7 +9,11 @@ import ( ) var TLSModule = NewModuleFactory( - Condition(And(HavingBean(types.StringType, "certFile"), HavingBean(types.StringType, "keyFile")), + Condition( + And( + HavingFile(types.StringType, "certFile"), + HavingFile(types.StringType, "keyFile"), + ), Declare( Method(func(param struct { config *tls.Config `inject:"'default' optional"` diff --git a/factory/factory.go b/factory/factory.go index 0a99d2b..ae35bec 100644 --- a/factory/factory.go +++ b/factory/factory.go @@ -113,10 +113,28 @@ func NewSliceFactory(typ reflect.Type, name ...types.StringFactory) types.BeanFa return &resolveAnyFactory{typ: typ} } - f := &resolveNamesFactory{typ: typ} - f.name = make([]types.StringFactory, len(name)) - copy(f.name, name) - return f + dump := make([]types.StringFactory, len(name)) + copy(dump, name) + + if types.BeanFactoryType == typ { + return &resolveGeneralFactory{ + typ: typ, + append: func(value reflect.Value, factory types.GeneralFactory) reflect.Value { + return reflect.Append(value, reflect.ValueOf(factory.(types.BeanFactory))) + }, + } + } + + if types.BeanFactoryType == typ { + return &resolveGeneralFactory{ + typ: typ, + append: func(value reflect.Value, factory types.GeneralFactory) reflect.Value { + return reflect.Append(value, reflect.ValueOf(factory)) + }, + } + } + + return &resolveNamesFactory{typ: typ, name: dump} } func NewLazyFactory(typ reflect.Type, factory types.BeanFactory) types.BeanFactory { diff --git a/factory/slice.go b/factory/slice.go index 323fd28..5d9b11f 100644 --- a/factory/slice.go +++ b/factory/slice.go @@ -46,3 +46,20 @@ func (f *resolveNamesFactory) Instance(provider types.Provider) (interface{}, er return val.Interface(), nil } + +func (f *resolveGeneralFactory) Instance(provider types.Provider) (interface{}, error) { + val := reflect.MakeSlice(reflect.SliceOf(f.typ), 0, len(f.name)) + + for _, b := range f.name { + id, err := b.Instance(provider) + if nil != err { + // add check error + continue + } + if v := provider.Factory(nil, id, -1); nil != v { + val = f.append(val, v) + } + } + + return val.Interface(), nil +} diff --git a/factory/struct.go b/factory/struct.go index d04c52d..bd67630 100644 --- a/factory/struct.go +++ b/factory/struct.go @@ -93,3 +93,9 @@ type makeChanFactory struct { typ reflect.Type length int } + +type resolveGeneralFactory struct { + typ reflect.Type + name []types.StringFactory + append func(reflect.Value, types.GeneralFactory) reflect.Value +} diff --git a/module/operation/condition.go b/module/operation/condition.go index 027cb2b..d3162b0 100644 --- a/module/operation/condition.go +++ b/module/operation/condition.go @@ -1,9 +1,11 @@ package operation import ( + "fmt" "github.com/vlorc/gioc/module" "github.com/vlorc/gioc/types" "github.com/vlorc/gioc/utils" + "os" "reflect" "strings" ) @@ -27,8 +29,8 @@ func havingValue(eq func(types.BeanFactory, types.Provider) bool, typ reflect.Ty return false } for _, v := range names { - if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "") { - if str, err := types.NewNameFactory(v).Instance(ctx.Container().AsProvider()); nil != err { + if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") { + if str, err := types.NewNameFactory(v[2 : len(v)-1]).Instance(ctx.Container().AsProvider()); nil != err { // add check error continue } else { @@ -45,15 +47,17 @@ func havingValue(eq func(types.BeanFactory, types.Provider) bool, typ reflect.Ty } func HavingBean(impType interface{}, names ...string) module.ModuleCondHandle { - return havingValue(func(factory types.BeanFactory, provider types.Provider) bool { - return nil != factory - }, utils.TypeOf(impType), names...) + return havingValue(havingBean, utils.TypeOf(impType), names...) } func HavingValue(eq func(types.BeanFactory, types.Provider) bool, impType interface{}, names ...string) module.ModuleCondHandle { return havingValue(eq, utils.TypeOf(impType), names...) } +func HavingFile(impType interface{}, names ...string) module.ModuleCondHandle { + return havingValue(havingFile, utils.TypeOf(impType), names...) +} + func Not(cond ...module.ModuleCondHandle) module.ModuleCondHandle { return func(c *module.ModuleInitContext) bool { for _, v := range cond { @@ -96,3 +100,19 @@ func Equal(val interface{}) func(types.BeanFactory, types.Provider) bool { return reflect.DeepEqual(val, instance) } } + +func havingBean(factory types.BeanFactory, provider types.Provider) bool { + return nil != factory +} + +func havingFile(factory types.BeanFactory, provider types.Provider) bool { + instance, err := factory.Instance(provider) + if nil != err { + return false + } + + file := fmt.Sprint(instance) + _, err = os.Stat(file) + + return nil == err || !os.IsNotExist(err) +} diff --git a/provider/provider.go b/provider/provider.go index 83a3a2f..2a11d7b 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -56,7 +56,7 @@ func (p *coreProvider) load(receive interface{}, typ reflect.Type, name string) return } -func (p *coreProvider) Factory(typ reflect.Type, name string, deep int) types.BeanFactory { +func (p *coreProvider) Factory(typ reflect.Type, name string, deep int) types.GeneralFactory { if factory := p.selector.Get(typ, name); nil != factory { return factory } diff --git a/types/types.go b/types/types.go index 6271c35..7feb0e6 100644 --- a/types/types.go +++ b/types/types.go @@ -42,7 +42,7 @@ type Provider interface { Load(receive interface{}, name ...string) error - Factory(typ reflect.Type, name string, deep int) BeanFactory + Factory(typ reflect.Type, name string, deep int) GeneralFactory Range(callback func(GeneralFactory) bool, types ...reflect.Type) bool @@ -230,3 +230,5 @@ var Type = reflect.TypeOf((*reflect.Type)(nil)).Elem() var StringType = reflect.TypeOf((*string)(nil)).Elem() var ErrorType = reflect.TypeOf((*error)(nil)).Elem() var ProviderType = reflect.TypeOf((*Provider)(nil)).Elem() +var BeanFactoryType = reflect.TypeOf((*BeanFactory)(nil)).Elem() +var GeneralFactoryType = reflect.TypeOf((*GeneralFactory)(nil)).Elem()