func Test_InjectorSetParent(t *testing.T) { injector := inject.New() injector.MapTo("another dep", (*SpecialString)(nil)) injector2 := inject.New() injector2.SetParent(injector) expect(t, injector2.Get(inject.InterfaceOf((*SpecialString)(nil))).IsValid(), true) }
//结论:Apply方法是用于对struct的字段进行注入,参数为指向底层类型为结构体的指针。 //可注入的前提是:字段必须是导出的(也即字段名以大写字母开头),并且此字段的tag设置为`inject` func main() { s := TestStruct{} inj := inject.New() inj.Map("陈一回") inj.MapTo("男", (*SpecialString)(nil)) inj2 := inject.New() inj2.Map(20) inj.SetParent(inj2) inj.Apply(&s) fmt.Println("s.Name =", s.Name) fmt.Println("s.Gender =", s.Gender) fmt.Println("s.Age =", s.Age) fmt.Println("s.Nick =", s.Nick) fmt.Println("s.uid =", s.uid) }
func (ae *App) MakeHandler(handlers ...interface{}) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { child := inject.New() child.SetParent(ae.Injector) child.MapTo(w, (*http.ResponseWriter)(nil)) child.Map(r) handlerLoop: for _, reqProcessor := range handlers { result, err := child.Invoke(reqProcessor) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(os.Stderr, "error in url %v: %v\n", r.URL, err) return } if len(result) == 0 { continue } else { valAsInterface := result[0].Interface() if resp, ok := valAsInterface.(HTTPResponse); ok { err := resp.Render(w) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(os.Stderr, "error: %v", err) } if reflect.TypeOf(valAsInterface) != reflect.TypeOf(ChainHttpResponse{}) { break handlerLoop } } } } } }
func TestInjectImplementors(t *testing.T) { injector := inject.New() g := &Greeter{"Jeremy"} injector.Map(g) expect(t, injector.Get(inject.InterfaceOf((*fmt.Stringer)(nil))).IsValid(), true) }
func wrap(f interface{}) func(*cli.Context) { return func(ctx *cli.Context) { if ctx.GlobalBool("debug") { log.SetOutputLevel(log.Ldebug) } sockPath := filepath.Join(GOSUV_HOME, "gosuv.sock") if err := testConnection("unix", sockPath); err != nil { log.Fatal(err) } conn, err := connect(ctx) if err != nil { log.Fatal(err) } defer conn.Close() programClient := pb.NewProgramClient(conn) gosuvClient := pb.NewGoSuvClient(conn) inj := inject.New() inj.Map(programClient) inj.Map(gosuvClient) inj.Map(ctx) inj.Invoke(f) } }
func Test_InjectorInvoke(t *testing.T) { injector := inject.New() expect(t, injector == nil, false) dep := "some dependency" injector.Map(dep) dep2 := "another dep" injector.MapTo(dep2, (*SpecialString)(nil)) dep3 := make(chan *SpecialString) dep4 := make(chan *SpecialString) typRecv := reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(dep3).Elem()) typSend := reflect.ChanOf(reflect.SendDir, reflect.TypeOf(dep4).Elem()) injector.Set(typRecv, reflect.ValueOf(dep3)) injector.Set(typSend, reflect.ValueOf(dep4)) _, err := injector.Invoke(func(d1 string, d2 SpecialString, d3 <-chan *SpecialString, d4 chan<- *SpecialString) { expect(t, d1, dep) expect(t, d2, dep2) expect(t, reflect.TypeOf(d3).Elem(), reflect.TypeOf(dep3).Elem()) expect(t, reflect.TypeOf(d4).Elem(), reflect.TypeOf(dep4).Elem()) expect(t, reflect.TypeOf(d3).ChanDir(), reflect.RecvDir) expect(t, reflect.TypeOf(d4).ChanDir(), reflect.SendDir) }) expect(t, err, nil) }
func Injs(args ...interface{}) Injector { inj := inject.New() for _, v := range args { inj.Map(v) } return inj }
// 连接函数 返回error 结束 下一次传递 func JoinBy(t interface{}, fs ...interface{}) interface{} { val := reflect.ValueOf(t) if val.Kind() != reflect.Func { return nil } for k, v := range fs { c := toCaller(v) if c == nil { return nil } fs[k] = c } typ := val.Type() r := reflect.MakeFunc(typ, func(args []reflect.Value) (results []reflect.Value) { inj := inject.New() for _, v := range args { inj.Set(v.Type(), v) } inj = SliceFunc(inj, fs) for i := 0; i != typ.NumOut(); i++ { results = append(results, inj.Get(typ.Out(i))) } return }) return r.Interface() }
func Test_Static_Options_Logging(t *testing.T) { response := httptest.NewRecorder() var buffer bytes.Buffer m := &Martini{Injector: inject.New(), action: func() {}, logger: log.New(&buffer, "[martini] ", 0)} m.Map(m.logger) m.Map(defaultReturnHandler()) opt := StaticOptions{} m.Use(Static(currentRoot, opt)) req, err := http.NewRequest("GET", "http://localhost:3000/martini.go", nil) if err != nil { t.Error(err) } m.ServeHTTP(response, req) expect(t, response.Code, http.StatusOK) expect(t, buffer.String(), "[martini] [Static] Serving /martini.go\n") // Now without logging m.Handlers() buffer.Reset() // This should disable logging opt.SkipLogging = true m.Use(Static(currentRoot, opt)) m.ServeHTTP(response, req) expect(t, response.Code, http.StatusOK) expect(t, buffer.String(), "") }
// create new helper, this object will be used for globar service for martini middleware func New() *MartiniHelper { this := &MartiniHelper{inject.New()} retHandler := martini.New().Get(reflect.TypeOf(martini.ReturnHandler(nil))).Interface() // retHandler := martini.defaultReturnHandler() this.Map(retHandler) return this }
func (e *eventManager) Trigger(eventName EventType, data map[string]interface{}) { e.Lock() defer e.Unlock() handlers, ok := e.events[eventName] wildcardHandlers, wok := e.events[AllEvents] if !ok && !wok { return } event := Event{eventName, data} c := inject.New() c.SetParent(e.injector) c.Map(event) if ok { for _, handler := range handlers { c.Invoke(handler.Interface()) } } if wok { for _, handler := range wildcardHandlers { c.Invoke(handler.Interface()) } } }
func NewApp() *App { return &App{ TemplateFuncs: make(map[string]interface{}), TemplateCache: make(map[string]*template.Template), CacheTemplates: true, Injector: inject.New(), } }
func (m *Martini) createContext(res http.ResponseWriter, req *http.Request) *context { c := &context{inject.New(), m.handlers, m.action, NewResponseWriter(res), 0} c.SetParent(m) c.MapTo(c, (*Context)(nil)) c.MapTo(c.rw, (*http.ResponseWriter)(nil)) c.Map(req) return c }
func Test_InjectorGet(t *testing.T) { injector := inject.New() injector.Map("some dependency") expect(t, injector.Get(reflect.TypeOf("string")).IsValid(), true) expect(t, injector.Get(reflect.TypeOf(11)).IsValid(), false) }
func (w *WorkerConfig) worker(id string) { injector := inject.New() injector.SetParent(w.Injector) for msg := range w.workQueue { if msg.die { break } job := msg.job typ, ok := w.workerMapping[msg.job.Type] if !ok { err := UnknownWorkerError{job.Type} w.scheduleRetry(job, err, true) continue } w.trackJobStart(job, id) // wrap Perform() in a function so that we can recover from panics var err error var worker interface{} func() { defer func() { if r := recover(); r != nil { err = newPanicError(r) } }() workerVal := reflect.New(typ) worker = workerVal.Interface() if err = json.Unmarshal(*job.Args, worker); err != nil { return } injector.Map(job) if err = injector.Apply(worker); err != nil { return } var res []reflect.Value res, err = injector.Invoke(workerVal.MethodByName("Perform").Interface()) if err != nil { return } if resErr := res[0].Interface(); resErr != nil && resErr.(error) != nil { err = resErr.(error) } }() if err != nil { report := true if checker, ok := worker.(ReportableErrorChecker); ok { report = checker.ReportableError(err) } w.scheduleRetry(job, err, report) } w.trackJobFinish(job, id, err == nil) } w.done.Done() }
func main() { inj := inject.New() inj.Map("Xargin") inj.MapTo("男", (*SpecialString)(nil)) //inj.MapTo("男", (*SpecialString)(nil)) //inj.MapTo(10, (*MyInt)(nil)) inj.MapTo(10, (*MyInt)(nil)) inj.Map(1000) inj.Invoke(say) }
func NewPacketContext(pkt *Packet, ses *Session) IPacketContext { c := &packetContext{ Injector: inject.New(), index: 0, } c.Map(pkt) c.Map(ses) c.MapTo(c, (*IPacketContext)(nil)) return c }
func Test_InjectorApply(t *testing.T) { injector := inject.New() injector.Map("a dep").MapTo("another dep", (*SpecialString)(nil)) s := TestStruct{} err := injector.Apply(&s) expect(t, err, nil) expect(t, s.Dep1, "a dep") expect(t, s.Dep2, "another dep") }
func main() { ij := inject.New() ij.Map(20) ij.MapTo("Good Morning", (*MyString)(nil)) ij1 := inject.New() ij1.Map("Steven") ij.SetParent(ij1) ij.Invoke(Hello) fmt.Println(inject.InterfaceOf((*MyString)(nil))) team := MyStruct{} ij2 := inject.New() ij2.Map("Liverpool LFC") ij2.MapTo("England", (*MyString)(nil)) ij2.Apply(&team) fmt.Printf("TEAM NAME: %s \n", team.Name) fmt.Printf("TEAM TEAM: %s \n", team.Team) fmt.Printf("TEAM LOCATION: %s \n", team.Location) }
func NewSession() *Session { env := make(map[string]string) for _, key := range []string{"PATH"} { env[key] = os.Getenv(key) } s := &Session{ inj: inject.New(), alias: make(map[string][]string), dir: Dir(""), Stdout: os.Stdout, Stderr: os.Stderr, Env: env, } return s }
func TestEventHandler(t *testing.T) { invoker := inject.New() manager := NewEventManager(invoker) test := false manager.Bind(TestEvent, func(event Event) { test = true }) manager.Trigger(TestEvent, nil) if !test { t.Error("Failed to trigger event") } }
// NewAction creates an empty action, ready to populate with views func NewAction(name string, config ConfigValues) *Action { a := &Action{ Injector: inject.New(), name: name, views: make(map[string]*View), items: make([]*Item, 0), } // config if _, found := config["actionDefaultScript"]; !found { panic("you should specify 'actionDefaultScript' in the config") } defaultConfig := ConfigValues{ "debug": false, "autoUpdate": true, } for k, v := range config { defaultConfig[k] = v } a.Config = NewConfigDefaults(a.SupportPath(), defaultConfig) a.Cache = NewCache(a.CachePath()) fd, err := os.OpenFile(path.Join(a.SupportPath(), "error.log"), os.O_APPEND|os.O_CREATE|os.O_WRONLY|os.O_SYNC, 0644) if err != nil { fd = os.Stderr } a.Logger = log.New(fd, "", 0) c := &Context{ Action: a, Config: a.Config, Cache: a.Cache, Logger: a.Logger, } a.context = c a.Map(c) data, err := ioutil.ReadFile(path.Join(a.ActionPath(), "Contents", "Info.plist")) if err != nil { a.Logger.Println(err) panic(err) } _, err = plist.Unmarshal(data, &a.info) if err != nil { a.Logger.Println(err) panic(err) } return a }
func Test_InjectorInvoke(t *testing.T) { injector := inject.New() expect(t, injector == nil, false) dep := "some dependency" injector.Map(dep) dep2 := "another dep" injector.MapTo(dep2, (*SpecialString)(nil)) _, err := injector.Invoke(func(d1 string, d2 SpecialString) { expect(t, d1, dep) expect(t, d2, dep2) }) expect(t, err, nil) }
func (this *MartiniHelper) context(rwc *karambie.ResponseWriterContext, r *http.Request) martini.Context { if v, ok := rwc.GetOk(contextInstance); ok { return v.(martini.Context) } else { c := &context{inject.New()} c.SetParent(this) c.Map(rwc) c.MapTo(c, (*martini.Context)(nil)) c.MapTo(martini.NewResponseWriter(rwc), (*http.ResponseWriter)(nil)) c.Map(r) rwc.Set(contextInstance, c) return c } }
// NewInjector creates a TestInjector func NewInjector(method string, body string) *Injector { var i Injector i.r, _ = http.NewRequest(method, "http://localhost/v1/", strings.NewReader(body)) w := httptest.NewRecorder() enc := negotiator.JsonEncoder{PrettyPrint: false} cn := negotiator.NewContentNegotiator(enc, w) cn.AddEncoder(negotiator.MimeJSON, enc) i.Injector = inject.New() i.Injector.Map(i.r) i.Injector.MapTo(w, (*http.ResponseWriter)(nil)) i.Injector.MapTo(cn, (*negotiator.Negotiator)(nil)) return &i }
func NewWorkerConfig() *WorkerConfig { w := &WorkerConfig{ Injector: inject.New(), PollInterval: defaultPollInterval, StopTimeout: defaultStopTimeout, WorkerCount: defaultWorkerCount, Queues: QueueConfig{"default": 1}, ReportError: func(error, *Job) {}, workerMapping: make(map[string]reflect.Type), workQueue: make(chan message), work: make(map[string]*Job), } w.RedisPool = redis.NewPool(func() (redis.Conn, error) { return redis.Dial("tcp", defaultRedisServer) }, w.WorkerCount+1) return w }
func TestInvalidHandler(t *testing.T) { failed := false defer func() { if err := recover(); err == InvalidHandler { failed = true } }() invoker := inject.New() manager := NewEventManager(invoker) manager.Bind(TestEvent, nil) if !failed { t.Error("Failed to trigger error") } }
func Test_InjectorSet(t *testing.T) { injector := inject.New() typ := reflect.TypeOf("string") typSend := reflect.ChanOf(reflect.SendDir, typ) typRecv := reflect.ChanOf(reflect.RecvDir, typ) // instantiating unidirectional channels is not possible using reflect // http://golang.org/src/pkg/reflect/value.go?s=60463:60504#L2064 chanRecv := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0) chanSend := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0) injector.Set(typSend, chanSend) injector.Set(typRecv, chanRecv) expect(t, injector.Get(typSend).IsValid(), true) expect(t, injector.Get(typRecv).IsValid(), true) expect(t, injector.Get(chanSend.Type()).IsValid(), false) }
func Test_InjectorInvokeReturnValues(t *testing.T) { injector := inject.New() expect(t, injector == nil, false) dep := "some dependency" injector.Map(dep) dep2 := "another dep" injector.MapTo(dep2, (*SpecialString)(nil)) result, err := injector.Invoke(func(d1 string, d2 SpecialString) string { expect(t, d1, dep) expect(t, d2, dep2) return "Hello world" }) expect(t, result[0].String(), "Hello world") expect(t, err, nil) }
func Test_Static_Options_Expires(t *testing.T) { response := httptest.NewRecorder() var buffer bytes.Buffer m := &Martini{Injector: inject.New(), action: func() {}, logger: log.New(&buffer, "[martini] ", 0)} m.Map(m.logger) m.Map(defaultReturnHandler()) // Serve current directory under /public m.Use(Static(currentRoot, StaticOptions{Expires: func() string { return "46" }})) // Check file content behaviour req, err := http.NewRequest("GET", "http://localhost:3000/martini.go", nil) if err != nil { t.Error(err) } m.ServeHTTP(response, req) expect(t, response.Header().Get("Expires"), "46") }