NHibernate StructureMap ASP.NET webform System.OutOfMemoryException
i created a web application by using Asp.NET webform, NHibernate to access Sql Server 2008 database and StructureMap as IOC Container.
Everything seem to work ok since few users use it; when user number increases (we can say 10+ users) webapp crashes with this error:
System.OutOfMemoryException
I downloaded redgate ants suite: the performance tool says that maximum cpu time is in NHibernate createSessionFactory for a GetAll request.
This is my NHibernateHelper object:
public static NHibernate.ISessionFactory _sessionFactory;
public static NHibernate.ISessionFactory createSessionFactory()
{
try
{
if (_sessionFactory == null)
{
return
FluentNHibernate.Cfg.Fluently.Configure()
.Database
(
FluentNHibernate
.Cfg.Db.MsSqlConfiguration.MsSql2008
.ConnectionSt开发者_如何学JAVAring
(
c => c
.Server(ConfigurationManager.DbConnectionValue.Server)
.Username(ConfigurationManager.DbConnectionValue.User)
.Password(ConfigurationManager.DbConnectionValue.Password)
.Database(ConfigurationManager.DbConnectionValue.Database)
)
.ProxyFactoryFactory("NHibernate.ByteCode.LinFu.ProxyFactoryFactory,NHibernate.ByteCode.LinFu")
)
.Mappings
(
m => m.FluentMappings.AddFromAssemblyOf<Repository.IRepositoryBlocco>()
)
.BuildSessionFactory();
}
else
return _sessionFactory;
}
catch (Exception ex)
{
throw ex;
}
}
This is the way i read data from db:
public IList<DomainModel.Model.Variabile> GetAll()
{
try
{
var session_factory = NHibernateHelper.createSessionFactory();
using (var session = session_factory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var query = session.Linq<DomainModel.Model.Variabile>()
.OrderBy(v => v.ordine);
return query.ToList();
}
}
}
catch (Exception ex)
{
throw ex;
}
}
Am i doing any mistakes? Could it be the one which provokes OutOfMemoryException? Best regards
It looks like the SessionFactory is created in every call to the GetAll method. Creating the SessionFactory is an expensive operation. I would follow one of the two options below
Create the SessionFactory in the Application's start method. This would be in the Global.asax.cs file. Then expose a static public property for the SessionFactory in the Global asax class that could be accessed from any method as so
Global.SessionFactory.OpenSession
The other option would be to have a Repository factory or a Repository Provider class. This would have a constructor that would take in the connection string. It will build the SessionFactory based on the constructor parameters and create an instance of Repository class. The Repository class would have all your Getxxx methods. So this would be something like
public interface IRepositoryFactory
{
IRepository GetRepository();
}
public interface IRepository:IDispose
{
IEnumerable<T> Getxxx<T>();
}
public class RepositoryFactory:IRepositoryFactory
{
private string _connectionString;
public RepositoryFactory(string connectionString)
{
_connectionString=connectionString;
}
public IRepository GetRepository()
{
//use the connection string and fluently build SessionFactory
return new Repository(SessionFactory.OpenSession());
}
}
public class Repository:IRepository
{
private ISession _session;
public Repository(ISession session)
{
_session=session;
}
public IEnumerable<T> Getxxx<T>()
{
return _session.Query<T>();
}
public void Dispose()
{
//dispose session and any other disposables
}
}
And you can configure StructureMap to provide instances of RepositoryFactory
For<IRepositoryFactory>.Use<RepositoryFactory>().Ctor<string>.EqualToAppSetting("connStr");
Now you can tell SM to give you instance of RepositoryFactory using which you can obtain a Repository instance and make all the Getxx calls.
Hope this helps!
First of all you're creating a new Session factory for every call. This is an expensive operation. You should have one session factory for your app that creates sessions as needed. Second of all you're not following the unit of work pattern that is recommended by NHibernate:
http://nhforge.org/wikis/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.aspx
精彩评论