Need help understanding how Ninject is getting a N

2020-02-29 13:53发布

问题:

So using some assistance from tutorials I have managed to wire up a Nhibernate session to my repositories and my repositories to my controllers using Ninject. However, there is one peice of the setup that I am not grasping the "automagic" of what Ninject is doing and was hoping someone could explain.

Below is my Ninject ModuleRepository that inherits from NinjectModule that does all the binding.

public class ModuleRepository : NinjectModule
{
    public override void Load()
    {
        var helper = new NHibernateHelper(ConfigurationManager.ConnectionStrings[Environment.MachineName].ConnectionString);

        Bind<ISessionFactory>().ToConstant(helper.SessionFactory)
            .InSingletonScope();

        Bind<IUnitOfWork>().To<UnitOfWork>()
            .InRequestScope();
        Bind<ISession>().ToProvider<SessionProvider>()
            .InRequestScope();
        Bind<IRepository<Product>>().To<ProductRepository>();
        Bind<IRepository<Category>>().To<CategoryRepository>();
    }
}

Here is the UnitOfWork class:

public class UnitOfWork : IUnitOfWork
{
    private readonly ISessionFactory _sessionFactory;
    private readonly ITransaction _transaction;
    public ISession Session { get; private set; }

    public UnitOfWork(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;

        //Open Session
        Session = _sessionFactory.OpenSession();
        Session.FlushMode = FlushMode.Auto;
        _transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public void Commit()
    {
        if (!_transaction.IsActive)
            throw new InvalidOperationException("There is no active Transaction");
        _transaction.Commit();
    }

    public void Rollback()
    {
        if (_transaction.IsActive)
            _transaction.Rollback();
    }

    //Close open session
    public void Dispose()
    {
        Session.Close();
    }
}

So I understand that we are creating a single instance constant instance of the object that creates a Nhibernate SessionFactory. Below is the SessionProvider class which returns the session from the UnitOfWork object that wraps each unit of work in a transaction.

SessionProvider

public class SessionProvider : Provider<ISession>
{
    protected override ISession CreateInstance(IContext context)
    {
        var unitOfWork = (UnitOfWork)context.Kernel.Get<IUnitOfWork>();
        return unitOfWork.Session;
    }
}

The Repositories take a ISession in their constructor. But what I am not seeing is how the UnitOfWork.Session is the "session" that gets passed to my repositories?

Any help in understanding this would be great. Thanks.

回答1:

The binding using:

Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();

states that it should maintain Request Scope. That means that Ninject will cache all requests for ISession during the entire HttpRequest - so all classes being injected (or explicitly getting an instance) will be using the same instance of the ISession. In your configuration the same goes for the IUnitOfWork.

See this post by Nate Kohari for descriptions of the different scope objects in Ninject.