StructureMapとIDbConnectionで「要求ごと」アプローチを使用する - 接続は開かれますが、実行されると閉じられます

dapper structuremap

質問

「リクエストごと」のシナリオを利用するために、Structure MapでDapperを設定しようとしています。私のGlobal.asaxには以下のものがあります(AyendeのNHibernate関連の古いポストから修正されたもの、StructureMapのBuildUp()メソッドの説明がありBuildUp() )。

protected static IDbConnection CreateConnection() { 
    var settings = ConfigurationManager.ConnectionStrings["MyConnectionString"];
    var connection = DbProviderFactories.GetFactory(settings.ProviderName).CreateConnection();
    if (connection == null) { 
        throw new ArgumentNullException("connection");
    }
    connection.ConnectionString = settings.ConnectionString;
    return connection;
}

public static IDbConnection CurrentConnection { 
    get { return (IDbConnection)HttpContext.Current.Items["current.connection"]; }
    set { HttpContext.Current.Items["current.connection"] = value; }
}

public Global() { 
    BeginRequest += (sender, args) => { 
        CurrentConnection = CreateConnection();
        CurrentConnection.Open(); 
    };

    EndRequest += (sender, args) => { 
        if (CurrentConnection == null) return;
        CurrentConnection.Close();
        CurrentConnection.Dispose();
    }
}

void Application_Start(object sender, EventArgs e) { 
    ObjectFactory.Initialize(x => { 
        x.For<IDbConnection>().Singleton().Use(CreateConnection());
        x.For<ICustomerRepository>().Use<CustomerRepository>();
        x.SetAllProperties(y => y.OfType<ICustomerRepository>());
    });
}

// BasePage.cs
public class BasePage : System.Web.UI.Page { 
    public IDbConnection CurrentConnection { get; set; }

    public BasePage() { 
        ObjectFactory.BuildUp(this);
    }
}

私がこれを呼び出そうとするたびに、BeginRequestハンドラのブレークポイントがOpen()が接続で呼び出されていることを示していますが、Connectionの現在の状態が閉じられているというエラーで実際のクエリが失敗します。

各リポジトリメソッド内でIDbConnectionのOpenとCloseを手動で呼び出すと動作するようですが、可能ならばそれをやる必要はありません。

受け入れられた回答

接続をシングルトンとして作成しています。つまり、アプリケーション・ページ全体で使用される接続オブジェクトは1つだけです。 Application_Startハンドラで新規に作成した接続は、コンテナから接続を取得するため、ページで使用されることはありません。

次のようなものを使用する方がよいでしょう。

void Application_Start(object sender, EventArgs e) { 
    ObjectFactory.Initialize(x => { 
        x.For<IDbConnection>().HttpContextScoped().Use(() => CreateConnection());
        ...
    }
}

 public Global() { 
    EndRequest += (sender, args) => { 
        ObjectFactory.GetInstance<IDbConnection>.Dispose();
    }
 }


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ