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); }