public ModelAttributesInfo(Type modelType) { QueryAuthAttributes = GetAuthAttributesOfClassOrDirectTopClass <QueryAuthAttribute>(modelType); QueryEntryAuthAttributes = GetAuthAttributesOfClassOrDirectTopClass <QueryEntryAuthAttribute>(modelType); UpdateAuthAttributes = GetAuthAttributesOfClassOrDirectTopClass <UpdateAuthAttribute>(modelType); RemoveAuthAttributes = GetAuthAttributesOfClassOrDirectTopClass <RemoveAuthAttribute>(modelType); CreateAuthAttributes = GetAuthAttributesOfClassOrDirectTopClass <CreateAuthAttribute>(modelType); CreateEventAttributes = GetHookAttributeOfClassAndTopClasses <CreateEventAttribute>(modelType); UpdateEventAttributes = GetHookAttributeOfClassAndTopClasses <UpdateEventAttribute>(modelType); RemoveEventAttributes = GetHookAttributeOfClassAndTopClasses <RemoveEventAttribute>(modelType); QueryFunctionAttribute = modelType.GetCustomAttribute <QueryFunctionAttribute>(false); QueryFunctionAttribute?.Compile(modelType); UpdatableAttribute = modelType.GetCustomAttribute <UpdatableAttribute>(false); }
public void HandleCollections(ConnectionBase connection, string contextName, Type dbContextType, List <ChangeResponse> changes, IServiceProvider requestServiceProvider) { IEnumerable <IGrouping <string, CollectionSubscription> > subscriptionGroupings = connection.Subscriptions .Where(s => s.ContextName == contextName) .GroupBy(s => s.CollectionName); foreach (IGrouping <string, CollectionSubscription> subscriptionGrouping in subscriptionGroupings) { KeyValuePair <Type, string> property = dbContextType.GetDbSetType(subscriptionGrouping.Key); List <ChangeResponse> changesForCollection = changes .Where(c => c.CollectionName == subscriptionGrouping.Key) .ToList(); AuthModelInfo modelInfo = property.Key.GetAuthModelInfos(); IEnumerable <ChangeResponse> authenticatedChanges = changesForCollection; if (modelInfo.QueryEntryAuthAttributes.Any()) { authenticatedChanges = changesForCollection .Where(change => change.State == ChangeResponse.ChangeState.Deleted || property.Key.CanQueryEntry(connection.Information, requestServiceProvider, change.Value)); IEnumerable <ChangeResponse> oldLoadedNotAllowed = changesForCollection .Where(change => change.State == ChangeResponse.ChangeState.Modified && !property.Key.CanQueryEntry(connection.Information, requestServiceProvider, change.Value)) .Select(change => { ChangeResponse newChangeResponse = change.CreateResponse(null, change.Value); newChangeResponse.State = ChangeResponse.ChangeState.Deleted; return(newChangeResponse); }); authenticatedChanges = authenticatedChanges.Concat(oldLoadedNotAllowed); } List <ChangeResponse> collectionChanges = authenticatedChanges.ToList(); if (collectionChanges.Any()) { QueryFunctionAttribute queryFunctionAttribute = property.Key.GetCustomAttribute <QueryFunctionAttribute>(false); if (queryFunctionAttribute != null) { var queryFunctionInfo = property.Key.GetMethod(queryFunctionAttribute.Function, BindingFlags.Default | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (queryFunctionInfo != null) { object[] methodParameters = queryFunctionInfo.CreateParameters(connection.Information, serviceProvider); dynamic queryFunctionExpression = ((dynamic)queryFunctionInfo.Invoke(null, methodParameters)).Compile(); collectionChanges = collectionChanges.Where(change => queryFunctionExpression(change.Value)) .ToList(); } } } foreach (CollectionSubscription subscription in subscriptionGrouping) { Task.Run(() => { HandleSubscription(subscription, dbContextType, requestServiceProvider, connection, property, collectionChanges, changes); }); } } }