Замок Виндзор, Беглый Nhibernate и Automapping Isession закрыли проблему - PullRequest
3 голосов
/ 29 декабря 2010

Я новичок во всем стеке виндзорских, Nhibernate, Fluent и Automapping, так что прошу прощения за мое невежество здесь.Я не хотел публиковать еще один вопрос по этому вопросу, поскольку, похоже, уже существует огромное количество вопросов, в которых пытались найти решение проблемы управления Windsor nhib Isession, но ни один из них до сих пор не решил мою проблему.Я все еще получаю исключение ISession закрыто, когда я пытаюсь вызвать Db из моих репозиториев. Вот мой код установки контейнера.

container.AddFacility<FactorySupportFacility>()
            .Register(
                Component.For<ISessionFactory>()
                    .LifeStyle.Singleton
                    .UsingFactoryMethod(() => Fluently.Configure()
                                                  .Database(
                                                      MsSqlConfiguration.MsSql2005.
                                                          ConnectionString(
                                                              c => c.Database("DbSchema").Server("Server").Username("UserName").Password("password")))
                                                  .Mappings
                                                     (
                                                      m => 
                                                      m.AutoMappings.Add
                                                        (
                                                          AutoMap.AssemblyOf<Message>(cfg)
                                                          .Override<Client>(map =>
                                                          {
                                                              map.HasManyToMany(x => x.SICCodes).Table("SICRefDataToClient");
                                                          })
                                                          .IgnoreBase<BaseEntity>()
                                                          .Conventions.Add(DefaultCascade.SaveUpdate())
                                                          .Conventions.Add(new StringColumnLengthConvention(),new EnumConvention())
                                                          .Conventions.Add(new EnumConvention())

                                                          .Conventions.Add(DefaultLazy.Never())
                                                        )
                                                      )
                                                  .ExposeConfiguration(ConfigureValidator)
                                                  .ExposeConfiguration(BuildDatabase)
                                                  .BuildSessionFactory() as SessionFactoryImpl),
                 Component.For<ISession>().LifeStyle.PerWebRequest.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>().OpenSession()
                                                  ));

В своих репозиториях я внедряю private readonly ISession session; и использую егокак следует

 public User GetUser(int id)
    {
        User u;

            u = session.Get<User>(id);
            if (u != null && u.Id > 0)
            { 
                NHibernateUtil.Initialize(u.UserDocuments);
            }


        return u;

в моем web.config внутри <httpModules>.я также добавил эту строку

      <add name="PerRequestLifestyle" 
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/>

Мне все еще не хватает части головоломки здесь, я не могу поверить, что это такая сложная вещь для настройки для базовой потребности любой разработки веб-приложенийс nHibernate и замком Виндзор.

Я пытался следовать приведенному здесь коду windsor-nhibernate-isession-mvc , и я разместил там свой вопрос, поскольку они, похоже, имели ту же проблему, номой не решен.

ОБНОВЛЕНИЕ MooKid8000 Я теперь обновил свой код регистрации замка до этого

private void AddRepositories()
    {
        container.Register(
            AllTypes.FromAssembly(typeof(MembershipRepository).Assembly)
                .Pick()
                .Configure(c => c.Interceptors(
                    InterceptorReference.ForKey("simpleLogger")).Anywhere
                )
                .Configure(c => c.LifeStyle.Is(LifestyleType.Transient))
                .WithService.FirstInterface());
    }

Но я все еще получаю, что ISession закрыт, проблема,Нужно ли регистрировать мои сервисы как временные, не могли бы вы объяснить более подробно, почему они должны быть временными, а не синглтон

ОБНОВЛЕНИЕ Предложение MooKid8000 было на 100% правильным, мне просто нужноубедитесь, что все мои службы и репозитории имеют вид LifestyleType.Transient, чтобы ISession не был уничтожен.Отличное место Mookid8000, даже не увидев изначально код регистрации моего замка.

Если кто-то заинтересован, свяжитесь со мной, и я могу выслать вам настройки моего контейнера.

1 Ответ

5 голосов
/ 30 декабря 2010

Вы не забыли зарегистрировать свои репозитории с временным образом жизни?

Если ваши репозитории являются синглетонами (это стиль жизни по умолчанию в Windsor), то внедренный экземпляр ISession будет «пойман», что приведет кв случае ошибок закрытого сеанса позже.

Обратите внимание, что любые службы, использующие ваши репозитории, также должны иметь временный образ жизни, а также любые службы, использующие эти службы и т. д.

Как правило, вы можетескажем, что детализация образа жизни не должна увеличиваться по мере того, как вы уходите дальше от корня композиции, в противном случае произойдет некоторая область видимости.Конечно, это не всегда проблема, но это может привести к ошибкам, которые довольно сложно диагностировать.

...