Skip to content

Commit

Permalink
refactor interface Container
Browse files Browse the repository at this point in the history
  • Loading branch information
berkaroad committed Oct 24, 2023
1 parent 74f765e commit b228860
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 41 deletions.
40 changes: 18 additions & 22 deletions ioc.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ var resolverType reflect.Type = reflect.TypeOf((*Resolver)(nil)).Elem()
// New ioc container, and add singleton service 'ioc.Resolver' to it.
func New() Container {
var c Container = &defaultContainer{}
c.RegisterSingleton(resolverType, c)
c.AddSingleton(resolverType, c)
return c
}

// Inversion of Control container.
type Container interface {
Resolver

// RegisterSingleton to add singleton instance.
// AddSingleton to add singleton instance.
//
// // service
// type Service1 interface {
Expand All @@ -71,12 +71,12 @@ type Container interface {
//
// var container ioc.Container
// // interface as service, register as singleton
// err := container.RegisterSingleton(reflect.TypeOf((*Service1)(nil)).Elem(), &ServiceImplementation1{Field1: "abc"})
// err := container.AddSingleton(reflect.TypeOf((*Service1)(nil)).Elem(), &ServiceImplementation1{Field1: "abc"})
// // or *struct as service, register as singleton
// err = container.RegisterSingleton(reflect.TypeOf((*ServiceImplementation1)(nil)), &ServiceImplementation1{Field1: "abc"})
RegisterSingleton(serviceType reflect.Type, instance any) error
// err = container.AddSingleton(reflect.TypeOf((*ServiceImplementation1)(nil)), &ServiceImplementation1{Field1: "abc"})
AddSingleton(serviceType reflect.Type, instance any) error

// RegisterTransient to add transient by instance factory.
// AddTransient to add transient by instance factory.
//
// // service
// type Service1 interface {
Expand All @@ -90,14 +90,14 @@ type Container interface {
//
// var container ioc.Container
// // interface as service, register as transient
// err = container.RegisterTransient(reflect.TypeOf((*Service1)(nil)).Elem(), func() any {
// err = container.AddTransient(reflect.TypeOf((*Service1)(nil)).Elem(), func() any {
// return &ServiceImplementation1{Field1: "abc"}
// })
// // or *struct as service, register as transient
// err = container.RegisterTransient(reflect.TypeOf((*ServiceImplementation1)(nil)), func() any {
// err = container.AddTransient(reflect.TypeOf((*ServiceImplementation1)(nil)), func() any {
// return &ServiceImplementation1{Field1: "abc"}
// })
RegisterTransient(serviceType reflect.Type, instanceFactory any) error
AddTransient(serviceType reflect.Type, instanceFactory func() any) error
}

// Resolver can resolve service.
Expand Down Expand Up @@ -156,7 +156,7 @@ func AddSingleton[TService any](instance TService) {
//
// It will panic if 'TService' or 'instance' is invalid.
func AddSingletonToC[TService any](container Container, instance TService) {
err := container.RegisterSingleton(reflect.TypeOf((*TService)(nil)).Elem(), instance)
err := container.AddSingleton(reflect.TypeOf((*TService)(nil)).Elem(), instance)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -196,8 +196,8 @@ func AddTransientToC[TService any](container Container, instanceFactory func() T
if instanceFactory == nil {
panic("param 'instanceFactory' is null")
}
err := container.RegisterTransient(reflect.TypeOf((*TService)(nil)).Elem(), func() reflect.Value {
return reflect.ValueOf(instanceFactory())
err := container.AddTransient(reflect.TypeOf((*TService)(nil)).Elem(), func() any {
return instanceFactory()
})
if err != nil {
panic(err)
Expand Down Expand Up @@ -395,7 +395,7 @@ func (c *defaultContainer) Resolve(serviceType reflect.Type) reflect.Value {
}
return binding.Instance
}
return binding.InstanceFactory()
return reflect.ValueOf(binding.InstanceFactory())
} else {
parent := c.parent
if parent != nil {
Expand All @@ -420,7 +420,7 @@ func (c *defaultContainer) SetParent(parent Resolver) {
}
}

func (c *defaultContainer) RegisterSingleton(serviceType reflect.Type, instance any) error {
func (c *defaultContainer) AddSingleton(serviceType reflect.Type, instance any) error {
if serviceType == nil {
return errors.New("param 'serviceType' is null")
}
Expand Down Expand Up @@ -451,23 +451,19 @@ func (c *defaultContainer) RegisterSingleton(serviceType reflect.Type, instance
return c.addBinding(binding)
}

func (c *defaultContainer) RegisterTransient(serviceType reflect.Type, instanceFactory any) error {
func (c *defaultContainer) AddTransient(serviceType reflect.Type, instanceFactory func() any) error {
if serviceType == nil {
return errors.New("param 'serviceType' is null")
}
if instanceFactory == nil || reflect.ValueOf(instanceFactory).IsZero() {
if instanceFactory == nil {
return errors.New("param 'instanceFactory' is null")
}
instanceFactoryFunc, ok := instanceFactory.(func() reflect.Value)
if !ok {
return errors.New("param 'instanceFactory' should be func() reflect.Value")
}
binding := c.getBinding(serviceType)
if binding != nil {
// ignore exists service in current container
return nil
}
binding = &serviceBinding{ServiceType: serviceType, InstanceFactory: instanceFactoryFunc}
binding = &serviceBinding{ServiceType: serviceType, InstanceFactory: instanceFactory}
return c.addBinding(binding)
}

Expand Down Expand Up @@ -500,7 +496,7 @@ type serviceBinding struct {
Instance reflect.Value
InstanceInitializer reflect.Value
InstanceInitialized bool
InstanceFactory func() reflect.Value
InstanceFactory func() any

initializerLocker sync.Mutex
}
Expand Down
Loading

0 comments on commit b228860

Please sign in to comment.