Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use so many kinds of method to create an instance of a type?

Tags:

c#

.net

I know these methods to create an instance:

  • Activator.CreateInstance()
  • AppDomain.CreateInstance()
  • AppDomain.CreateInstanceAndUnwrap()

When to use them? What are their differences? What does the Unwrap mean? Unwrap what? Why don't the other two methods also unwrap?

Update

Currently, I have the following medical analogy:

  • Activator.CreateInstance() = external insemination
  • AppDomain.CreateInstance() = natural pregnancy/internal insemination

As to the Unwrap operation, I have some vague feeling but I won't post it until it is more clear.

like image 995
smwikipedia Avatar asked Sep 24 '10 04:09

smwikipedia


2 Answers

You didn't include Assembly.CreateInstance() in your list. Difference there is that it will be happy with just the Type.FullName to create the object. You have to give Activator.CreateInstance the 'fully qualified typename' so it can find the proper assembly to load. Depends if you already have the assembly reference. But these are equivalent:

        var asm = System.Reflection.Assembly.Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
        var obj1 = asm.CreateInstance("System.Object");
        var obj2 = Activator.CreateInstance("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Object");

AppDomain.CreateInstance() is a whole different ballgame. AppDomains are mainly important in custom CLR hosts like ASP.NET and SQL Server. A subset are apps that support plug-ins. An AD is similar to a process in Windows, they isolate chunks of code so that they cannot destabilize each other. A Windows process accomplishes that by giving each process a completely separate view of memory, strongly enabled by the processor's support for virtual memory. An AD is the exact same analogue, each AD has its own garbage collected heap and its own loader heap. Which allows isolating chunks of managed code, each running in their own AD, so they cannot destabilize the host. The win here is that creating an AD is a lot cheaper than creating a process. Pretty important in the quest to kick LAMP ass.

Just as there's a need to scale the wall that Windows puts up between processes so they can interact, there's a way and need in .NET as well. AppDomain.CreateInstance. The actual plumbing isn't very relevant here, the difference between MarshalByRefObject and objects that are marshaled by value is very opaque and worthy of a question by itself perhaps.

The difference between the two you listed is small. CreateInstanceAndUnWrap is a convenience method because that's what you'd normally want to do. Get a proxy reference or copy of the object in the other AD and it better not fail. AppDomain.CreateInstance() lets you first test if the marshaling was successful, avoiding the exception that unwrapping would cause when CreateInstance returns a null ObjectHandle.

like image 63
Hans Passant Avatar answered Nov 15 '22 20:11

Hans Passant


The ones for AppDomain allow you to create instances in a separate application domain. You have to understand the concept to realize why it makes a difference: http://msdn.microsoft.com/en-us/library/aa719528.aspx

The one with unwrap is a convenience method, its doing what's shown in the example here: http://msdn.microsoft.com/en-us/library/system.runtime.remoting.objecthandle.unwrap.aspx. Basically its allowing to make calls between the application domains, which requires the initial object to be declared marked as a MarshalByRefObject.

like image 31
eglasius Avatar answered Nov 15 '22 21:11

eglasius