# 自定义服务

服务即是被注入到处理器中的参数. 你可以映射一个服务到 **全局** 或者 **请求** 的级别.

## 全局映射

因为 Macaron 实现了 [`inject.Injector`](https://gowalker.org/github.com/go-macaron/macaron/inject#Injector) 的接口, 那么映射一个服务就变得非常简单:

```go
db := &MyDatabase{}
m := macaron.Classic()
m.Map(db) // Service will be available to all handlers as *MyDatabase
m.Get("/", func(db *MyDatabase) {
    // Operations with db.
})
m.Run()
```

## 请求级别的映射

映射在请求级别的服务可以通过 [`*macaron.Context`](https://gowalker.org/github.com/go-macaron/macaron#Context) 来完成:

```go
func MyCustomLoggerHandler(ctx *macaron.Context) {
    logger := &MyCustomLogger{ctx.Req}
    ctx.Map(logger) // mapped as *MyCustomLogger
}

func main() {
    //...
    m.Get("/", MyCustomLoggerHandler, func(logger *MyCustomLogger) {
        // Operations with logger.
    })
    m.Get("/panic", func(logger *MyCustomLogger) {
        // This will panic because no logger service maps to this request.
    })
    //...
}
```

## 映射值到接口

关于服务最强悍的地方之一就是它能够映射服务到接口. 例如说, 假设你想要覆盖 [`http.ResponseWriter`](http://gowalker.org/net/http#ResponseWriter) 成为一个对象, 那么你可以封装它并包含你自己的额外操作, 你可以如下这样来编写你的处理器:

```go
func WrapResponseWriter(ctx *macaron.Context) {
    rw := NewSpecialResponseWriter(ctx.Resp)
    // override ResponseWriter with our wrapper ResponseWriter
    ctx.MapTo(rw, (*http.ResponseWriter)(nil)) 
}
```

如此一来，您不仅可以修改自定义的实现而不对客户代码做任何修改，还可以允许对于相同类型的服务使用多种实现。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://go-macaron.com/zh-cn/custom_services.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
