List<TypeDefinition> types = new
List<TypeDefinition>(assembly.MainModule.Types);
        foreach (TypeDefinition typeDef in types)
        {
            TypeDefinition innerType = null;
            MethodDefinition innerTypeCctor = null;

            var methods = new List<MethodDefinition>(typeDef.Methods);
            foreach (MethodDefinition method in methods)
            {
                if(method.HasBody)
                {
                    foreach(var attr in
method.CustomAttributes.Where(o =>
m_types.Keys.Contains(o.AttributeType.Resolve())))
                    {
                        if(innerType == null)
                        {
                            innerType = new
TypeDefinition(typeDef.Namespace, "<>_Utils",
TypeAttributes.NestedPrivate | TypeAttributes.Sealed |
TypeAttributes.Class);
                            innerTypeCctor = new
MethodDefinition(".cctor", MethodAttributes.SpecialName |
MethodAttributes.RTSpecialName | MethodAttributes.HideBySig |
MethodAttributes.Static, method.Module.GetVoidType());
 
innerTypeCctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                            innerType.Methods.Add(innerTypeCctor);
                            typeDef.NestedTypes.Add(innerType);
                        }

 
attr.EmitAttributeInitialization(innerTypeCctor);
                   }
  ....
} } }

and EmitAttributeInitialization:

        public static void EmitAttributeInitialization(this
CustomAttribute attribute, MethodDefinition m0)
        {
            var module  = m0.Module;
            var declaring  = m0.DeclaringType;
            var emitter = m0.Body.GetILProcessor();
            var _Attribute = attribute.AttributeType;

            var __attrContainer =
declaring.AddField(Utils.GetFieldName(declaring,
attribute.AttributeType.Name),
 
FieldAttributes.Static | FieldAttributes.Private,
 
_Attribute.Resolve());

            var ins = m0.Body.Instructions[0];

            var ctor = module.Import((MethodDefinition)(from f in
_Attribute.Resolve().Methods
                                                        where
f.IsConstructor && f.IsPublic select f).FirstOrDefault());

            if(ctor == null) return;

            emitter.InsertBefore(ins, emitter.Create(OpCodes.Newobj,
ctor.GetElementMethod()));
            emitter.InsertBefore(ins, emitter.Create(OpCodes.Stsfld,
__attrContainer));

     ...
    }

Second method creates wrong filed definition in resulting assembly.
Definition of the field to be created must be of type _Attribute, but
the real type - the type of nested type, which contains the definition
of the field. Whats wrong?

-- 
--
mono-cecil

Reply via email to