2

Иногда я получаю эту ошибку трассировки стека на моем веб-приложение:SessionFactory поточно проблема

[ArgumentException: An item with the same key has already been added.] 
    System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) +52 
    System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +10695474 
    System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value) +10 
    NHibernate.Util.ThreadSafeDictionary`2.Add(TKey key, TValue value) +93 
    NHibernate.Type.TypeFactory.GetType(NullableType defaultUnqualifiedType, Int32 length, GetNullableTypeWithLength ctorDelegate) +88 
    NHibernate.Type.TypeFactory.<RegisterDefaultNetTypes>b__c(Int32 l) +82 
    NHibernate.Type.TypeFactory.BuiltInType(String typeName, Int32 length) +46 
    NHibernate.Mapping.SimpleValue.GetHeuristicType() +168 
    NHibernate.Mapping.SimpleValue.get_Type() +49 
    NHibernate.Mapping.SimpleValue.IsValid(IMapping mapping) +30 
    NHibernate.Mapping.PersistentClass.Validate(IMapping mapping) +87 
    NHibernate.Mapping.RootClass.Validate(IMapping mapping) +21 
    NHibernate.Cfg.Configuration.ValidateEntities() +183 
    NHibernate.Cfg.Configuration.Validate() +13 
    NHibernate.Cfg.Configuration.BuildSessionFactory() +36 
    Framework.Data.Code.BaseSessionFactoryProvider..ctor() +74 
    Framework.Data.Code.SessionFactoryProvider..ctor() +29 
    Framework.Data.Code.NestedSessionManager..cctor() +43 

Мой SessionFactoryProvider потокобезопасно singletone:

public interface ISessionFactoryProvider 
{ 
     ISessionFactory GetSessionFactory(); 
} 
public abstract class BaseSessionFactoryProvider : ISessionFactoryProvider 
{ 
     protected readonly ISessionFactory factory; 
     public ISessionFactory GetSessionFactory() 
     { 
      return factory; 
     } 

     protected BaseSessionFactoryProvider() 
     { 
      factory = GetConfig().BuildSessionFactory(); 
     } 
     public abstract Configuration GetConfig(); 
} 
public class SessionFactoryProvider : BaseSessionFactoryProvider 
{ 
      public static ISessionFactory SessionFactory 
      { 
       get { return Instance.factory; } 
      } 
      public override Configuration GetConfig() 
      { 
       return new Configuration().Configure(); 
      } 
      public static SessionFactoryProvider Instance 
      { 
       get 
       { 
        return NestedSessionManager.sessionManager; 
       } 
      } 
      class NestedSessionManager 
      { 
       internal static readonly SessionFactoryProvider sessionManager = 
        new SessionFactoryProvider(); 
      } 
    } 

Кроме того, в моем приложении я связываю SessionFactoryProvider к ISessionFactoryProvider через ninject kernel.Bind<ISessionFactoryProvider>().To<SessionFactoryProvider>().InSingletonScope();

Так что мой вопрос, почему я могу получить эту ошибку?

+0

Не вводите в заблуждение 'ThreadSafeDictionary' в трассировке стека. Я не думаю, что это проблема с потоками. Скорее всего, это проблема с сопоставлениями NHibernate. У вас есть два объекта, которые имеют одно и то же имя класса? Возможно, в разных пространствах имен? –

+0

@ DanielSchilling, если это должно быть дублирующее отображение, не будет ли ошибка всегда появляться, а не «иногда»? – jbl

+1

Боюсь, у меня нет ответа ... Но вы, кажется, смешиваете немного другую версию этого http://csharpindepth.com/Articles/General/Singleton.aspx#nested-cctor с наследованием. Я не вижу недостатков здесь (но я не C# ниндзя). Вы также смешиваете его с реализацией одного синглета IOC. Я думаю, проблема может быть здесь, и вы должны полагаться только на свою IOC для реализации singleton. – jbl

ответ

0

В моих комментариях я сказал, что не видел недостатков в реализации Singleton. Фактически, есть очевидный: ваш конструктор без параметров не является приватным, потому что SessionFactoryProvider не имеет перегрузки для его конструктора.

Таким образом, компилятор генерирует конструктор по без параметров для SessionFactoryProvider см Should we always include a default constructor in the class?

Таким образом, любой код может создать экземпляр нового SessionFactoryProvider через этот публичный конструктор (это должно быть легко проверить), который используется Ninject для конкретизации класс. (Это меня озадачило: как Ninject создает экземпляр класса? Он не должен создавать экземпляр класса без публичного конструктора). Я думаю, это так, как вы заканчиваете с дубликатом SessionFactoryProvider.

Вы должны реализовать свой SessionFactoryProvider с помощью открытого конструктора, не обращая внимания на реализацию одного синглтона. Затем просто положитесь на Ninject и его InSingletonScope(), чтобы обеспечить однотонную функциональность

Смежные вопросы