고 언어의 의존성 주입을 위한 Provider
Provider
Provider는 제가 만들고 있는 고 언어에서 의존성 주입을 위한 컨테이너입니다.
정의
type Provider struct {
constructors map[reflect.Type]map[reflect.Value]struct{}
container map[reflect.Type]any
lock sync.RWMutex
}Provider는 constructors와 container를 가지고 있습니다.
constructors는 생성자를 저장하는 맵입니다.container는 실제로 생성된 인스턴스를 저장하는 맵입니다.
생성자 등록
func (p *Provider) Register(constructFunction ...any) error {
p.lock.Lock()
defer p.lock.Unlock()
for _, con := range constructFunction {
if err := p.register(con); err != nil {
return err
}
}
return nil
}
func (p *Provider) register(constructFunction any) error {
args, _, err := analyzeConstructor(constructFunction)
if err != nil {
return err
}
for _, arg := range args {
if _, ok := p.constructors[arg]; !ok {
p.constructors[arg] = make(map[reflect.Value]struct{})
}
p.constructors[arg][reflect.ValueOf(constructFunction)] = struct{}{}
}
return nil
}
func analyzeConstructor(constructFunction any) ([]reflect.Type, []reflect.Type, error) {
if reflect.TypeOf(constructFunction).Kind() != reflect.Func {
return nil, nil, ErrNotAFunction{}
}
constructor := reflect.ValueOf(constructFunction)
var args []reflect.Type
for i := 0; i < constructor.Type().NumIn(); i++ {
args = append(args, constructor.Type().In(i))
}
var returns []reflect.Type
for i := 0; i < constructor.Type().NumOut(); i++ {
returns = append(returns, constructor.Type().Out(i))
}
return args, returns, nil
}Register 메서드는 생성자를 등록하는 메서드입니다.
...any로 가변인자를 받아서 여러개의 생성자를 등록할 수 있습니다.
내부에 정의된 register 메서드를 호출해서 각 함수를 constructors에 저장합니다.