using System; using System.Collections.Generic; using System.Linq; namespace ln.http.rest { public delegate void CRUDEvent(CRUDObjectContainer sender, CRUDEventArgs args); public enum CRUDEventType { CREATE, READ, UPDATE, DELETE } public class CRUDEventArgs : EventArgs { public CRUDEventType EventType { get; } public Type ObjectType { get; } public object ObjectIdentity { get; } public object ObjectInstance { get; } public FieldValueList FieldValues { get; } public CRUDEventArgs(CRUDEventType eventType, Type objectType, object objectIdentity, object objectInstance, FieldValueList fieldValues) { EventType = eventType; ObjectType = objectType; ObjectIdentity = objectIdentity; ObjectInstance = objectInstance; FieldValues = fieldValues; } } public abstract partial class CRUDObjectContainer { public event CRUDEvent OnCRUDEvent; Dictionary registeredTypes = new Dictionary(); public CRUDObjectContainer() { } public abstract bool TryGetObjectIdentifier(object objectInstance, out object objectIdentifier); public abstract bool TryCreateObject(Type objectType, FieldValueList fieldValues, out object objectInstance); public abstract bool TryLookupObject(Type objectType, object objectIdentifier, out object objectInstance); public abstract bool TryUpdateObject(Type objectType, object objectIdentifier, FieldValueList fieldValues); public abstract bool TryDeleteObject(Type objectType, object objectIdentifier); public virtual bool TryUpdateObject(object objectInstance, FieldValueList fieldValues) { if (TryGetObjectIdentifier(objectInstance, out object objectIdentifier)) return TryUpdateObject(objectInstance.GetType(), objectIdentifier, fieldValues); return false; } public virtual bool TryDeleteObject(object objectInstance) { if (TryGetObjectIdentifier(objectInstance, out object objectIdentifier)) return TryDeleteObject(objectInstance.GetType(), objectIdentifier); return false; } protected void FireCRUDEvent(CRUDEventArgs args) => OnCRUDEvent?.Invoke(this, args); protected void FireCRUDEVent(CRUDEventType EventType, Type ObjectType, object ObjectIdentity, object ObjectInstance, FieldValueList FieldValues) => FireCRUDEvent(new CRUDEventArgs(EventType, ObjectType, ObjectIdentity, ObjectInstance, FieldValues)); public virtual IEnumerable RegisteredTypes => registeredTypes.Keys; public virtual bool ContainsRegisteredType(Type objectType) => registeredTypes.ContainsKey(objectType); public virtual bool TryRegisterType(Type objectType) => TryRegisterType(objectType, null); public virtual bool TryRegisterType(Type objectType, Func idGetter) { if (ContainsRegisteredType(objectType)) throw new ArgumentException("objectType already registered", nameof(objectType)); RegisteredType registeredType = new RegisteredType(this, objectType, idGetter); registeredTypes.Add(objectType, registeredType); return true; } public virtual bool TryGetFieldDescriptors(Type objectType, out FieldDescriptor[] fieldDescriptors) { if (registeredTypes.TryGetValue(objectType, out RegisteredType registeredType)) { fieldDescriptors = registeredType.FieldDescriptors.ToArray(); return true; } fieldDescriptors = null; return false; } public virtual IEnumerable EnumerateObjectInstances(Type objectType) => EnumerateObjectInstances(objectType, null); public abstract IEnumerable EnumerateObjectInstances(Type objectType, FieldValueList conditionalFieldValues); public abstract bool AddForeignObjectInstance(object objectInstance); } }