我有这样的Ninject和NHibernate的设置。现在,如果我有这种情况..
class HomeController : Controller
{
[Inject]
public ISession Session { get; set; }
}
这很正常。
但如果我再上一堂课......
class QueryObject
{
[Inject]
public ISession Session { get; set; }
}
// .. somewhere else in my program.
var test = new QueryObject().Execute();
ISession为空!这不仅仅是ISession,它是我尝试注入的任何东西。
这是我的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();
}
}
答案 0 :(得分:11)
它适用于控制器,因为您使用Ninject(通过控制器工厂)实例化它们。
当您执行new QueryObject().Execute();
时,您没有使用Ninject来实例化QueryObject。 .NET框架本身不知道注入属性。
您需要使用Ninject内核来解析QueryObject。这样的事情应该这样做:
IKernel kernel = new StandardKernel(new SessionModule());
var queryObject = kernel.Get<QueryObject>();
queryObject.Execute();
然后,内核将实例化一个新的QueryObject,并正确设置所有依赖项。
为此,您必须注册QueryObject:
Bind<QueryObject>().ToSelf();
这告诉Ninject在执行kernel.Get<QueryObject>();
这是在SessionModule
。
我建议您从文档中阅读Modules and the Kernel。 ≈
答案 1 :(得分:5)
如果您想自己创建对象,可以执行以下操作:
class QueryObject
{
[Inject]
public ISession Session { get; set; }
}
// .. somewhere else in my program.
var test = new QueryObject();
kernel.Inject(test);
Ninject将尝试实现您的依赖关系。