I am using Ninject to use the same database connection per request. We have a route called RosterProcess that is another web application inside the root, but using the same code base so we can have two different application pools. I believe the application pools are causing an issue with threading since we are throwing some threads during this process. InThreadScope works, but that opens multiple connections in the database instead of using just one. I am getting the error below and not sure why?
Global.asax
kernel.Bind<IDatabaseFactory>().To<DatabaseFactory<MySqlConnection>>().InRequestScope().WithConstructorArgument("connectionString", Config.Data.MySQLConnection);
Factory
public class DatabaseFactory<T> : Disposable, IDatabaseFactory where T : IDbConnection, new()
{
private readonly string _connectionString;
private IDbConnection _dataConnection;
public DatabaseFactory(string connectionString)
{
_connectionString = connectionString;
}
#region IDatabaseFactory Members
public IDbConnection Get()
{
return _dataConnection ?? (_dataConnection = new T { ConnectionString = _connectionString });
}
#endregion
protected override void DisposeCore()
{
if (_dataConnection != null)
_dataConnection.Dispose();
}
}
Object reference not set to an instance of an object. at
MySql.Data.MySqlClient.MySqlDataReader.Close() at
MySql.Data.MySqlClient.MySqlConnection.Close() at
MySql.Data.MySqlClient.MySqlConnection.Dispose(Boolean disposing) at
System.ComponentModel.Component.Dispose() at
CL.NatGeo.Dashboard.Data.Infrastructure.DatabaseFactory1.DisposeCore()1
at CL.NatGeo.Dashboard.Data.Infrastructure.Disposable.Dispose() at
Ninject.Activation.Strategies.DisposableStrategy.<Deactivate>b__0(IDisposable
x) at Ninject.Activation.InstanceReference.IfInstanceIs[T](Action
action) at
Ninject.Activation.Strategies.DisposableStrategy.Deactivate(IContext
context, InstanceReference reference) at
Ninject.Activation.Pipeline.<>c_DisplayClass6.b_4(IActivationStrategy
s) at
Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable11 action) at
series, Action
Ninject.Activation.Pipeline.Deactivate(IContext context,
InstanceReference reference) at
Ninject.Activation.Caching.Cache.Forget(CacheEntry entry) at
Ninject.Activation.Caching.Cache.Forget(IEnumerable1 cacheEntries) at1
Ninject.Activation.Caching.Cache.Clear(Object scope) at
Ninject.OnePerRequestModule.<>c__DisplayClass5.<DeactivateInstancesForCurrentHttpRequest>b__3(ICache
cache) at
Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable
series, Action`1 action) at
Ninject.OnePerRequestModule.DeactivateInstancesForCurrentHttpRequest()
at Ninject.OnePerRequestModule.b__0(Object o, EventArgs e) at
System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step,
Boolean& completedSynchronously)
Sounds to me like one of your threads thats spawning during the request is attempting to use the database connection – however that connection is already disposed of thanks to Ninject (InRequestScope).
My suggestion is to rethink your architecture. You’ve fallen into the trap of some high level Sequential Cohesion, in that you’re expecting things to happen in a certain order; but as soon as you start spawning threads you’ll never be able to guarantee what order things are happening in. What makes the request take so long you’ve decided to spawn a thread to take care of it? Can that be improved? Is there really a bottleneck by having more than 1 database connection happen?
This also explains why you’re seeing results using the InThreadScope binding – Ninject is keeping a database factory per thread you spawn.