Ninject игнорируя атрибут [Inject] - PullRequest
8 голосов
/ 20 марта 2011

У меня есть настройки с 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();
    }
}

Ответы [ 2 ]

11 голосов
/ 20 марта 2011

Это работает для контроллеров, потому что вы создаете их экземпляры с помощью 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 всегда возвращать экземпляр QueryObject, когда вы делаете kernel.Get<QueryObject>();

Это делается в вашем SessionModule.

Iрекомендуем прочитать Модули и Ядро из документации.≈

5 голосов
/ 21 марта 2011

Вы можете сделать следующее, если хотите создать объект самостоятельно:

class QueryObject
{
  [Inject]
  public ISession Session { get; set; }
}

// .. somewhere else in my program.
var test = new QueryObject();
kernel.Inject(test);

Затем Ninject попытается выполнить ваши зависимости.

...