Utilisation de l'approche "par demande" avec StructureMap et IDbConnection - la connexion est ouverte mais est fermée lorsqu'elle est exécutée

dapper structuremap

Question

Essayer de configurer Dapper avec StructureMap pour utiliser un type de scénario "par requête". Dans mon Global.asax, j'ai le suivant (modifié à partir d'un ancien article de Ayende impliquant NHibernate, et celui que j'ai trouvé discutant de la méthode BuildUp() dans StructureMap):

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);
    }
}

Chaque fois que j'essaie d'appeler cela, la requête réelle échoue avec une erreur indiquant que l'état actuel de la connexion est fermé, bien qu'un point d'arrêt sur le gestionnaire BeginRequest indique que Open () est appelé sur la connexion.

Cela semble fonctionner si j'appelle manuellement Open et Close sur la IDbConnection dans chaque méthode de référentiel, mais j'essaie d'éviter de le faire si possible.

Réponse acceptée

Vous créez la connexion en tant que singleton. Cela signifie qu'il n'y aura qu'un seul objet de connexion pour toutes les pages d'applications. La connexion que vous créez dans le gestionnaire Application_Start n'est jamais utilisée par les pages, car elles obtiendront la connexion du conteneur.

Vous feriez mieux d'utiliser quelque chose comme ceci:

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();
    }
 }



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi