static object CreateProxy(Type entityType, ClassDefineMetadata metadata)
        {
            Func <IInterceptor[], object> func;

            if (!(factoryCache.TryGetValue(entityType, out func)))
            {
                lock (factoryCache)
                {
                    if (!(factoryCache.TryGetValue(entityType, out func)))
                    {
                        ProxyGenerationOptions options = new ProxyGenerationOptions(new InnerHook(metadata));
                        var proxyType    = generator.ProxyBuilder.CreateClassProxyType(entityType, new Type[0], options);
                        var construncor  = proxyType.GetConstructor(new Type[] { typeof(IInterceptor[]) });
                        var interceptors = Expression.Parameter(typeof(IInterceptor[]), "interceptors");
                        var main         = Expression.Convert(Expression.New(construncor, interceptors), typeof(object));

                        func = Expression.Lambda <Func <IInterceptor[], object> >(main, interceptors).Compile();
                        factoryCache[entityType] = func;
                    }
                }
            }
            var ei    = new EntityInterceptor(metadata);
            var proxy = func(new IInterceptor[] { ei });

            ei.Inited = true;
            return(proxy);
        }
        public object Proxy(object entity, Func <object, object> subProxyHandler)
        {
            var metadata = RepositoryFramework.GetDefineMetadata(entity.GetType());

            var proxy   = entity;
            var proxyed = false;

            if (!ProxyProvider.IsProxy(entity) && metadata.ClassJoinDefines.Count > 0)
            {
                proxy = ProxyProvider.CreateEntityProxy(metadata.EntityType);
                metadata.MergeData(entity, proxy);
                proxyed = true;
            }

            var pa = PropertyAccessorFactory.GetPropertyAccess(metadata.EntityType);

            foreach (var property in metadata.CascadeProperties)
            {
                if (EntityInterceptor.PropertyInited(entity, property.Name))
                {
                    var value = pa.GetGetter(property.Name).Get(entity);
                    if (value != null)
                    {
                        var valueProxy = subProxyHandler(value);
                        if (valueProxy != value || proxyed)
                        {
                            pa.GetSetter(property.Name).Set(proxy, valueProxy);
                        }
                    }
                }
            }

            return(proxy);
        }
        public static bool PropertyInited(object entity, string member)
        {
            var proxy = entity as IProxyTargetAccessor;

            if (proxy != null)
            {
                EntityInterceptor ei = (EntityInterceptor)proxy.GetInterceptors().FirstOrDefault(o => o.GetType() == typeof(EntityInterceptor));
                if (ei != null)
                {
                    return(ei.PropertyInited(member));
                }
            }
            return(true);
        }