method 包

在 definition 包中,可以看到 Definition.Function 必须是一个函数,这就要求业务逻辑必须放在函数中,而不能在实例方法中。为了解决这个问题,method 包提供了一个实例方法容器,帮助用户把实例方法转换为函数。

容器如下:

// Container contains instances and mappings.
type Container struct {
    ...
}

// Put puts an instance in this container. The instance must have one or more methods.
func (c *Container) Put(instance interface{})

// PutInterface puts an instance in this container. The instance must have one or more methods.
// The iface should be like (*ArbitraryInterface)(nil).
func (c *Container) PutInterface(iface interface{}, instance interface{})

// Get returns a function for specified method. If you want to specify a method from an
// interface, you need to use (*ArbitraryInterface)(nil) as instance.
func (c *Container) Get(instance interface{}, method string) interface{}

这个实例方法容器分离了方法的 Get 和 Put 过程。也就是可以在声明 API 时,使用 Get 获取某个实例的方法,之后再在服务启动逻辑里 Put 真正的实例,即 Get 可以在 Put 之前使用。

这个主要是利用了 golang 的动态函数构建的功能,先生成函数,但是在函数被真正调用的时候才去获取真正的实例里的方法。

method 包还提供了一个全局的 Container:

var defaultContainer = NewContainer()

// Put puts an instance in this container. The instance must have one or more methods.
func Put(instance interface{}) {
    defaultContainer.Put(instance)
}

// PutInterface puts an instance in this container. The instance must have one or more methods.
// The iface should be like (*ArbitraryInterface)(nil).
func PutInterface(iface interface{}, instance interface{}) {
    defaultContainer.PutInterface(iface, instance)
}

// Get returns a function for specified method. If you want to specify a method from an
// interface, you need to use (*ArbitraryInterface)(nil) as instance.
func Get(instance interface{}, method string) interface{} {
    return defaultContainer.Get(instance, method)
}

一般情况下,用户会使用这个全局的容器。

results matching ""

    No results matching ""