Пример #1
0
        // Handle factories
        private static Type CreateFactoryType(Type factoryDefType)
        {
            if (factoryDefType.BaseType == typeof(Object) && factoryDefType.GetGenericTypeDefinition() == typeof(ManagementClassFactory <>))
            {
                return(factoryDefType);
            }

            string factoryTypeName = $"Impl_{factoryDefType.Name}";

            if (factoryDefType.BaseType.GetGenericTypeDefinition() != typeof(ManagementClassFactory <>))
            {
                throw new Exception($"'{factoryDefType.Name}' does not immediately inherit from '{typeof(ManagementClassFactory<>).Name}'");
            }

            Type classDefType = factoryDefType.BaseType.GetGenericArguments().First();
            Type classType    = ManagementSession.GetClassType(classDefType);

            string mgmtNamespacePath = ManagementSession.GetNamespacePath(classDefType);
            string mgmtClassName     = ManagementSession.GetClassName(classDefType);

            ManagementClass mgmtClass = new ManagementClass(mgmtNamespacePath, mgmtClassName, null);

            TypeBuilder  factoryType         = ManagementSession.moduleBuilder.DefineType(factoryTypeName, TypeAttributes.Class | TypeAttributes.NotPublic, factoryDefType);
            BindingFlags defaultBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly;

            // Predefined method info
            MethodInfo getManagementObject = classType.GetMethod("get_ManagementObject", BindingFlags.Instance | BindingFlags.Public);
            MethodInfo getManagementBaseObjectProperties = typeof(ManagementBaseObject).GetMethod("get_Properties", BindingFlags.Instance | BindingFlags.Public);
            MethodInfo getPropertyDataCollectionItem     = typeof(PropertyDataCollection).GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public);

            MethodInfo getPropertyDataValue = typeof(PropertyData).GetMethod("get_Value", BindingFlags.Instance | BindingFlags.Public);
            MethodInfo setPropertyDataValue = typeof(PropertyData).GetMethod("set_Value", BindingFlags.Instance | BindingFlags.Public);

            MethodInfo convertToDateTime   = typeof(ManagementDateTimeConverter).GetMethod("ToDateTime", BindingFlags.Static | BindingFlags.Public);
            MethodInfo convertFromDateTime = typeof(ManagementDateTimeConverter).GetMethod("ToDmtfDateTime", BindingFlags.Static | BindingFlags.Public);

            IEnumerable <MethodInfo> methodsToImplement = factoryDefType.GetMethods(defaultBindingFlags).Where(m => m.IsAbstract);

            foreach (MethodInfo methodInfo in methodsToImplement)
            {
                if (methodInfo.Name != "CreateInstance")
                {
                    throw new Exception($"Unable to implement method '{methodInfo.Name}'. Name is not CreateInstance");
                }

                ParameterInfo[] paramInfos = methodInfo.GetParameters();

                MethodBuilder methodBuilder = factoryType.DefineMethod("CreateInstance", MethodAttributes.Public | MethodAttributes.Virtual, classDefType, paramInfos.Select(p => p.ParameterType).ToArray());
                ILGenerator   il            = methodBuilder.GetILGenerator();

                LocalBuilder managementClass = il.DeclareLocal(typeof(ManagementClass));

                // managementClass = new ManagementClass(mgmtNamespacePath, mgmtClassName, null)
                il.Emit(OpCodes.Ldstr, mgmtNamespacePath);
                il.Emit(OpCodes.Ldstr, mgmtClassName);
                il.Emit(OpCodes.Ldnull);
                il.Emit(OpCodes.Newobj, typeof(ManagementClass).GetConstructor(new[] { typeof(String), typeof(String), typeof(ObjectGetOptions) }));
                il.Emit(OpCodes.Stloc_S, managementClass);

                for (int paramIndex = 0; paramIndex < paramInfos.Length; paramIndex++)
                {
                    ParameterInfo paramInfo = paramInfos[paramIndex];

                    ManagementPropertyAttribute paramAttribute = paramInfo.GetCustomAttribute(typeof(ManagementPropertyAttribute)) as ManagementPropertyAttribute;

                    string realParamPropertyName = paramAttribute?.Name ?? paramInfo.Name;
                    Type   realParamPropertyType = paramAttribute?.CastAs ?? paramInfo.ParameterType;

                    if (mgmtClass.Properties[realParamPropertyName] == null)
                    {
                        throw new ArgumentException($"'{mgmtNamespacePath}:{mgmtClassName}' does not have key '{realParamPropertyName}'");
                    }

                    // Get property - will always exist, checked above
                    il.Emit(OpCodes.Ldloc_S, managementClass);
                    il.Emit(OpCodes.Callvirt, getManagementBaseObjectProperties);
                    il.Emit(OpCodes.Ldstr, realParamPropertyName);
                    il.Emit(OpCodes.Callvirt, getPropertyDataCollectionItem);

                    // Get argument, ldarg.0 = this
                    il.Emit(OpCodes.Ldarg_S, paramIndex + 1);

                    if (paramInfo.ParameterType == typeof(DateTime))
                    {
                        // Convert to DMTF DateTime
                        il.Emit(OpCodes.Call, convertFromDateTime);
                    }
                    else if (realParamPropertyType != paramInfo.ParameterType)
                    {
                        if (!paramInfo.ParameterType.IsValueType)
                        {
                            // TODO: Get converter
                        }
                    }

                    if (realParamPropertyType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, realParamPropertyType);
                    }

                    // Set property value
                    il.Emit(OpCodes.Callvirt, setPropertyDataValue);
                }

                // managementObject = managementClass.CreateInstance()
                il.Emit(OpCodes.Ldloc_S, managementClass);
                il.Emit(OpCodes.Call, typeof(ManagementClass).GetMethod("CreateInstance", BindingFlags.Instance | BindingFlags.Public));

                // [classDefType] instance = new [classType](managementObject)
                il.Emit(OpCodes.Newobj, classType.GetConstructor(new[] { typeof(ManagementBaseObject) }));

                // return instance
                il.Emit(OpCodes.Ret);
            }

            return(factoryType.CreateType());
        }
Пример #2
0
 public T CreateInstance(ManagementBaseObject managementObject) => (T)Activator.CreateInstance(ManagementSession.GetClassType(typeof(T)), managementObject);
Пример #3
0
 public static Type GetClassType <T>() where T : ManagementClassBase => ManagementSession.GetClassType(typeof(T));