【问题标题】:What is the right way to access to instance of class methods outside scope?访问范围外的类方法实例的正确方法是什么?
【发布时间】:2017-06-22 16:47:19
【问题描述】:

我有以下代码:

import std.stdio;
import database;
import router; 
import config;
import vibe.d;

void main()
{
    Config config = new Config();
    auto settings = new HTTPServerSettings;
    settings.port = 8081;
    settings.bindAddresses = ["::1", "127.0.0.1"];

    auto router = new URLRouter();
    router.get("/*", serveStaticFiles("./html"));

    Database database = new Database(config);
    database.MySQLConnect(); // all DB methods are declared here

    router.registerRestInterface(new MyRouter(database));
    router.get("*", &myStuff); // all other request
    listenHTTP(settings, router);

    logInfo("Please open http://127.0.0.1:8081/ in your browser.");
    runApplication();

}


void myStuff(HTTPServerRequest req, HTTPServerResponse res) // I need this to handle any accessed URLs
{
    writeln(req.path); // getting URL that was request on server
    // here I need access to DB methods to do processing and return some DB data
}

我需要创建 router.get("*", &myStuff); 来处理与任何 REST 实例无关的任何 url。

不知道如何从myStuff()获取DB方法的问题

【问题讨论】:

  • make database shared 并将其移至模块范围?

标签: d vibed


【解决方案1】:

没有尝试过,但使用“部分”可能是一个解决方案。

https://dlang.org/phobos/std_functional.html#partial

void myStuff(Database db, HTTPServerRequest req, HTTPServerResponse res) { ... }

void main()
{
    import std.functional : partial;

    ...
    router.get("*", partial!(myStuff, database));
    ...
}

Partial 创建一个函数,其第一个参数绑定到给定值 - 因此调用者不需要知道它。就我个人而言,我不喜欢 globals/、singletons/ 等并尝试注入依赖项。虽然实现可能会变得有点复杂,但这确实大大简化了测试。

上面的示例以类似于此处提到的构造函数注入的方式注入依赖项:

https://en.wikipedia.org/wiki/Dependency_injection#Constructor_injection

像这样注入依赖项时,您还可以快速了解调用此函数所需的组件。如果依赖项的数量增加,请考虑使用其他方法 - 例如。注入一个 ServiceLocator。

https://martinfowler.com/articles/injection.html#UsingAServiceLocator

罗尼

【讨论】:

    【解决方案2】:

    作为部分替代方案,您可以使用closure 实现partial application

    router.get("*", (req, resp) => myStuff(database, req, resp));
    
    // ...
    
    void myStuff(Database db, HTTPServerRequest req, HTTPServerResponse res)
    
    // ...
    

    myStuff 现在从周围的作用域注入了database

    【讨论】:

    • 对,比局部好很多!
    【解决方案3】:

    我没有使用 vibe.d 的经验,但这可能是一种解决方案:

    Database database;
    
    shared static this(){
        Config config = new Config();
        database = new Database(config);
    }
    
    void main(){
    (...)
    
    void myStuff(HTTPServerRequest req, HTTPServerResponse res){
        database.whatever;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-10
      • 2014-03-12
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      相关资源
      最近更新 更多