AppDomain::CreateInstanceAndUnwrap Method (String^, String^, array<Object^>^)
Creates a new instance of the specified type. Parameters specify the assembly where the type is defined, the name of the type, and an array of activation attributes.
Assembly: mscorlib (in mscorlib.dll)
public: Object^ CreateInstanceAndUnwrap( String^ assemblyName, String^ typeName, array<Object^>^ activationAttributes )
Parameters
- assemblyName
-
Type:
System::String^
The display name of the assembly. See Assembly::FullName.
- typeName
-
Type:
System::String^
The fully qualified name of the requested type, including the namespace but not the assembly, as returned by the Type::FullName property.
- activationAttributes
-
Type:
array<System::Object^>^
An array of one or more attributes that can participate in activation. Typically, an array that contains a single UrlAttribute object that specifies the URL that is required to activate a remote object.
This parameter is related to client-activated objects.Client activation is a legacy technology that is retained for backward compatibility but is not recommended for new development. Distributed applications should instead use Windows Communication Foundation.
| Exception | Condition |
|---|---|
| ArgumentNullException | assemblyName or typeName is null. |
| MissingMethodException | No matching public constructor was found. |
| TypeLoadException | typename was not found in assemblyName. |
| FileNotFoundException | assemblyName was not found. |
| MethodAccessException | The caller does not have permission to call this constructor. |
| NotSupportedException | The caller cannot provide activation attributes for an object that does not inherit from MarshalByRefObject. |
| AppDomainUnloadedException | The operation is attempted on an unloaded application domain. |
| BadImageFormatException | assemblyName is not a valid assembly. -or- Version 2.0 or later of the common language runtime is currently loaded and assemblyName was compiled with a later version. |
| FileLoadException | An assembly or module was loaded twice with two different evidences. |
This is a convenience method that combines CreateInstance and ObjectHandle::Unwrap. This method calls the default constructor for typeName.
See AssemblyName for the format of assemblyName. See the Type::FullName property for the format of typeName.
Note |
|---|
If you make an early-bound call to a method M of an object of type T1 that was returned by CreateInstanceAndUnwrap, and that method makes an early-bound call to a method of an object of type T2 in an assembly C other than the current assembly or the assembly containing T1, assembly C is loaded into the current application domain. This loading occurs even if the early-bound call to T1.M() was made in the body of a DynamicMethod, or in other dynamically generated code. If the current domain is the default domain, assembly C cannot be unloaded until the process ends. If the current domain later attempts to load assembly C, the load might fail. |
using namespace System; using namespace System::IO; using namespace System::Threading; using namespace System::Reflection; using namespace System::Reflection::Emit; using namespace System::Runtime::Remoting; ref class ADDyno { public: static Type^ CreateADynamicAssembly( interior_ptr<AppDomain^> myNewDomain, String^ executableNameNoExe ) { String^ executableName = String::Concat( executableNameNoExe, ".exe" ); AssemblyName^ myAsmName = gcnew AssemblyName; myAsmName->Name = executableNameNoExe; myAsmName->CodeBase = Environment::CurrentDirectory; AssemblyBuilder^ myAsmBuilder = ( *myNewDomain)->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::RunAndSave ); Console::WriteLine( "-- Dynamic Assembly instantiated." ); ModuleBuilder^ myModBuilder = myAsmBuilder->DefineDynamicModule( executableNameNoExe, executableName ); TypeBuilder^ myTypeBuilder = myModBuilder->DefineType( executableNameNoExe, TypeAttributes::Public, MarshalByRefObject::typeid ); array<Type^>^temp0 = nullptr; MethodBuilder^ myFCMethod = myTypeBuilder->DefineMethod( "CountLocalFiles", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), nullptr, temp0 ); MethodInfo^ currentDirGetMI = Environment::typeid->GetProperty( "CurrentDirectory" )->GetGetMethod(); array<Type^>^temp1 = {String::typeid}; MethodInfo^ writeLine0objMI = Console::typeid->GetMethod( "WriteLine", temp1 ); array<Type^>^temp2 = {String::typeid,Object::typeid,Object::typeid}; MethodInfo^ writeLine2objMI = Console::typeid->GetMethod( "WriteLine", temp2 ); array<Type^>^temp3 = {String::typeid}; MethodInfo^ getFilesMI = Directory::typeid->GetMethod( "GetFiles", temp3 ); myFCMethod->InitLocals = true; ILGenerator^ myFCIL = myFCMethod->GetILGenerator(); Console::WriteLine( "-- Generating MSIL method body..." ); LocalBuilder^ v0 = myFCIL->DeclareLocal( String::typeid ); LocalBuilder^ v1 = myFCIL->DeclareLocal( int::typeid ); LocalBuilder^ v2 = myFCIL->DeclareLocal( String::typeid ); LocalBuilder^ v3 = myFCIL->DeclareLocal( array<String^>::typeid ); Label evalForEachLabel = myFCIL->DefineLabel(); Label topOfForEachLabel = myFCIL->DefineLabel(); // Build the method body. myFCIL->EmitCall( OpCodes::Call, currentDirGetMI, nullptr ); myFCIL->Emit( OpCodes::Stloc_S, v0 ); myFCIL->Emit( OpCodes::Ldc_I4_0 ); myFCIL->Emit( OpCodes::Stloc_S, v1 ); myFCIL->Emit( OpCodes::Ldstr, "---" ); myFCIL->EmitCall( OpCodes::Call, writeLine0objMI, nullptr ); myFCIL->Emit( OpCodes::Ldloc_S, v0 ); myFCIL->EmitCall( OpCodes::Call, getFilesMI, nullptr ); myFCIL->Emit( OpCodes::Stloc_S, v3 ); myFCIL->Emit( OpCodes::Br_S, evalForEachLabel ); // foreach loop starts here. myFCIL->MarkLabel( topOfForEachLabel ); // Load array of strings and index, store value at index for output. myFCIL->Emit( OpCodes::Ldloc_S, v3 ); myFCIL->Emit( OpCodes::Ldloc_S, v1 ); myFCIL->Emit( OpCodes::Ldelem_Ref ); myFCIL->Emit( OpCodes::Stloc_S, v2 ); myFCIL->Emit( OpCodes::Ldloc_S, v2 ); myFCIL->EmitCall( OpCodes::Call, writeLine0objMI, nullptr ); // Increment counter by one. myFCIL->Emit( OpCodes::Ldloc_S, v1 ); myFCIL->Emit( OpCodes::Ldc_I4_1 ); myFCIL->Emit( OpCodes::Add ); myFCIL->Emit( OpCodes::Stloc_S, v1 ); // Determine if end of file list array has been reached. myFCIL->MarkLabel( evalForEachLabel ); myFCIL->Emit( OpCodes::Ldloc_S, v1 ); myFCIL->Emit( OpCodes::Ldloc_S, v3 ); myFCIL->Emit( OpCodes::Ldlen ); myFCIL->Emit( OpCodes::Conv_I4 ); myFCIL->Emit( OpCodes::Blt_S, topOfForEachLabel ); //foreach loop end here. myFCIL->Emit( OpCodes::Ldstr, "---" ); myFCIL->EmitCall( OpCodes::Call, writeLine0objMI, nullptr ); myFCIL->Emit( OpCodes::Ldstr, "There are {0} files in {1}." ); myFCIL->Emit( OpCodes::Ldloc_S, v1 ); myFCIL->Emit( OpCodes::Box, int::typeid ); myFCIL->Emit( OpCodes::Ldloc_S, v0 ); myFCIL->EmitCall( OpCodes::Call, writeLine2objMI, nullptr ); myFCIL->Emit( OpCodes::Ret ); Type^ myType = myTypeBuilder->CreateType(); myAsmBuilder->SetEntryPoint( myFCMethod ); myAsmBuilder->Save( executableName ); Console::WriteLine( "-- Method generated, type completed, and assembly saved to disk." ); return myType; } }; int main() { String^ domainDir; String^ executableName = nullptr; Console::Write( "Enter a name for the file counting assembly: " ); String^ executableNameNoExe = Console::ReadLine(); executableName = String::Concat( executableNameNoExe, ".exe" ); Console::WriteLine( "---" ); domainDir = Environment::CurrentDirectory; AppDomain^ curDomain = Thread::GetDomain(); // Create a new AppDomain, with the current directory as the base. Console::WriteLine( "Current Directory: {0}", Environment::CurrentDirectory ); AppDomainSetup^ mySetupInfo = gcnew AppDomainSetup; mySetupInfo->ApplicationBase = domainDir; mySetupInfo->ApplicationName = executableNameNoExe; mySetupInfo->LoaderOptimization = LoaderOptimization::SingleDomain; AppDomain^ myDomain = AppDomain::CreateDomain( executableNameNoExe, nullptr, mySetupInfo ); Console::WriteLine( "Creating a new AppDomain '{0}'...", executableNameNoExe ); Console::WriteLine( "-- Base Directory = '{0}'", myDomain->BaseDirectory ); Console::WriteLine( "-- Shadow Copy? = '{0}'", myDomain->ShadowCopyFiles ); Console::WriteLine( "---" ); Type^ myFCType = ADDyno::CreateADynamicAssembly( &curDomain, executableNameNoExe ); Console::WriteLine( "Loading '{0}' from '{1}'...", executableName, myDomain->BaseDirectory ); BindingFlags bFlags = static_cast<BindingFlags>(BindingFlags::Public | BindingFlags::CreateInstance | BindingFlags::Instance); Object^ myObjInstance = myDomain->CreateInstanceAndUnwrap( executableNameNoExe, executableNameNoExe, false, bFlags, nullptr, nullptr, nullptr, nullptr, nullptr ); Console::WriteLine( "Executing method 'CountLocalFiles' in {0}...", myObjInstance ); array<Object^>^temp4 = nullptr; myFCType->InvokeMember( "CountLocalFiles", BindingFlags::InvokeMethod, nullptr, myObjInstance, temp4 ); }
for the ability to access the location of the assembly. Associated enumeration: FileIOPermissionAccess::PathDiscovery
for the ability to read the file containing the assembly manifest. Associated enumeration: FileIOPermissionAccess::Read
for the ability to access the location of the assembly if the assembly is not local.
for the ability to call unmanaged code when creating an instance of a delegate. Associated enumeration: SecurityPermissionFlag::UnmanagedCode
for the ability to invoke operations on all type members. Associated enumeration: ReflectionPermissionFlag::MemberAccess
Available since 1.1
