ホームページ  >  記事  >  バックエンド開発  >  Baa フレームワークの依存性注入 (DI) とは何ですか?

Baa フレームワークの依存性注入 (DI) とは何ですか?

WBOY
WBOYオリジナル
2016-06-20 12:25:521065ブラウズ

私が初めて触れた Go WEB フレームワークは beego でした。これは非常に強力なフレームワークであり、あまりにも (bu) 強力 (go) なので、多くの人が最初に選択します。 ling) (huo) その後、マカロン (マティーニ) を試しました。 Macaron の設計は、多くのフレームワーク、ルーティング、ミドルウェア、HTTP コンテキストの主流のアイデアであり、一般的に使用されるいくつかのミドルウェアを実装しています (追記。一部のミドルウェア コードは beego から来ています)。マカロンさんの頭の中では、m.Map() で任意の型を注入し、Context へのリフレクションで型を取得できるとのことで、初めて試したときはとても嬉しくて、その設計を褒めました。

PHP を使用する場合、Phalcon というフレームワークがあり、その設計の中心となるのは、log、db、などのサービスを登録することです。キャッシュやメタデータなどを DI に保存し、使用する場合は DI から取り出してください。 Phalcon の使用姿勢は、まず APP を初期化し、その後、さまざまな DI を登録し、その後 RUN します。 疑似コードは次のとおりです。

<?php$di = new \Phalcon\DI\FactoryDefault();$di->set('router', new MyRouter());$di->set('logger', function () {    return new LoggerFile('../apps/logs/error.log');});$di->set('db', function () {    return new PdoMysql(        array(            "host"     => "localhost",            "username" => "root",            "password" => "secret",            "dbname"   => "blog"        )    );});$di->set('db2', ...);$di->set('mongo', new \MongoClient());// Create an application$application = new \Phalcon\Mvc\Application($di);// Handle the requestecho $application->handle()->getContent();

上記の初期化は、さまざまなセットに対応しています。の型で、lazyload などもサポートしており、使用方法は比較的簡単です。

<?php$di = new \Phalcon\DI\FactoryDefault();$db = $di->get('db');$mongo = $di->get('mongo');$mongo->selectCollection('xxx');

要約すると、set はサービス (インジェクション) を設定することです。 get は、使用するサービスを取り出すことです。もちろん、PHP は静的言語である Go とは異なり、型アサーションを必要としません。

マカロンを使用するプロセスでは、問題は基本的に明らかです。たとえば、2 つの db が必要な場合、リフレクションに依存しすぎると、同じタイプの登録が 1 つだけになってしまいます。ロガーのタイプは同じですが、異なるサービス目的を実行するのはより困難です。実際、私にとって最も痛いのは、マカロンフレームワークが独自のログパッケージを使用していることです。フレームワークで出力されるログはインジェクションに依存せず、ネイティブです。ログ。 Phalconでの経験を組み合わせて、Phalon DIのアイデアを移植するというアイデアを思いつき、他のアイデアと組み合わせてBaaを作りました。 DI は現在 Baa で書かれている最も単純なものですが、車輪の再発明の最も直接的な結果です。

Baa の DI のアイデアを見ると、set と get という非常にシンプルな内容になっています。使用姿勢は Phalcon と同じですが、遅延ロードなどの多くの姿勢をサポートしていません。 (無名関数) を呼び出すと初期化され、静的クラスは文字列を設定して new を使用します。シンプルではありますが、考え方に違いはありません。例を示します。

package mainimport (    "github.com/go-baa/cache"    _ "github.com/go-baa/cache/redis"    "github.com/go-baa/render"    "gopkg.in/baa.v1")func main() {    // new app    app := baa.New()        // register logger    app.SetDI("logger", log.Logger)        // register render    b.SetDI("render", render.New(render.Options{        Baa:        app,        Root:       "templates/",        Extensions: []string{".html", ".tmpl"},        FuncMap:    template.Funcs(b),    }))    // register cache    app.SetDI("cache", cache.New(cache.Options{        Name:     "cache",        Prefix:   "MyApp",        Adapter:  "memory",        Config:   map[string]string{},    }))    app.SetDI("cache2", cache.New(cache.Options{        Name:     "cache2",        Prefix:   "MyApp2",        Adapter:  "redis",        Config:   map[string]string{},    }))    // router    app.Get("/", func(c *baa.Context) {        ca := c.DI("cache").(cache.Cacher)        ca.Set("test", "baa", 10)        v := ca.Get("test").(string)        c.String(200, v)    })    // run app    app.Run(":1323")}

アプリの初期化では、必要に応じて、Context、context.DI() Get などのロガー、レンダー、キャッシュ、さらには DB 初期化を挿入します。または、baa.Default().GetDI() を使用して他の場所で取得します。上記で指摘したログを見てください。ここでは、フレームワークに組み込まれているロガーを置き換えるために app.SetDI("logger", xxx) を使用するだけです。これは、レンダリングを実装するレンダーを登録するだけです。 baa.Renderer インターフェイスをカスタマイズできます。

依存性注入 (DI) は、数行のコードしかありませんが、設計上のアイデア、コンセプト、問題解決の姿勢です。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。