public static void EntitiesContextInitialization <T>() where T : EntitiesContext { if (_contexts.Value.FirstOrDefault(c => c.Name == (typeof(T).Name)).IsNull()) { string sessionid = MVCEngine.Tools.Session.Session.CreateUserSession(typeof(T).Name); Task task = new Task(() => { Dictionary <MVCEngine.Model.Internal.Descriptions.DynamicProperties, string[]> dynamicList = new Dictionary <MVCEngine.Model.Internal.Descriptions.DynamicProperties, string[]>(); Context ctx = new Context() { Name = typeof(T).Name, Entites = new List <EntityClass>() }; _contexts.Value.Add(ctx); _entitiesCollection.Value.Add(ctx.Name, new Dictionary <string, Func <object, object> >()); typeof(T).GetFields().Where(f => f.FieldType.Name == "EntitiesCollection`1" && f.IsPublic). ToList().ForEach((f) => { List <string> realTimeValidator = new List <string>(); PropertyInfo ctxInfo = f.FieldType.GetProperty("Context"); Type entityType = f.FieldType.GetGenericArguments().First <Type>(); Debug.Assert(typeof(Entity).IsAssignableFrom(entityType), "Entity[" + entityType.FullName + "] it cann't be recognise as valid entity."); if (typeof(Entity).IsAssignableFrom(entityType)) { if (!_entites.Value.ContainsKey(entityType.FullName)) { EntityClass entityClass = new EntityClass(); Debug.Assert(!ctx.Entites.Exists((t) => { return(t.Name == entityType.Name); }), "Entity[" + entityType.Name + "] is defined twice."); if (!ctx.Entites.Exists((t) => { return(t.Name == entityType.Name); })) { entityClass.Name = entityType.Name; entityClass.EntityType = entityType; entityClass.Attributes.AddRange(Attribute.GetCustomAttributes(entityType)); _entitiesCollection.Value[ctx.Name].Add(entityType.Name, LambdaTools.FieldGetter(typeof(T), f)); var propertyquery = entityType.GetProperties().Where(p => p.CanRead && p.GetGetMethod().IsVirtual); propertyquery.ToList().ForEach((p) => { EntityProperty property = new EntityProperty() { Name = p.Name, PropertyType = p.PropertyType, PropertyInfo = p, Setter = p.CanWrite ? LambdaTools.PropertySetter(entityType, p) : null, Getter = LambdaTools.PropertyGetter(entityType, p) }; property.Attibutes.AddRange(Attribute.GetCustomAttributes(p)); entityClass.Properties.Add(property); if (typeof(Entity).IsAssignableFrom(p.PropertyType)) { property.ReletedEntity = new ReletedEntity() { Related = Releted.Entity, RelatedEntityName = p.PropertyType.Name }; } else if (p.PropertyType.Name == "EntitiesCollection`1") { property.ReletedEntity = new ReletedEntity() { Related = Releted.List, RelatedEntityName = p.PropertyType.GetGenericArguments().First <Type>().Name }; } Attribute.GetCustomAttributes(p).ToList().ForEach((a) => { Relation relation = null; Discriminator discriminator = null; PropertyValidator validator = null; DefaultValue defaultValue = null; Synchronized synchronized = null; Formatter formatter = null; NotIntercept notIntercept = null; Intercept intercept = null; attribute.DynamicProperties dynamicProperties = null; if (a.IsTypeOf <PrimaryKey>()) { Debug.Assert(entityClass.Properties.FirstOrDefault(primary => primary.PrimaryKey).IsNull(), "Entity[" + entityType.Name + "] at least two primary key property defined"); property.PrimaryKey = true; entityClass.PrimaryKeyProperty = property; entityClass.PrimaryKey = property.Getter; } else if ((relation = a.CastToType <Relation>()).IsNotNull()) { EntitiesRelation r = ctx.Relations.FirstOrDefault(re => re.Name == relation.RelationName); Debug.Assert(r.IsNull(), "Relation[" + relation.RelationName + "] is declared at least twice"); if (property.ReletedEntity.IsNotNull()) { EntitiesRelation entityrelation = new EntitiesRelation() { Name = relation.RelationName, Parent = new EntityRelated() { EntityName = relation.ParentEntity, Key = relation.ParentProperty }, Child = new EntityRelated() { EntityName = relation.ChildEntity, Key = relation.ChildProperty }, OnDelete = relation.OnDelete, OnAccept = relation.OnAccept, OnFreeze = relation.OnFreeze }; ctx.Relations.Add(entityrelation); property.ReletedEntity.Relation = entityrelation; } } else if ((synchronized = a.CastToType <Synchronized>()).IsNotNull()) { if (property.ReletedEntity.IsNotNull()) { property.ReletedEntity.Synchronized = true; } } else if ((discriminator = a.CastToType <Discriminator>()).IsNotNull()) { if (property.ReletedEntity.IsNotNull()) { property.ReletedEntity.Discriminators.Add(discriminator); } } else if ((validator = a.CastToType <PropertyValidator>()).IsNotNull()) { property.Validators.Add(validator); } else if ((defaultValue = a.CastToType <DefaultValue>()).IsNotNull()) { property.DefaultValue = defaultValue; } else if ((dynamicProperties = a.CastToType <attribute.DynamicProperties>()).IsNotNull()) { if (property.ReletedEntity.IsNotNull() && property.ReletedEntity.Related == Releted.List) { entityClass.DynamicProperties = new Internal.Descriptions.DynamicProperties() { CodeProperty = dynamicProperties.CodeProperty, Property = property, }; dynamicList.Add(entityClass.DynamicProperties, dynamicProperties.ValueProperties); } } else if ((formatter = a.CastToType <Formatter>()).IsNotNull()) { property.AddFormatter(formatter); } else if ((notIntercept = a.CastToType <NotIntercept>()).IsNotNull()) { if (notIntercept.InterceptorId.IsNullOrEmpty()) { property.RemoveGetInterceptor(string.Empty); property.RemoveSetInterceptor(string.Empty); } else { if (notIntercept.Method == Method.Get) { property.RemoveGetInterceptor(notIntercept.InterceptorId); } else { property.RemoveSetInterceptor(notIntercept.InterceptorId); } } } else if ((intercept = a.CastToType <Intercept>()).IsNotNull() && intercept.Method.IsNotNull()) { if (intercept.Method.Contains(Method.Get)) { property.AddGetInterceptor(intercept.InterceptorId); } if (intercept.Method.Contains(Method.Set)) { property.AddSetInterceptor(intercept.InterceptorId); } } }); }); Attribute.GetCustomAttributes(entityType).ToList().ForEach((a) => { EntityValidator validator = null; if ((validator = a.CastToType <EntityValidator>()).IsNotNull()) { entityClass.Validators.Add(validator); } }); ctx.Entites.Add(entityClass); } _entites.Value.Add(entityType.FullName, entityClass); } else { ctx.Entites.Add(_entites.Value[entityType.FullName]); } } }); ctx.Relations.ForEach((r) => { EntityClass entity = ctx.Entites.FirstOrDefault(e => e.Name == r.Parent.EntityName); Debug.Assert(entity.IsNotNull(), "Relation[" + r.Name + "] parent entity not found"); r.Parent.Entity = entity; EntityProperty property = entity.Properties.FirstOrDefault(p => p.Name == r.Parent.Key); Debug.Assert(property.IsNotNull(), "Entity[" + entity.Name + "] property[" + r.Parent.Key + "] not defined"); r.Parent.Type = property.PropertyType; r.Parent.Value = property.Getter; EntityClass childEntity = ctx.Entites.FirstOrDefault(e => e.Name == r.Child.EntityName); Debug.Assert(childEntity.IsNotNull(), "Relation[" + r.Name + "] child entity not found"); r.Child.Entity = childEntity; EntityProperty childProperty = childEntity.Properties.FirstOrDefault(p => p.Name == r.Child.Key); Debug.Assert(childProperty.IsNotNull(), "Entity[" + childEntity.Name + "] property[" + r.Child.Key + "] not defined"); r.Child.Type = childProperty.PropertyType; r.Child.Value = childProperty.Getter; }); var reletedquery = ctx.Entites.Where(e => e.Properties.Count(p => p.ReletedEntity.IsNotNull()) > 0). SelectMany(e => e.Properties.Where(p => p.ReletedEntity.IsNotNull()), (e, p) => new { Entity = e, Property = p }); reletedquery.ToList().ForEach((ep) => { EntityClass entityClass = ctx.Entites.FirstOrDefault(e => e.Name == ep.Property.ReletedEntity.RelatedEntityName); Debug.Assert(entityClass.IsNotNull(), "Entity[" + ep.Property.ReletedEntity.RelatedEntityName + "] dosen't have collection"); ep.Property.ReletedEntity.RelatedEntity = entityClass; if (ep.Property.ReletedEntity.Relation.IsNull()) { if (!ep.Property.ReletedEntity.RelationName.IsNullOrEmpty()) { EntitiesRelation relation = ctx.Relations.FirstOrDefault(r => r.Name == ep.Property.ReletedEntity.RelationName); Debug.Assert(relation.IsNotNull(), "Relation[" + ep.Property.ReletedEntity.RelationName + "] not defined"); ep.Property.ReletedEntity.Relation = relation; } else { List <EntitiesRelation> relations = null; if (ep.Property.ReletedEntity.Related == Releted.Entity) { relations = ctx.Relations.Where(r => r.Parent.EntityName == ep.Property.ReletedEntity.RelatedEntityName && r.Child.EntityName == ep.Entity.Name).ToList(); } else { relations = ctx.Relations.Where(r => r.Parent.EntityName == ep.Entity.Name && r.Child.EntityName == ep.Property.ReletedEntity.RelatedEntityName).ToList(); } Debug.Assert(relations.Count() < 2, "Relation[" + ep.Property.ReletedEntity.RelatedEntityName + "-" + ep.Entity.Name + "] more then one"); if (relations.Count() == 1) { ep.Property.ReletedEntity.Relation = relations[0]; } } } if (ep.Property.ReletedEntity.Synchronized) { ep.Property.ReletedEntity.RelatedEntity.Synchronized(ep.Entity.Name, ep.Property.Name); } if (ep.Property.ReletedEntity.Related == Releted.List) { ep.Property.AddGetInterceptor(CollectionInterceptorDispatcher.GetId(ep.Property.ReletedEntity.Relation.Child.Entity.EntityType)); } else { ep.Property.AddGetInterceptor(EntityInterceptorDispatcher.GetId(ep.Property.ReletedEntity.RelatedEntityName)); } }); foreach (MVCEngine.Model.Internal.Descriptions.DynamicProperties dynamicProperty in dynamicList.Keys) { foreach (string p in dynamicList[dynamicProperty]) { EntityProperty property = dynamicProperty.Property.ReletedEntity.RelatedEntity.Properties.FirstOrDefault(pr => pr.Name == p); if (property.IsNotNull()) { dynamicProperty.ValuesProperties.Add(property.PropertyType, property.Name); } } } }); task.ContinueWith((antecedent) => { MVCEngine.Tools.Session.Session.ReleaseSession(sessionid); }); task.ContinueWith((antecedent) => { if (_contexts.IsValueCreated) { _contexts.Value.Clear(); } //ToDo log exception into log file }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted); MVCEngine.Tools.Session.Session.SetSessionData(sessionid, "InitializeTask", task); task.Start(); } }