I am using Mono.Cecil to automatically generate (lots of, simple, generic) factory methods providing a convenient API for a library. The factories are generated for properties marked with a special custom attribute. To generate them, I must know the type of such property. The non-generic case is simple:
ModuleDefinition module = /* obtained from ReadAssembly */
foreach (var type in module.Types)
if (/* type is marked with the right attribute */)
foreach (var prop in type.Properties)
if (/* prop is marked with the right attribute */)
GenerateFactory(type, prop, prop.PropertyType);
However, some of the types marked are in fact generics. In this case, the attribute on the type contains the generic arguments for which the factory should be made, like this:
[EmitFactories(typeof(int))]
public class Class<T>
{
[MagicProperty]
T Property { get; set; }
}
(here, I want the factory to be made for Class<int>.Property
).
I am handling this case by making type
a GenericInstanceType
. However, I cannot get to the type of the property -- to enumerate type.Properties
I need to first call Resolve()
, which loses all generic information. The property type is then T
(instead of int
), which of course makes later code fail miserably.
Mono.Cecil has GenericInstanceType
and GenericInstanceMethod
, but there is no equivalent for properties. I tried using module.Import(prop.PropertyType, type)
(giving type
as the generic parameter provider), but this doesn't work.
Do you have any ideas on how I can resolve the actual property type? Note, that it can be completely unrelated to T
, T
itself, or have T
burried inside (e.g., List<T>
). Ideally, it would work given type
as a TypeReference
-- this way I would not have to write separate code for the non-generic and generic cases.