C# reflection with manually loaded assemblies

Started by
12 comments, last by joanusdmentia 20 years, 8 months ago
I'm currently trying to create an object whose type is specified as a string. I use Type.GetType(typestr) with a type in the currently executing assembly and all is good. However, I'm using a plugin system where I manually load some assemblies using Assembly.LoadFrom(), and whenever typestr is a type in a loaded assembly GetType() fails (returns null). This is basically what I'm doing:

Assembly assembly = Assembly.LoadFrom("Plugin.Assembly.dll");
string typename = assembly.GetTypes()[0].AssemblyQualifiedName;
Type type = Type.GetType(typename);
 
What I'm actually doing is using the AssemblyQualifiedName to store the object type in a save file. When I load the file back up I use this to recreate the object and then fill the objects data in with the data that follows in the save file. As a last resort I could probably call GetType() for every loaded assembly myself but from what I could gather from the documentation this should work. [edited by - joanusdmentia on August 6, 2003 11:11:24 PM]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Advertisement
What are you trying to do??? To me it seems like you should use serialization instead.
Type.GetType only works on the statically present types in your project. It will not get you a type from an assembly thats only present in one of your Assembly variables.

To get a type from an assembly, you have to use Assembly.GetTypes again, and check whether each types name is the type you are looking for.

Then use Activator.CreateInstance(type); to create an instance of that object.
quote:
What are you trying to do??? To me it seems like you should use serialization instead.

I''m writing out and reading back a structure somewhat like a scenegraph. I did try using XmlSerializer, but it seems like using it with recursive data types is more trouble than just doing it all myself. Also, if I''m deserializing a type that might be in an assembly loaded with LoadFrom() would that even work? If I''m missing something here please let me know!

quote:
Type.GetType only works on the statically present types in your project. It will not get you a type from an assembly thats only present in one of your Assembly variables.

That''s annoying
Easy enough to get around though. Thanks for your help.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
quote:Original post by joanusdmentia
quote:
What are you trying to do??? To me it seems like you should use serialization instead.

I''m writing out and reading back a structure somewhat like a scenegraph. I did try using XmlSerializer, but it seems like using it with recursive data types is more trouble than just doing it all myself.
quote:I really think you should do it the "right" way, it shouldn''t be impossible or too hard. If you post a small testable sample of what you want to do it''s easier to help.

One reason to not use reflection is that it won''t work in many scenarios. Reflection requires ReflectionPermission, which many users might not have if admins has restricted permissions (which will be more and more common).
quote:
I really think you should do it the "right" way, it shouldn''t be impossible or too hard. If you post a small testable sample of what you want to do it''s easier to help.

One reason to not use reflection is that it won''t work in many scenarios. Reflection requires ReflectionPermission, which many users might not have if admins has restricted permissions (which will be more and more common).

Hmm, wasn''t aware of that. That really isn''t an issue for me though since my plugin system relies on reflection, so my app would really be screwed anyway . For the time being at least I''ll simply be happy to get this working.

A simplified version of the data structure is
    public abstract class SceneGraphNode : Named    {        public SceneGraphNode() {}        public SceneGraphNode(string name) : base(name) {}        private SceneGraphNode parent = null;        [XmlIgnore]        public SceneGraphNode Parent        {            get { return parent; }        }        private ArrayList children = new ArrayList();        public ArrayList Children        {            get { return children; }        }        protected Math.Vector position = new Math.Vector();        public Math.Vector Position        {            get { return position; }            set { position = value; }        }        protected Math.Vector rotation = new Math.Vector();        public Math.Vector Rotation        {            get { return rotation; }            set { rotation = value; }        }    }

My problem was that attempting to serialize the object would go into an infinite loop, even with [XmlIgnore] applied to the Parent property. I tried playing with it but after a little while I gave up and decided to go with reflection. How would you go about serializing this? And would this work correctly when the type being serialized is derived from SceneGraphNode and exists in an assembly loaded with Assembly.LoadFrom()?
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
I haven''t done this myself, so I cannot help much more. I''d guess you need to implement ISerializable. I think Microsoft''s news server is a better place to look for help about this:

http://groups.google.com/groups?q=microsoft.public.dotnet.xml

or

http://msdn.microsoft.com/newsgroups/default.asp?url=/newsgroups/loadframes.asp?icp=msdn&slcid=us&newsgroup=microsoft.public.dotnet.xml



quote:Original post by joanusdmentia
...my plugin system relies on reflection...
Not sure what you''re doing... ;-) But if you''re doing some sort of executable and allow 3rd parties to write plugin to your code, I don''t think you need reflection. Simply have an interface assembly, where you define the interfaces they need to implement. Then have a config file telling what assemblies/classes you need to load, containing the implementations of your interfaces.
quote:Original post by Tylon
Type.GetType only works on the statically present types in your project. It will not get you a type from an assembly thats only present in one of your Assembly variables.


Check out the AppDomain.TypeResolve and AppDomain.AssemblyResolve events. You can help the CLR to resolve types and assemblies!

Regards
VizOne

[edited by - VizOne on August 7, 2003 12:58:57 PM]
Andre Loker | Personal blog on .NET
quote:Original post by Anonymous Poster
I don''t think you need reflection. Simply have an interface assembly, where you define the interfaces they need to implement. Then have a config file telling what assemblies/classes you need to load, containing the implementations of your interfaces.

And this would get around the need for reflection how?


AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
As I interpret "plugin system", it''s a way to provide 3rd parties to implement some functionality so your application can use it without knowing how it''s implemented.

If so, you could expose an interface in an assembly, and the 3rd party can reference that assembly and implement that interface. There''s no need to use reflection.

But joanusdmentia''s plugin system is maybe something else than this, in which case reflection might be needed.

The reason I''m wondering if reflecion is necessary, is that I''ve seen few cases where it really is needed. It''s a really powerful and cool feature! I''ve used it a lot for testing, but rarely used it in production code.

This topic is closed to new replies.

Advertisement