/// <summary>
        /// Initialize and configure the data source using given properties.
        /// Called when space is started.
        /// </summary>
        /// <param name="properties">Propeties to initialize by.</param>
        public override void Init(Dictionary <string, string> properties)
        {
            base.Init(properties);

            _enumeratorLoadFetchSize   = GetIntProperty("EnumeratorLoadFetchSize", _enumeratorLoadFetchSize);
            _initialLoadChunkSize      = GetIntProperty("InitialLoadChunkSize", _initialLoadChunkSize);
            _performOrderById          = GetBoolProperty("PerformOrderById", _performOrderById);
            _initialLoadThreadPoolSize = GetIntProperty("InitialLoadThreadPoolSize", _initialLoadThreadPoolSize);
            _useMerge = GetBoolProperty("UseMerge", _useMerge);

            // only configure a session factory if it is not injected
            if (_sessionFactory == null)
            {
                string nhibernateFile   = GetFileProperty(NHibernateConfigProperty);
                string hbmDirectory     = GetFileProperty(NHibernateHbmDirectory);
                string connectionString = GetProperty(NHibernateConnectionStringProperty);
                _sessionFactory = SessionFactoryBuilder.GetFactory(nhibernateFile, hbmDirectory, connectionString);
            }
            // only extract managed entries if it wasn't injected
            if (_managedEntries == null)
            {
                List <string> managedEntriesList = new List <string>();
                IDictionary <string, IClassMetadata> allClassMetadata = _sessionFactory.GetAllClassMetadata();
                foreach (string type in allClassMetadata.Keys)
                {
                    managedEntriesList.Add(type);
                }
                ManagedEntries = managedEntriesList.ToArray();
            }
            // only extract initial load entries if it wasn't injected
            if (_initialLoadEntries == null)
            {
                List <string> initialLoadEntriesList = new List <string>();
                IDictionary <string, IClassMetadata> allClassMetadata = _sessionFactory.GetAllClassMetadata();
                foreach (KeyValuePair <string, IClassMetadata> entry in allClassMetadata)
                {
                    AbstractEntityPersister entityPersister = (AbstractEntityPersister)entry.Value;
                    string mappedSuperClass = entityPersister.MappedSuperclass;
                    if (mappedSuperClass != null)
                    {
                        IClassMetadata superClassMetadata = allClassMetadata[mappedSuperClass];
                        if (superClassMetadata.GetMappedClass(EntityMode.Map) != null)
                        {
                            //Filter out those who have their super classes mapped
                            continue;
                        }
                    }
                    initialLoadEntriesList.Add(entry.Key);
                }
                InitialLoadEntries = initialLoadEntriesList.ToArray();
            }
        }
Пример #2
0
        private bool CheckDatabaseWasCleaned()
        {
            if (sessions.GetAllClassMetadata().Count == 0)
            {
                // Return early in the case of no mappings, also avoiding a warning when executing the HQL below.
                return(true);
            }

            bool empty;

            using (ISession s = sessions.OpenSession())
            {
                IList objects = s.CreateQuery("from System.Object o").List();
                empty = objects.Count == 0;
            }

            if (!empty)
            {
                log.Error("Test case didn't clean up the database after itself, re-creating the schema");
                DropSchema();
                CreateSchema();
            }

            return(empty);
        }
 public static Core.Validator GetValidatorFromSession(ISessionFactory sessionFactory)
 {
     var allDefindedClasses = sessionFactory.GetAllClassMetadata();
     Core.Validator validator = new Core.Validator();
     foreach (KeyValuePair<string, IClassMetadata> pair in allDefindedClasses)
     {
         IClassMetadata metadata = pair.Value;
         foreach (string propertyName in metadata.PropertyNames)
         {
             IType propertyType = metadata.GetPropertyType(propertyName);
             StringType st = propertyType as StringType;
             if (st != null)
             {
                 if (st.SqlType.Length > 0)
                 {
                     validator.AddRule(Rule.For(metadata.GetMappedClass(EntityMode.Poco))
                         .OnMember(propertyName)
                                 .MaxLength(st.SqlType.Length)
                                 .Message(String.Format(
                                 "Property {0} have a maximum length of {1}",
                                     propertyName,
                                             st.SqlType.Length)));
                 }
             }
         }
     }
     return validator;
 }
Пример #4
0
        public static Core.Validator GetValidatorFromSession(ISessionFactory sessionFactory)
        {
            var allDefindedClasses = sessionFactory.GetAllClassMetadata();

            Core.Validator validator = new Core.Validator();
            foreach (KeyValuePair <string, IClassMetadata> pair in allDefindedClasses)
            {
                IClassMetadata metadata = pair.Value;
                foreach (string propertyName in metadata.PropertyNames)
                {
                    IType      propertyType = metadata.GetPropertyType(propertyName);
                    StringType st           = propertyType as StringType;
                    if (st != null)
                    {
                        if (st.SqlType.Length > 0)
                        {
                            validator.AddRule(Rule.For(metadata.GetMappedClass(EntityMode.Poco))
                                              .OnMember(propertyName)
                                              .MaxLength(st.SqlType.Length)
                                              .Message(String.Format(
                                                           "Property {0} have a maximum length of {1}",
                                                           propertyName,
                                                           st.SqlType.Length)));
                        }
                    }
                }
            }
            return(validator);
        }
Пример #5
0
        private bool CheckDatabaseWasCleaned()
        {
            if (sessions.GetAllClassMetadata().Count == 0)
            {
                // Return early in the case of no mappings, also avoiding
                // a warning when executing the HQL below.
                return(true);
            }

            bool empty = false;

            using (ISession s = sessions.OpenSession())
            {
                foreach (Type type in this.Mappings)
                {
                    IList objects = s.CreateQuery("from " + type.FullName).List();
                    empty = objects.Count == 0;
                    if (!empty)
                    {
                        break;
                    }
                }
            }

            if (!empty)
            {
                Log.Error("Test case didn't clean up the database after itself, re-creating the schema");
                DropSchema();
                CreateSchema();
            }

            return(empty);
        }
        /// <summary>
        /// Registers the interfaces of the entities defined in the session factory in the kernel.
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        /// <param name="sessionFactory">The session factory.</param>
        /// <param name="repository">The repository type to map to <seealso cref="IRepository{T}"/>.</param>
        /// <param name="isCandidateForRepository">The is candidate for repository.</param>
        /// <remarks>
        /// The reason that we have the <paramref name="isCandidateForRepository"/> is to avoid registering services
        /// for interfaces that are not related to the domain (INotifyPropertyChanged, as a good example).
        /// </remarks>
        public static void Register(
            IKernel kernel,
            ISessionFactory sessionFactory,
            Type repository,
            IsCandidateForRepositoryDelegate isCandidateForRepository
            )
        {
            if (ImplementsOpenIRepository(repository) == false)
            {
                throw new ArgumentException("Repository must be a type inheriting from IRepository<T>, and must be an open generic type. Sample: typeof(NHRepository<>).");
            }

            foreach (IClassMetadata meta in sessionFactory.GetAllClassMetadata().Values)
            {
                Type mappedClass = meta.GetMappedClass(EntityMode.Poco);
                if (mappedClass == null)
                {
                    continue;
                }
                foreach (Type interfaceType in mappedClass.GetInterfaces())
                {
                    if (isCandidateForRepository(interfaceType, mappedClass) == false)
                    {
                        continue;
                    }
                    kernel.Register(
                        Component.For(typeof(IRepository <>).MakeGenericType(interfaceType))
                        .ImplementedBy(repository.MakeGenericType(interfaceType))
                        .DependsOn(Property.ForKey("ConcreteType").Eq(mappedClass))
                        );
                }
            }
        }
        public ODataSessionFactoryContext(ISessionFactory sessionFactory)
        {
            Require.NotNull(sessionFactory, "sessionFactory");

            MappedClassMetadata = sessionFactory.GetAllClassMetadata().Values.ToDictionary(
                x => x.GetMappedClass(EntityMode.Poco), 
                x => new MappedClassMetadata(x)
            );
        }
        public static ISessionFactory EnsureHasClassMetadata(this ISessionFactory source)
        {
            if (source.GetAllClassMetadata().Count == 0)
            {
                throw new Exception("В NHSessionFactory отсутствуют какие-либо ClassMetadata: вероятно MappingAssembly указана некорректно.");
            }

            return(source);
        }
Пример #9
0
        public ODataSessionFactoryContext(ISessionFactory sessionFactory)
        {
            Require.NotNull(sessionFactory, "sessionFactory");

            MappedClassMetadata = sessionFactory.GetAllClassMetadata().Values.ToDictionary(
                x => x.MappedClass,
                x => new MappedClassMetadata(x)
                );
        }
Пример #10
0
        public void CanConfirmDatabaseMatchesMappings()
        {
            var allClassMetadata = sessionFactory.GetAllClassMetadata();

            foreach (var entry in allClassMetadata)
            {
                session.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
                .SetMaxResults(0).List();
            }
        }
Пример #11
0
        public IList <Type> GetTables()
        {
            List <Type> result = new List <Type>();

            foreach (var entry in _sessionFactory.GetAllClassMetadata())
            {
                result.Add(entry.Value.GetMappedClass(EntityMode.Poco));
            }
            return(result);
        }
Пример #12
0
        private static void ValidateDatabaseSchemaAgainstMappings(ISessionFactory sessionFactory)
        {
            using (var session = sessionFactory.OpenSession()) {
                var classMetadatas = sessionFactory.GetAllClassMetadata();

                foreach (var classMetadata in classMetadatas)
                {
                    session.CreateCriteria(classMetadata.Value.GetMappedClass(EntityMode.Poco)).SetMaxResults(0).List();
                }
            }
        }
        /// <summary>
        /// Build the Breeze metadata as a nested Dictionary.
        /// The result can be converted to JSON and sent to the Breeze client.
        /// </summary>
        /// <param name="includeFilter">Function that returns true if a Type should be included in metadata, false otherwise</param>
        /// <returns></returns>
        public Metadata BuildMetadata(Func <Type, bool> includeFilter)
        {
            // retrieves all mappings with the name property set on the class  (mapping with existing type, no duck typing)
            IDictionary <string, IClassMetadata> classMeta = _sessionFactory.GetAllClassMetadata().Where(p => ((IEntityPersister)p.Value).EntityMetamodel.Type != null).ToDictionary(p => p.Key, p => p.Value);

            if (includeFilter != null)
            {
                classMeta = classMeta.Where(p => includeFilter(((IEntityPersister)p.Value).EntityMetamodel.Type)).ToDictionary(p => p.Key, p => p.Value);
            }
            return(BuildMetadata(classMeta.Values));
        }
Пример #14
0
        public static void ClearSecondLevelCache(ISessionFactory sessionFactory)
        {
            var classMetadata = sessionFactory.GetAllClassMetadata();
            foreach (var ep in classMetadata.Values) {
                sessionFactory.EvictEntity(ep.EntityName);
            }

            var collMetadata = sessionFactory.GetAllCollectionMetadata();
            foreach (var acp in collMetadata.Values) {
                sessionFactory.EvictCollection(acp.Role);
            }
        }
Пример #15
0
 static void ClearCache(ISessionFactory factory)
 {
     factory.EvictQueries();
     foreach (var collectionMetadata in factory.GetAllCollectionMetadata())
     {
         factory.EvictCollection(collectionMetadata.Key);
     }
     foreach (var classMetadata in factory.GetAllClassMetadata())
     {
         factory.EvictEntity(classMetadata.Key);
     }
 }
Пример #16
0
        /// <summary>
        /// Build the Breeze metadata as a nested Dictionary.
        /// The result can be converted to JSON and sent to the Breeze client.
        /// </summary>
        /// <returns></returns>
        public IDictionary <string, object> BuildMetadata()
        {
            InitMap();

            IDictionary <string, IClassMetadata> classMeta = _sessionFactory.GetAllClassMetadata();

            foreach (var meta in classMeta.Values)
            {
                AddClass(meta);
            }
            return(_map);
        }
Пример #17
0
        /// <summary>
        /// 지정된 <see cref="ISessionFactory"/> 인스턴스에 등록된 모든 NHibernate용 Entity를 조사해서,
        /// 자동으로 Generic Dao (INHRepository{T} 구현 클래스)를 <see cref="IKernel"/>에 Component로 등록한다.
        /// 이렇게 하면, NHRepository{T} 하나만 만들고, 실제 Entity별의 NHRepository는 Castle에 자동으로 등록되고, Instancing될 것이다!!!
        /// (예 NHRepository{Blog}, NHRepository{Customer} 등을 Castle Component로 정의하지 않아도, 이 함수에서 자동으로 조사하여, IoC에 등록시켜 준다는 뜻!!!)
        /// </summary>
        /// <param name="sessionFactory">NHibernate Session Factory</param>
        /// <param name="kernel">Castle.MicroKernel 인스턴스</param>
        /// <param name="repositoryType">INHRepository{T} 를 구현한 Concrete Class Type</param>
        /// <param name="isCandidateForRepository">NHibernate의 매핑된 Entity 중에 IoC Container에 등록할 Type을 선별하는 Predicator</param>
        public static void Register(IKernel kernel,
                                    ISessionFactory sessionFactory,
                                    Type repositoryType,
                                    Predicate <Type> isCandidateForRepository)
        {
            if (IsDebugEnabled)
            {
                log.Debug("NHibernate SessionFactory에 등록된 Entity Class에 대한 " +
                          @"Generic Repository (INHRepository<TEntity>) 의 인스턴스를 생성합니다. repositoryType=[{0}]", repositoryType);
            }

            if (IsImplementsOfGenericNHRepository(repositoryType) == false)
            {
                throw new InvalidOperationException("Repository must be a type inheriting from INHRepository<T>, " +
                                                    "and must be an open generic type. Sample: typeof(NHRepository<>).");
            }

            // GetAllClassMetadata 는 IDictionary<Type, IClassMetadata> 이고 Type은 Mapping된 entity의 Type이다.
            //
            foreach (IClassMetadata meta in sessionFactory.GetAllClassMetadata().Values)
            {
                var mappedClass = meta.GetMappedClass(EntityMode.Poco);
                if (mappedClass == null)
                {
                    continue;
                }

                foreach (Type interfaceType in mappedClass.GetInterfaces())
                {
                    if (isCandidateForRepository(interfaceType))
                    {
                        if (IsDebugEnabled)
                        {
                            log.Debug("Register Generic Repository. INHRepository<{0}>", interfaceType.FullName);
                        }

                        // NOTE : INHRepository<TEnitity> 는 꼭 ConcreteType 속성 (Entity의 Type) 을 가져야한다.
                        //
                        kernel.Register(
                            Component
                            .For(typeof(INHRepository <>).MakeGenericType(interfaceType))
                            .ImplementedBy(repositoryType.MakeGenericType(interfaceType))
                            .DependsOn(Dependency.OnValue("ConcreteType", mappedClass))
                            .OnlyNewServices());
                        //.DependsOn(Property.ForKey("ConcreteType").Eq(mappedClass))
                        //.Unless(Component.ServiceAlreadyRegistered));
                    }
                }
            }
        }
Пример #18
0
        /// <summary>
        /// Build the Breeze metadata as a nested Dictionary.
        /// The result can be converted to JSON and sent to the Breeze client.
        /// </summary>
        /// <returns></returns>
        public IDictionary <string, object> BuildMetadata()
        {
            InitMap();

            // retrieves all mappings with the name property set on the class  (mapping with existing type, no duck typing)
            IDictionary <string, IClassMetadata> classMeta = _sessionFactory.GetAllClassMetadata().Where(p => ((IEntityPersister)p.Value).EntityMetamodel.Type != null).ToDictionary(p => p.Key, p => p.Value);

            //IDictionary<string, ICollectionMetadata> collectionMeta = _sessionFactory.GetAllCollectionMetadata();

            foreach (var meta in classMeta.Values)
            {
                AddClass(meta);
            }
            return(_map);
        }
        static IEnumerable <byte[]> CollectAllIdentifiers(ISession session)
        {
            ISessionFactory sessionFactory = session.SessionFactory;

            IDictionary <string, IClassMetadata> allMetadata = sessionFactory.GetAllClassMetadata();

            foreach (IClassMetadata classMetadata in allMetadata.Values)
            {
                string[] names = classMetadata.PropertyNames;
                IType[]  types = classMetadata.PropertyTypes;

                for (int i = 0; i < names.Length; i++)
                {
                    string name = names[i];
                    IType  type = types[i];

                    if (typeof(ExternalBlobType).IsAssignableFrom(type.GetType()))
                    {
                        ICriteria criteria = CreateCriteria(session, classMetadata, name);

                        foreach (ExternalBlob blob in criteria.List <ExternalBlob>())
                        {
                            yield return(blob.Identifier);
                        }
                    }

                    if (typeof(ExternalClobType).IsAssignableFrom(type.GetType()))
                    {
                        ICriteria criteria = CreateCriteria(session, classMetadata, name);

                        foreach (ExternalClob clob in criteria.List <ExternalClob>())
                        {
                            yield return(clob.Identifier);
                        }
                    }

                    if (typeof(ExternalXlobType).IsAssignableFrom(type.GetType()))
                    {
                        ICriteria criteria = CreateCriteria(session, classMetadata, name);

                        foreach (ExternalXlob xlob in criteria.List <ExternalXlob>())
                        {
                            yield return(xlob.Identifier);
                        }
                    }
                }
            }
        }
Пример #20
0
        public static void ClearSecondLevelCache(ISessionFactory sessionFactory)
        {
            var classMetadata = sessionFactory.GetAllClassMetadata();

            foreach (var ep in classMetadata.Values)
            {
                sessionFactory.EvictEntity(ep.EntityName);
            }

            var collMetadata = sessionFactory.GetAllCollectionMetadata();

            foreach (var acp in collMetadata.Values)
            {
                sessionFactory.EvictCollection(acp.Role);
            }
        }
Пример #21
0
        public ODataSessionFactoryContext(ISessionFactory sessionFactory)
        {
            Require.NotNull(sessionFactory, "sessionFactory");

            /**
             * 01.06.2020: change first parameter from x.GetMappedClass(EntityMode.Poco) to x.MappedClass
             */
            MappedClassMetadata = sessionFactory.GetAllClassMetadata().Values.ToDictionary(
                x => x.MappedClass,
                x => new MappedClassMetadata(x)
                );

            /**
             * 01.06.2020: SessionFactory extended to hold a dictionary with base type (key) and mapped class type (value).
             * The dictionary will be used during building ICriteria if searched type is not mapped, but exists as key in
             * this dictionary. This behavior is required if base controller classes are used and model classes are overwritten in the project
             * and the project models are mapped. If the base model are queried and filtered by name of referenced type, then the
             * OData.nHibernate cannot find the mapping. With the new dictionary the mapping can be found.
             * The "base type to inherited mapping" can only be used, if two or more mapped classes have not the same base type.
             */
            var baseTypeUse = new Dictionary <string, int>();

            foreach (var mappedClass in MappedClassMetadata)
            {
                var baseTypeName = mappedClass.Key.BaseType.FullName;
                if (baseTypeUse.ContainsKey(baseTypeName))
                {
                    baseTypeUse[baseTypeName] += 1;
                }
                else
                {
                    baseTypeUse[baseTypeName] = 1;
                }
            }

            BaseClassToMappedClass = new Dictionary <System.Type, System.Type>();
            foreach (var mappedClass in MappedClassMetadata)
            {
                var baseTypeName = mappedClass.Key.BaseType.FullName;

                if (baseTypeUse[baseTypeName] == 1)
                {
                    BaseClassToMappedClass[mappedClass.Key.BaseType] = mappedClass.Key;
                }
            }
        }
Пример #22
0
 public static List<ExplorerItem> GetSchema(ISessionFactory sessionFactory)
 {
     var items = sessionFactory.GetAllClassMetadata().Values
         .Select(x => new ExplorerItem(x.EntityName, ExplorerItemKind.QueryableObject, ExplorerIcon.Table)
                          {
                              Children = x.PropertyNames.Select(p => GetPropertyItem(x, p)).ToList(),
                              Tag = x.GetMappedClass(EntityMode.Poco)
                          }).ToList();
     foreach (var property in items.SelectMany(x => x.Children))
     {
         var type = (IType)property.Tag;
         var manyToOne = type as ManyToOneType;
         if (manyToOne != null)
             property.HyperlinkTarget = items.Single(x => Equals(x.Tag, type.ReturnedClass));
     }
     return items;
 }
Пример #23
0
        /// <summary>
        /// 지정된 <see cref="ISessionFactory"/> 인스턴스에 등록된 모든 NHibernate용 Entity를 조사해서,
        /// 자동으로 Generic Dao (INHRepository{T} 구현 클래스)를 <see cref="IKernel"/>에 Component로 등록한다.
        /// 이렇게 하면, NHRepository{T} 하나만 만들고, 실제 Entity별의 NHRepository는 Castle에 자동으로 등록되고, Instancing될 것이다!!!
        /// (예 NHRepository{Blog}, NHRepository{Customer} 등을 Castle Component로 정의하지 않아도, 이 함수에서 자동으로 조사하여, IoC에 등록시켜 준다는 뜻!!!)
        /// </summary>
        /// <param name="sessionFactory">NHibernate Session Factory</param>
        /// <param name="kernel">Castle.MicroKernel 인스턴스</param>
        /// <param name="repositoryType">INHRepository{T} 를 구현한 Concrete Class Type</param>
        /// <param name="isCandidateForRepository">NHibernate의 매핑된 Entity 중에 IoC Container에 등록할 Type을 선별하는 Predicator</param>
        public static void Register(IKernel kernel,
                                    ISessionFactory sessionFactory,
                                    Type repositoryType,
                                    Predicate<Type> isCandidateForRepository) {
            if(IsDebugEnabled)
                log.Debug("NHibernate SessionFactory에 등록된 Entity Class에 대한 " +
                          @"Generic Repository (INHRepository<TEntity>) 의 인스턴스를 생성합니다. repositoryType=[{0}]", repositoryType);

            if(IsImplementsOfGenericNHRepository(repositoryType) == false)
                throw new InvalidOperationException("Repository must be a type inheriting from INHRepository<T>, " +
                                                    "and must be an open generic type. Sample: typeof(NHRepository<>).");

            // GetAllClassMetadata 는 IDictionary<Type, IClassMetadata> 이고 Type은 Mapping된 entity의 Type이다.
            //
            foreach(IClassMetadata meta in sessionFactory.GetAllClassMetadata().Values) {
                var mappedClass = meta.GetMappedClass(EntityMode.Poco);
                if(mappedClass == null)
                    continue;

                foreach(Type interfaceType in mappedClass.GetInterfaces()) {
                    if(isCandidateForRepository(interfaceType)) {
                        if(IsDebugEnabled)
                            log.Debug("Register Generic Repository. INHRepository<{0}>", interfaceType.FullName);

                        // NOTE : INHRepository<TEnitity> 는 꼭 ConcreteType 속성 (Entity의 Type) 을 가져야한다.
                        //
                        kernel.Register(
                            Component
                                .For(typeof(INHRepository<>).MakeGenericType(interfaceType))
                                .ImplementedBy(repositoryType.MakeGenericType(interfaceType))
                                .DependsOn(Dependency.OnValue("ConcreteType", mappedClass))
                                .OnlyNewServices());
                        //.DependsOn(Property.ForKey("ConcreteType").Eq(mappedClass))
                        //.Unless(Component.ServiceAlreadyRegistered));
                    }
                }
            }
        }
 public IDictionary <string, IClassMetadata> GetAllClassMetadata() =>
 _inner.GetAllClassMetadata();
Пример #25
0
 public void Probe(ProbeContext context)
 {
     context.Add("persistence", "nhibernate");
     context.Add("entities", _sessionFactory.GetAllClassMetadata().Select(x => x.Value.EntityName).ToArray());
 }
 /// <inheritdoc />
 public IEnumerable <IClassMetadata> GetAll()
 {
     return(_sessionFactory.GetAllClassMetadata().Values);
 }
Пример #27
0
 public IDictionary <string, IClassMetadata> GetAllClassMetadata()
 {
     return(_inner.GetAllClassMetadata());
 }
Пример #28
0
 public IDictionary <string, IClassMetadata> GetAllClassMetadata()
 {
     return(_sessionFactory.GetAllClassMetadata());
 }
 public IEnumerable <IClassMetadata> GetAll()
 {
     return(_fooSessionFactory.GetAllClassMetadata().Values
            .Concat(_barSessionFactory.GetAllClassMetadata().Values));
 }
        /// <summary>
        /// Registers the interfaces of the entities defined in the session factory in the kernel.
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        /// <param name="sessionFactory">The session factory.</param>
        /// <param name="repository">The repository type to map to <seealso cref="IRepository{T}"/>.</param>
        /// <param name="isCandidateForRepository">The is candidate for repository.</param>
        /// <remarks>
        /// The reason that we have the <paramref name="isCandidateForRepository"/> is to avoid registering services
        /// for interfaces that are not related to the domain (INotifyPropertyChanged, as a good example).
        /// </remarks>
        public static void Register(
            IKernel kernel,
            ISessionFactory sessionFactory,
            Type repository,
            IsCandidateForRepositoryDelegate isCandidateForRepository
            )
        {
            if (ImplementsOpenIRepository(repository) == false)
                throw new ArgumentException("Repository must be a type inheriting from IRepository<T>, and must be an open generic type. Sample: typeof(NHRepository<>).");

            foreach (IClassMetadata meta in sessionFactory.GetAllClassMetadata().Values)
            {
                Type mappedClass = meta.GetMappedClass(EntityMode.Poco);
                if (mappedClass == null)
                    continue;
                foreach (Type interfaceType in mappedClass.GetInterfaces())
                {
                    if (isCandidateForRepository(interfaceType, mappedClass) == false)
                        continue;
                    kernel.Register(
                        Component.For(typeof(IRepository<>).MakeGenericType(interfaceType))
                            .ImplementedBy(repository.MakeGenericType(interfaceType))
                            .DependsOn(Property.ForKey("ConcreteType").Eq(mappedClass))
                        );
                }
            }
        }