I've got a setup with Ninject and NHibernate like this. Now, if I have this scenario..
class HomeController : Controller
{
[Inject]
public ISession Session { get; set; }
}
This works properly.
But if I make another class ...
class QueryObject
{
[Inject]
public ISession Session { get; set; }
}
// .. somewhere else in my program.
var test = new QueryObject().Execute();
The ISession is null! This is not just with ISession, it is with anything I try to inject.
Here is my SessionModule:
public class SessionModule : Ninject.Modules.NinjectModule
{
private static ISessionFactory sessionFactory;
public override void Load()
{
Bind<ISessionFactory>()
.ToMethod(c => CreateSessionFactory())
.InSingletonScope();
Bind<ISession>()
.ToMethod(c => OpenSession())
.InRequestScope()
.OnActivation(session =>
{
session.BeginTransaction();
session.FlushMode = FlushMode.Commit;
})
.OnDeactivation(session =>
{
if (session.Transaction.IsActive)
{
try
{
session.Transaction.Commit();
}
catch
{
session.Transaction.Rollback();
}
}
});
}
/// <summary>
/// Create a new <see cref="NHibernate.ISessionFactory"/> to connect to a database.
/// </summary>
/// <returns>
/// A constructed and mapped <see cref="NHibernate.ISessionFactory"/>.
/// </returns>
private static ISessionFactory CreateSessionFactory()
{
if (sessionFactory == null)
sessionFactory = Persistence.SessionFactory.Map
(System.Web.Configuration
.WebConfigurationManager
.ConnectionStrings["Local"]
.ConnectionString
);
return sessionFactory;
}
/// <summary>
/// Open a new <see cref="NHibernate.ISession"/> from a <see cref="NHibernate.ISessionFactory"/>.
/// </summary>
/// <returns>
/// A new <see cref="NHibernate.ISession"/>.
/// </returns>
private static ISession OpenSession()
{
// check to see if we even have a session factory to get a session from
if (sessionFactory == null)
CreateSessionFactory();
// open a new session from the factory if there is no current one
return sessionFactory.OpenSession();
}
}
It's working for controllers because you're instantiating them with Ninject (via the controller factory).
When you're doing new QueryObject().Execute();
your're not using Ninject to instantiate your QueryObject. The .NET framework itself has no knowledge of injecting properties.
You need to use the Ninject Kernel to resolve your QueryObject. Something like this should do it:
IKernel kernel = new StandardKernel(new SessionModule());
var queryObject = kernel.Get<QueryObject>();
queryObject.Execute();
The kernel will then instantiate a new QueryObject with all dependencies properly set.
For this to work, you'll have to register the QueryObject:
Bind<QueryObject>().ToSelf();
This tells Ninject to always return a instance of an QueryObject when you're doing kernel.Get<QueryObject>();
This is done in your SessionModule
.
I recommend reading Modules and the Kernel from the docs. ≈
You can do the following if you want to create the object yourself:
class QueryObject
{
[Inject]
public ISession Session { get; set; }
}
// .. somewhere else in my program.
var test = new QueryObject();
kernel.Inject(test);
Ninject will then try to fulfil your dependencies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With