From 78a90ba98d6e902e6b8ddb4f773ee444669e6032 Mon Sep 17 00:00:00 2001 From: Gerald Lochner Date: Fri, 29 Apr 2016 11:50:50 +0200 Subject: [PATCH 1/5] Ignore generated file --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index d6cdbc8e..cf1ae05e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,7 @@ Makefile.in /configure /install-sh /missing +.suo +/*.suo +/Test/ +/packages/ From c07cecdf92586e4cb7f368f9c0d8139af681e3ec Mon Sep 17 00:00:00 2001 From: Copa-Data Date: Tue, 12 Jul 2016 14:57:31 +0200 Subject: [PATCH 2/5] Type Extension Points didn't work correctly, when using CustomExtensionAttribute. Using CustomExtensionAttribute on several TypeExtensionNodes didn't assign extension nodes to the correct extension points. Therefore, calling AddInEngine.GetExtensionNodes(typeof(IAnyInterface)) also returned extension nodes of another interface. Equivalent to ExtensionAttribute, CustomExtensionAttribute with property Type now. CustomAttribute with a list of nodes and properties (@IAssemblyReflector.cs) Reflector.cs/DefaultAssemblyReflector.cs now returns a list of properties and a list of nodes. Properties are needed to get value of property Type. AddinScanner now checks property Type of CustomExtensionAttribute, otherwise (equivalent to ExtensionAttribute) the base types are analyzed and used as path. --- .../Mono.Addins.CecilReflector/Reflector.cs | 20 ++++++++-- .../Mono.Addins.Database/AddinScanner.cs | 40 +++++++++++++++---- .../DefaultAssemblyReflector.cs | 13 +++--- .../IAssemblyReflector.cs | 38 +++++++++++++----- .../Mono.Addins/CustomExtensionAttribute.cs | 32 +++++++++++---- 5 files changed, 108 insertions(+), 35 deletions(-) diff --git a/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs b/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs index b22c4a6e..f94ade1c 100644 --- a/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs +++ b/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs @@ -206,7 +206,7 @@ MA.CustomAttribute ConvertToRawAttribute (CustomAttribute att, string expectedTy NodeAttributeAttribute bat = (NodeAttributeAttribute) GetCustomAttribute (par, typeof(NodeAttributeAttribute), false); if (bat != null) name = bat.Name; - mat.Add (name, Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture)); + mat.NodeDictionary.Add (name, Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture)); } } } @@ -217,6 +217,20 @@ MA.CustomAttribute ConvertToRawAttribute (CustomAttribute att, string expectedTy if (val == null) continue; + if (val is TypeReference) + { + var typeRef = (TypeReference) val; + var typeDef = typeRef.Resolve(); + if (typeDef == null) + throw new InvalidOperationException(string.Format("Cannot resolve assembly '{0}'", typeDef.Module.Assembly.FullName)); + + val = Type.GetType(typeDef.FullName + ", " + typeDef.Module.Assembly.FullName, false); + if (val == null) + throw new InvalidOperationException(string.Format("Cannot resolve type '{0}' at assembly '{1}'", typeDef.FullName, typeDef.Module.Assembly.FullName)); + } + + mat.PropertyDictionary.Add(pname, val); + foreach (TypeDefinition td in GetInheritanceChain (attType)) { PropertyDefinition prop = GetMember (td.Properties, pname); if (prop == null) @@ -225,7 +239,7 @@ MA.CustomAttribute ConvertToRawAttribute (CustomAttribute att, string expectedTy NodeAttributeAttribute bat = (NodeAttributeAttribute) GetCustomAttribute (prop, typeof(NodeAttributeAttribute), false); if (bat != null) { string name = string.IsNullOrEmpty (bat.Name) ? prop.Name : bat.Name; - mat.Add (name, Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture)); + mat.NodeDictionary.Add (name, Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture)); } } } @@ -242,7 +256,7 @@ MA.CustomAttribute ConvertToRawAttribute (CustomAttribute att, string expectedTy NodeAttributeAttribute bat = (NodeAttributeAttribute) GetCustomAttribute (field, typeof(NodeAttributeAttribute), false); if (bat != null) { string name = string.IsNullOrEmpty (bat.Name) ? field.Name : bat.Name; - mat.Add (name, Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture)); + mat.NodeDictionary.Add (name, Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture)); } } } diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs index b87d92b1..dbfb2842 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs @@ -918,7 +918,7 @@ void ScanAssemblyContents (IAssemblyReflector reflector, AddinDescription config // Look for extension nodes declared using assembly attributes foreach (CustomAttribute att in reflector.GetRawCustomAttributes (asm, typeof(CustomExtensionAttribute), true)) - AddCustomAttributeExtension (module, att, "Type"); + AddCustomAttributeExtension (null, null, module, att, "Type"); // Get extensions or extension points applied to types @@ -1015,7 +1015,7 @@ void ScanAssemblyContents (IAssemblyReflector reflector, AddinDescription config else { // Look for custom extension attribtues foreach (CustomAttribute att in reflector.GetRawCustomAttributes (t, typeof(CustomExtensionAttribute), false)) { - ExtensionNodeDescription elem = AddCustomAttributeExtension (module, att, "Type"); + ExtensionNodeDescription elem = AddCustomAttributeExtension (reflector, t, module, att, "Type"); elem.SetAttribute ("type", typeFullName); if (string.IsNullOrEmpty (elem.GetAttribute ("id"))) elem.SetAttribute ("id", typeFullName); @@ -1025,13 +1025,37 @@ void ScanAssemblyContents (IAssemblyReflector reflector, AddinDescription config } } - ExtensionNodeDescription AddCustomAttributeExtension (ModuleDescription module, CustomAttribute att, string nameName) + ExtensionNodeDescription AddCustomAttributeExtension (IAssemblyReflector reflector, object t, ModuleDescription module, + CustomAttribute att, string nameName) { - string path; - if (!att.TryGetValue (CustomExtensionAttribute.PathFieldKey, out path)) - path = "%" + att.TypeName; - ExtensionNodeDescription elem = module.AddExtensionNode (path, nameName); - foreach (KeyValuePair prop in att) { + string path; + if (!att.NodeDictionary.TryGetValue(CustomExtensionAttribute.PathFieldKey, out path) && reflector != null && t != null) + { + object type; + if (att.PropertyDictionary.TryGetValue("Type", out type) && type is Type) + { + var concreteType = (Type) type; + path = "$" + concreteType.FullName; + } + else + { + path = GetBaseTypeNameList(reflector, t); + if (path == "$") + { + // The type does not implement any interface and has no superclass. + // Will be reported later as an error. + string typeFullName = reflector.GetTypeFullName(t); + path = "$" + typeFullName; + } + } + } + else + { + path = "%" + att.TypeName; + } + + ExtensionNodeDescription elem = module.AddExtensionNode (path, nameName); + foreach (KeyValuePair prop in att.NodeDictionary) { if (prop.Key != CustomExtensionAttribute.PathFieldKey) elem.SetAttribute (prop.Key, prop.Value); } diff --git a/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs b/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs index b835f8a2..213255c7 100644 --- a/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs +++ b/Mono.Addins/Mono.Addins.Database/DefaultAssemblyReflector.cs @@ -95,21 +95,22 @@ CustomAttribute ConvertAttribute (object ob) NodeAttributeAttribute bt = (NodeAttributeAttribute) Attribute.GetCustomAttribute (prop, typeof(NodeAttributeAttribute), true); if (bt != null) { string name = string.IsNullOrEmpty (bt.Name) ? prop.Name : bt.Name; - at [name] = Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture); + at.NodeDictionary[name] = Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture); } } - } - foreach (FieldInfo field in type.GetFields (BindingFlags.Public | BindingFlags.Instance)) { + at.PropertyDictionary[prop.Name] = val; + } + foreach (FieldInfo field in type.GetFields (BindingFlags.Public | BindingFlags.Instance)) { object val = field.GetValue (ob); if (val != null) { NodeAttributeAttribute bt = (NodeAttributeAttribute) Attribute.GetCustomAttribute (field, typeof(NodeAttributeAttribute), true); if (bt != null) { string name = string.IsNullOrEmpty (bt.Name) ? field.Name : bt.Name; - at [name] = Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture); + at.NodeDictionary[name] = Convert.ToString (val, System.Globalization.CultureInfo.InvariantCulture); } } - } - return at; + } + return at; } public string GetTypeName (object type) diff --git a/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs b/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs index 5c763320..509def96 100644 --- a/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs +++ b/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs @@ -297,16 +297,34 @@ public interface IAssemblyLocator /// /// A custom attribute /// - public class CustomAttribute: Dictionary + public class CustomAttribute { - string typeName; - - /// - /// Full name of the type of the custom attribute - /// - public string TypeName { + private string typeName; + private Dictionary _nodeDictionary; + private Dictionary _propertyDictionary; + + public CustomAttribute() + { + _nodeDictionary = new Dictionary(); + _propertyDictionary = new Dictionary(); + } + + /// + /// Full name of the type of the custom attribute + /// + public string TypeName { get { return typeName; } - set { typeName = value; } - } - } + set { typeName = value; } + } + + /// + /// Returns a dictionary of nodes + /// + public IDictionary NodeDictionary { get { return _nodeDictionary;} } + + /// + /// Returns a dictionary of properties + /// + public IDictionary PropertyDictionary { get { return _propertyDictionary; } } + } } diff --git a/Mono.Addins/Mono.Addins/CustomExtensionAttribute.cs b/Mono.Addins/Mono.Addins/CustomExtensionAttribute.cs index d500190a..fef57d92 100644 --- a/Mono.Addins/Mono.Addins/CustomExtensionAttribute.cs +++ b/Mono.Addins/Mono.Addins/CustomExtensionAttribute.cs @@ -41,8 +41,9 @@ public class CustomExtensionAttribute: Attribute string insertBefore; string insertAfter; string path; - - internal const string PathFieldKey = "__path"; + Type type; + + internal const string PathFieldKey = "__path"; /// /// Identifier of the node @@ -82,12 +83,27 @@ public string InsertAfter { public string Path { get { return path; } set { path = value; } - } - - /// - /// The extension node bound to this attribute - /// - public ExtensionNode ExtensionNode { get; internal set; } + } + + /// + /// Type defining the extension point being extended + /// + /// + /// This property can be used to explicitly specify the type that defines the extension point + /// to be extended. By default, Mono.Addins will try to find any extension point defined in any + /// of the base classes or interfaces. This property can be used when there is more than one + /// base type providing an extension point. + /// + public Type Type + { + get { return type; } + set { type = value; } + } + + /// + /// The extension node bound to this attribute + /// + public ExtensionNode ExtensionNode { get; internal set; } /// From c3d60324c28f933a35553ec7b4e5e4124a2b607d Mon Sep 17 00:00:00 2001 From: Copa-Data Date: Wed, 13 Jul 2016 08:19:23 +0200 Subject: [PATCH 3/5] Anpassungen ignore --- .gitignore | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index cf1ae05e..abf76716 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,8 @@ *~ # Build stuff -obj -/bin +obj/ +bin/ *policy*config *.pc *.dll @@ -34,6 +34,7 @@ Makefile.in /install-sh /missing .suo -/*.suo +*.suo +*.user /Test/ /packages/ From ae85034492db27ddf184b868ade5a30526a7ad06 Mon Sep 17 00:00:00 2001 From: Gerald Lochner Date: Thu, 28 Jul 2016 10:06:09 +0200 Subject: [PATCH 4/5] Fix Spaces to Tabs; AddinEngine.Shutdown() throwed an exception, when an ExtensionNode still was loaded immediately before Shutdown, so ResetCachedData of Registry accessed the already uninitialized AddinEngine. Also there was a different behavior between using Mono.Cecil and .NET Reflection using a derived version from CustomExtensionAttribute. When using AddInRegistry.GetAddinDescription, extension nodes were not found, because AddinScanResult.GetAssemblyLocation did not resolve to the startup directory (in our case here are all needed assemblies located). --- .../Mono.Addins.Database/AddinDatabase.cs | 1 + .../Mono.Addins.Database/AddinScanResult.cs | 26 +++++++- .../Mono.Addins.Database/AddinScanner.cs | 65 +++++++++++-------- .../IAssemblyReflector.cs | 49 +++++++------- Mono.Addins/Mono.Addins/AddinEngine.cs | 4 +- 5 files changed, 92 insertions(+), 53 deletions(-) diff --git a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs index bdaa33fc..454e11c8 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs @@ -1441,6 +1441,7 @@ public void ParseAddin (IProgressStatus progressStatus, string domain, string fi } AddinScanResult sr = new AddinScanResult (); + sr.AddAssemblySearchLocation(registry.StartupDirectory); sr.Domain = domain; AddinScanner scanner = new AddinScanner (this, sr, progressStatus); diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs b/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs index e33becc2..6b47468d 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs @@ -48,7 +48,8 @@ internal class AddinScanResult: MarshalByRefObject, IAssemblyLocator Hashtable visitedFolders = new Hashtable (); Hashtable assemblyLocations = new Hashtable (); - Hashtable assemblyLocationsByFullName = new Hashtable (); + Hashtable assemblyLocationsByFullName = new Hashtable(); + List assemblySearchLocations = new List(); Hashtable filesToIgnore; bool regenerateRelationData; @@ -164,6 +165,11 @@ public void AddAssemblyLocation (string file) } list.Add (file); } + + public void AddAssemblySearchLocation(string directory) + { + assemblySearchLocations.Add(directory); + } public string GetAssemblyLocation (string fullName) { @@ -177,8 +183,24 @@ public string GetAssemblyLocation (string fullName) return GetType ().Assembly.Location; ArrayList list = assemblyLocations [name] as ArrayList; if (list == null) + { + var assemblyName = new AssemblyName(fullName); + foreach (var assemblySearchLocation in assemblySearchLocations) + { + string filePath = Path.Combine(assemblySearchLocation, assemblyName.Name + ".dll"); + if (File.Exists(filePath)) + { + var existingAssembly = AssemblyName.GetAssemblyName(filePath); + if (existingAssembly.FullName == assemblyName.FullName) + { + return filePath; + } + } + } + return null; - + } + string lastAsm = null; foreach (string file in list.ToArray ()) { try { diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs index 5b7f4e84..b443d6e7 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs @@ -748,7 +748,7 @@ void ReportReflectionException (IProgressStatus monitor, Exception ex, AddinDesc scanResult.AddFileToWithFailure (config.AddinFile); monitor.ReportWarning ("[" + config.AddinId + "] Could not load some add-in assemblies: " + ex.Message); if (monitor.LogLevel <= 1) - return; + return; ReflectionTypeLoadException rex = ex as ReflectionTypeLoadException; if (rex != null) { @@ -904,14 +904,25 @@ void ScanAssemblyContents (IAssemblyReflector reflector, AddinDescription config // Get extension points object[] extPoints = reflector.GetCustomAttributes (asm, typeof(ExtensionPointAttribute), false); - foreach (ExtensionPointAttribute ext in extPoints) { - ExtensionPoint ep = config.AddExtensionPoint (ext.Path); + foreach (ExtensionPointAttribute ext in extPoints) + { + ExtensionPoint ep; + if (ext.Path.Length > 0) + { + ep = config.AddExtensionPoint(ext.Path); + } + else + { + ep = config.AddExtensionPoint(GetDefaultTypeExtensionPath(config, ext.ObjectTypeName)); + } + ep.Description = ext.Description; ep.Name = ext.Name; ep.DefaultInsertBefore = ext.DefaultInsertBefore; ep.DefaultInsertAfter = ext.DefaultInsertAfter; ExtensionNodeType nt = ep.AddExtensionNode (ext.NodeName, ext.NodeTypeName); nt.ExtensionAttributeTypeName = ext.ExtensionAttributeTypeName; + nt.ObjectTypeName = ext.ObjectTypeName; } } @@ -1026,35 +1037,35 @@ void ScanAssemblyContents (IAssemblyReflector reflector, AddinDescription config } ExtensionNodeDescription AddCustomAttributeExtension (IAssemblyReflector reflector, object t, ModuleDescription module, - CustomAttribute att, string nameName) + CustomAttribute att, string nameName) { string path; if (!att.NodeDictionary.TryGetValue(CustomExtensionAttribute.PathFieldKey, out path) && reflector != null && t != null) { - object type; - if (att.PropertyDictionary.TryGetValue("Type", out type) && type is Type) - { - var concreteType = (Type) type; - path = "$" + concreteType.FullName; - } - else - { - path = GetBaseTypeNameList(reflector, t); - if (path == "$") - { - // The type does not implement any interface and has no superclass. - // Will be reported later as an error. - string typeFullName = reflector.GetTypeFullName(t); - path = "$" + typeFullName; - } - } - } - else - { - path = "%" + att.TypeName; - } + object type; + if (att.PropertyDictionary.TryGetValue("Type", out type) && type is Type) + { + var concreteType = (Type) type; + path = "$" + concreteType.FullName; + } + else + { + path = GetBaseTypeNameList(reflector, t); + if (path == "$") + { + // The type does not implement any interface and has no superclass. + // Will be reported later as an error. + string typeFullName = reflector.GetTypeFullName(t); + path = "$" + typeFullName; + } + } + } + else + { + path = "%" + att.TypeName; + } - ExtensionNodeDescription elem = module.AddExtensionNode (path, nameName); + ExtensionNodeDescription elem = module.AddExtensionNode (path, nameName); foreach (KeyValuePair prop in att.NodeDictionary) { if (prop.Key != CustomExtensionAttribute.PathFieldKey) elem.SetAttribute (prop.Key, prop.Value); diff --git a/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs b/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs index 509def96..04f3dadb 100644 --- a/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs +++ b/Mono.Addins/Mono.Addins.Database/IAssemblyReflector.cs @@ -300,31 +300,34 @@ public interface IAssemblyLocator public class CustomAttribute { private string typeName; - private Dictionary _nodeDictionary; - private Dictionary _propertyDictionary; + private Dictionary _nodeDictionary; + private Dictionary _propertyDictionary; - public CustomAttribute() - { - _nodeDictionary = new Dictionary(); - _propertyDictionary = new Dictionary(); - } - - /// - /// Full name of the type of the custom attribute - /// - public string TypeName { + /// + /// Constructor + /// + public CustomAttribute() + { + _nodeDictionary = new Dictionary(); + _propertyDictionary = new Dictionary(); + } + + /// + /// Full name of the type of the custom attribute + /// + public string TypeName { get { return typeName; } - set { typeName = value; } - } + set { typeName = value; } + } - /// - /// Returns a dictionary of nodes - /// - public IDictionary NodeDictionary { get { return _nodeDictionary;} } + /// + /// Returns a dictionary of nodes + /// + public IDictionary NodeDictionary { get { return _nodeDictionary;} } - /// - /// Returns a dictionary of properties - /// - public IDictionary PropertyDictionary { get { return _propertyDictionary; } } - } + /// + /// Returns a dictionary of properties + /// + public IDictionary PropertyDictionary { get { return _propertyDictionary; } } + } } diff --git a/Mono.Addins/Mono.Addins/AddinEngine.cs b/Mono.Addins/Mono.Addins/AddinEngine.cs index e0af4c26..5bba0ec8 100755 --- a/Mono.Addins/Mono.Addins/AddinEngine.cs +++ b/Mono.Addins/Mono.Addins/AddinEngine.cs @@ -224,12 +224,14 @@ Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args) public void Shutdown () { lock (LocalLock) { + ResetCachedData(); + initialized = false; AppDomain.CurrentDomain.AssemblyLoad -= new AssemblyLoadEventHandler (OnAssemblyLoaded); AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomainAssemblyResolve; loadedAddins = new Dictionary(); loadedAssemblies = new Dictionary (); - registry.Dispose (); + registry.Dispose(); registry = null; startupDirectory = null; ClearContext (); From e2342b884ec2cfb3b82666dd5d725fc80814730a Mon Sep 17 00:00:00 2001 From: Gerald Lochner Date: Thu, 28 Jul 2016 10:09:40 +0200 Subject: [PATCH 5/5] Space->Tab --- .../Mono.Addins.CecilReflector/Reflector.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs b/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs index f94ade1c..3613da5f 100644 --- a/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs +++ b/Mono.Addins.CecilReflector/Mono.Addins.CecilReflector/Reflector.cs @@ -217,19 +217,19 @@ MA.CustomAttribute ConvertToRawAttribute (CustomAttribute att, string expectedTy if (val == null) continue; - if (val is TypeReference) - { - var typeRef = (TypeReference) val; - var typeDef = typeRef.Resolve(); - if (typeDef == null) - throw new InvalidOperationException(string.Format("Cannot resolve assembly '{0}'", typeDef.Module.Assembly.FullName)); - - val = Type.GetType(typeDef.FullName + ", " + typeDef.Module.Assembly.FullName, false); - if (val == null) - throw new InvalidOperationException(string.Format("Cannot resolve type '{0}' at assembly '{1}'", typeDef.FullName, typeDef.Module.Assembly.FullName)); - } - - mat.PropertyDictionary.Add(pname, val); + if (val is TypeReference) + { + var typeRef = (TypeReference) val; + var typeDef = typeRef.Resolve(); + if (typeDef == null) + throw new InvalidOperationException(string.Format("Cannot resolve assembly '{0}'", typeDef.Module.Assembly.FullName)); + + val = Type.GetType(typeDef.FullName + ", " + typeDef.Module.Assembly.FullName, false); + if (val == null) + throw new InvalidOperationException(string.Format("Cannot resolve type '{0}' at assembly '{1}'", typeDef.FullName, typeDef.Module.Assembly.FullName)); + } + + mat.PropertyDictionary.Add(pname, val); foreach (TypeDefinition td in GetInheritanceChain (attType)) { PropertyDefinition prop = GetMember (td.Properties, pname);