Example #1
0
        public static void RegisterInstance(StateInstanceId id, object instance)
        {
            lock (Sync)
            {
                if (Instaces.ContainsKey(id))
                {
                    throw new InvalidOperationException($"Instance with {nameof(id)} = '{id}' was already registered.");
                }

                Instaces.Add(id, instance);

                IntPtr staticFieldAddress;
                if (InstanceHolderFieldAddresses.TryGetValue(id, out staticFieldAddress))
                {
                    SetInstanceToStaticFieldAddress(staticFieldAddress, instance);
                }
            }
        }
Example #2
0
        public static void RegisterInstanceHolderFieldAddress(StateInstanceId id, IntPtr instanceHolderFieldAddress)
        {
            lock (Sync)
            {
                if (InstanceHolderFieldAddresses.ContainsKey(id))
                {
                    throw new InvalidOperationException($"Instance holder field address was already added for {nameof(id)} = '{id}'.");
                }
                else
                {
                    InstanceHolderFieldAddresses.Add(id, instanceHolderFieldAddress);

                    object alreadyExistingInstance;
                    if (Instaces.TryGetValue(id, out alreadyExistingInstance))
                    {
                        SetInstanceToStaticFieldAddress(instanceHolderFieldAddress, alreadyExistingInstance);
                    }
                }
            }
        }
Example #3
0
        private static void RegisterInstanceRegisteredEvent(ModuleDefinition module, StateInstanceId instanceId, FieldDefinition instanceHolderField)
        {
            var moduleInitializer = ModuleInitializerProcessor.FindOrCreateInitializer(module);

            Action <StateInstanceId, IntPtr> registerMethod = StateInstancesManager.RegisterInstanceHolderFieldAddress;
            var registerMethodReference = module.Import(registerMethod.Method);

            Func <string, StateInstanceId> deserializeStateIdMethod = StateInstanceId.Deserialize;
            var deserializeStateIdMethodReference = module.Import(deserializeStateIdMethod.Method);

            var newInstructions = new Collection <Instruction>();

            // to IL we save only serialized string of id
            newInstructions.Add(Instruction.Create(OpCodes.Ldstr, instanceId.Serialize()));

            // now we need to deserialize the string and create instance od StateInstanceId
            newInstructions.Add(Instruction.Create(OpCodes.Call, deserializeStateIdMethodReference));

            // here we call registration call with stateInstanceId and field address
            newInstructions.Add(Instruction.Create(OpCodes.Ldsflda, instanceHolderField));
            newInstructions.Add(Instruction.Create(OpCodes.Call, registerMethodReference));

            moduleInitializer.Body.AddInstructionsToBegining(newInstructions);
        }
Example #4
0
        public static FieldDefinition PrepareInstanceHoldingField(ModuleDefinition moduleToExtend, Type fieldType, string fieldName, StateInstanceId instanceRegistrationId)
        {
            var holderType = moduleToExtend.Types.FirstOrDefault(t => t.Name == TypeName && t.Namespace == NamespaceName);

            if (holderType == null)
            {
                holderType = new TypeDefinition(NamespaceName, TypeName, TypeAttributes.AutoClass | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, moduleToExtend.TypeSystem.Object);
                moduleToExtend.Types.Add(holderType);
            }

            var holderField = holderType.Fields.FirstOrDefault(f => f.Name == fieldName);

            if (holderField == null)
            {
                holderField = new FieldDefinition(fieldName, FieldAttributes.Public | FieldAttributes.Static, moduleToExtend.Import(fieldType));
                holderType.Fields.Add(holderField);

                RegisterInstanceRegisteredEvent(moduleToExtend, instanceRegistrationId, holderField);
            }

            return(holderField);
        }