Instead of using the Trigger class abstract based isMet() method, make virtual , perhaps the default value is false. You can then override method in derived classes using the override keyword.
The second problem is related to the serialization and deserialization of triggers in the database. When you deserialize, you want to make sure that you are returning a derived trigger type, not the base. I donβt know how you chose to serialize your objects into a database, but you need a way to save this type. Take a DataContractSerializer , for example. As the first parameter, it takes Type . If you store typeof (DerivedTrigger) in a different field in your database when triggers are serialized, you can deserialize the type and use it to deserialize the trigger to the correct derived type. Then calling your isMet() method should call the derived override value. The following is a brief example of using static variables instead of a database:
[DataContract] partial class Trigger { public virtual bool isMet() { return false; } } [DataContract] class DerivedTrigger : Trigger { public object DataElement1 { get; set; } //and other properties to serialize. public override bool isMet() { return true; } } void Main() { DerivedTrigger t = new DerivedTrigger(); Serialize(t); ((Trigger)Deserialize()).isMet(); // returns True! } public static void Serialize<T>(T source) { MemoryStream ms = new MemoryStream(); Type serializedObjectType = typeof(T); DataContractSerializer dcsObject = new DataContractSerializer(serializedObjectType, null, int.MaxValue, false, true, null); dcsObject.WriteObject(ms, source); //serialize the object byte[] buffer = new byte[1024] //TODO: adjust size ms.Position = 0; ms.Read(buffer, 0, 1024); //TODO: write buffer to database colObject here ms.Position = 0; DataContractSerializer dcsType = new DataContractSerializer(typeof(Type), null, int.MaxValue, false, true, null); dcsType.WriteObject(ms, serializedObjectType.DeclaringType); buffer = new byte[1024] ms.Position = 0; ms.Read(buffer, 0, 1024); //TODO: write buffer to database colType here } public static object Deserialize() { MemoryStream ms = new MemoryStream(); byte[] buffer = new byte[1024]; //TODO: read colType into buffer here ms.Write(buffer, 0 1024); ms.Position = 0; DataContractSerializer dcsType = new DataContractSerializer(typeof(Type), null, int.MaxValue, false, true, null); Type serializedObjectType = dcs.Read(ms); //TODO: read colObject into buffer here DataContractSerializer dcs = new DataContractSerializer(serializedObjectType, null, int.MaxValue, false, true, null); return dcs.ReadObject(serializedObject); }
EDIT
Well, using a MemoryStream seems to have confused the situation. MemoryStream is not what is stored in the database, it is a database.
The whole reason for having serializedObjectType is because, as you say, using typeof(Trigger) for a type in a DataContractSerializer will not deserialize objects that are actually derived triggers. Therefore, you need to save the derived type with the object in the database.
You did not say which dbms you are using, but I would use blob to represent the Trigger column and either varbinary or blob to represent the serializedObjectType column, i.e. the actual most derived Trigger type. Serialize the type using a solid-state type encoder. those. DataContractSerializer(typeof(Type), ...) and serialize the object using DataContractSerializer(typeof(T), ...) , where T is the derived trigger type that you can get with a generic variable.
When deserializing, do this in reverse order. First, we deserialize the type using the solid-state type serializer. those. DataContractSerializer(typeof(Type), ...) , and then deserialize the object with the results of the deserialized type. I updated my code snippets, I hope it is better to illustrate your strategy. Sorry for the delay in my reply.
EDIT 2
Typically, when you talk about serialization, you only serialize the values ββin the object, since this is what separates one object from another. You do not need to serialize the method body in the database, since it is stored in assemblies in the file system (pluggable DLL files that you specify in your question). Downloading these DLLs is a separate step. take a look at System.Reflection.Assembly.LoadFile() .
Of these two statements in your question:
The trigger and action must be stored in the database.
and
... the user must discard their own trigger classes as DLLs in the specified folder.
I assumed (possibly incorrectly) that the definition for the class will be stored in fs, and the data that goes into each class object will be stored in the database. If your derived isMet() methods are static (perhaps not explicitly, but do not have any associated state), then nothing will be stored in the database. However, it looks like you are setting it up so that Trigger stores the Actions collection. In this case, those Actions are what are serialized in the database. Just mark them public if your class is Serializable , or mark the collection directly as Serializable . Then the size of the memory stream will be proportional to the number of Actions each trigger. Clean like dirt?