你也应该尝试一下
Dargo,它是新的,但具有Facebook没有的一些功能。代码在
这里。
以下是一个示例:
在此示例中,名为SimpleService的服务将注入一个记录器。该记录器本身是一个绑定了创建方法的Dargo服务。该创建方法如下:
func newLogger(ioc.ServiceLocator, ioc.Descriptor) (interface{}, error) {
return logrus.New(), nil
}
SimpleService的绑定将提供应用于实现接口的结构体。该结构体具有一个带有inject注释的字段,后跟要注入的服务的名称。这是用于实现接口的接口和结构体:
type SimpleService interface {
CallMe()
}
type SimpleServiceData struct {
Log *logrus.Logger `inject:"LoggerService_Name"`
}
func (ssd *SimpleServiceData) CallMe() {
ssd.Log.Info("This logger was injected!")
}
日志服务和SimpleService都被绑定到了ServiceLocator中。这通常在程序开始时完成:
locator, err := ioc.CreateAndBind("InjectionExampleLocator", func(binder ioc.Binder) error {
binder.Bind("SimpleService", SimpleServiceData{})
binder.BindWithCreator("LoggerService_Name", newLogger).InScope(ioc.PerLookup)
return nil
})
返回的定位器可用于查找SimpleService服务。SimpleService绑定到单例范围(默认范围),这意味着它只会在第一次查找或注入时创建,以后不会再创建。另一方面,LoggerService处于PerLookup范围,这意味着每次注入或查找时都会创建一个新的实例。
这是使用查找到的服务的代码:
raw, err := locator.GetDService("SimpleService")
if err != nil {
return err
}
ss, ok := raw.(SimpleService)
if !ok {
return fmt.Errorf("Invalid type for simple service %v", ss)
}
ss.CallMe()
支持任何深度的注入(ServiceA可以依赖于ServiceB,后者依赖于ServiceC等等)。服务还可以依赖于尽可能多的服务(ServiceA可以依赖于服务D、E和F等等)。但是,服务不能具有循环依赖关系。
datastr
类型添加一个工厂函数,返回一个Guy
接口,因为这可以在编译时保证你的结构体实现了预期要实现的接口。 - Kaedys