//
// System.Activator.cs
//
// Authors:
// Nick Drochak II (ndrochak@gol.com)
// Gonzalo Paniagua (gonzalo@ximian.com)
//
// (C) 2001 Nick Drochak II
// (c) 2002 Ximian, Inc. (http://www.ximian.com)
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Globalization;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security.Policy;
using System.Configuration.Assemblies;
namespace System
{
[ClassInterface (ClassInterfaceType.None)]
#if NET_2_0
[ComVisible (true)]
[ComDefaultInterface (typeof (_Activator))]
#endif
public sealed class Activator : _Activator
{
const BindingFlags _flags = BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance;
const BindingFlags _accessFlags = BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase |
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static;
private Activator ()
{
}
[MonoTODO]
public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
{
if (assemblyName == null)
throw new ArgumentNullException ("assemblyName");
if (typeName == null)
throw new ArgumentNullException ("typeName");
if (assemblyName.Length == 0)
throw new ArgumentException ("assemblyName");
throw new NotImplementedException();
}
#if NET_1_1
[MonoTODO]
public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName,
byte []hashValue, AssemblyHashAlgorithm hashAlgorithm)
{
if (assemblyName == null)
throw new ArgumentNullException ("assemblyName");
if (typeName == null)
throw new ArgumentNullException ("typeName");
if (assemblyName.Length == 0)
throw new ArgumentException ("assemblyName");
throw new NotImplementedException();
}
#endif
public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName)
{
return CreateInstanceFrom (assemblyFile, typeName, null);
}
public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, object [] activationAttributes)
{
return Activator.CreateInstanceFrom (assemblyFile, typeName, false, _flags, null, null, null,
activationAttributes, null);
}
public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
BindingFlags bindingAttr, Binder binder, object [] args,
CultureInfo culture, object [] activationAttributes,
Evidence securityInfo)
{
Assembly assembly = Assembly.LoadFrom (assemblyFile, securityInfo);
if (assembly == null)
return null;
Type type = assembly.GetType (typeName, true, ignoreCase);
if (type == null)
return null;
object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
return (obj != null) ? new ObjectHandle (obj) : null;
}
public static ObjectHandle CreateInstance (string assemblyName, string typeName)
{
if (assemblyName == null)
assemblyName = Assembly.GetCallingAssembly ().GetName ().Name;
return Activator.CreateInstance (assemblyName, typeName, null);
}
public static ObjectHandle CreateInstance (string assemblyName, string typeName, object [] activationAttributes)
{
if (assemblyName == null)
assemblyName = Assembly.GetCallingAssembly ().GetName ().Name;
return Activator.CreateInstance (assemblyName, typeName, false, _flags, null, null, null,
activationAttributes, null);
}
public static ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase,
BindingFlags bindingAttr, Binder binder, object [] args,
CultureInfo culture, object [] activationAttributes, Evidence securityInfo)
{
Assembly assembly = null;
if(assemblyName == null)
assembly = Assembly.GetCallingAssembly ();
else
assembly = Assembly.Load (assemblyName, securityInfo);
Type type = assembly.GetType (typeName, true, ignoreCase);
object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
return (obj != null) ? new ObjectHandle (obj) : null;
}
#if NET_2_0
public static T CreateInstance <T> ()
{
return (T) CreateInstance (typeof (T));
}
#endif
public static object CreateInstance (Type type)
{
return CreateInstance (type, false);
}
public static object CreateInstance (Type type, params object [] args)
{
return CreateInstance (type, args, new object [0]);
}
public static object CreateInstance (Type type, object [] args, object [] activationAttributes)
{
return CreateInstance (type, BindingFlags.Default, Binder.DefaultBinder, args, null, activationAttributes);
}
public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
CultureInfo culture)
{
return CreateInstance (type, bindingAttr, binder, args, culture, new object [0]);
}
public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
CultureInfo culture, object [] activationAttributes)
{
CheckType (type);
#if NET_2_0
if (type.ContainsGenericParameters)
throw new ArgumentException (type + " is an open generic type", "type");
#endif
// It seems to apply the same rules documented for InvokeMember: "If the type of lookup
// is omitted, BindingFlags.Public | BindingFlags.Instance will apply".
if ((bindingAttr & _accessFlags) == 0)
bindingAttr |= BindingFlags.Public | BindingFlags.Instance;
int length = 0;
if (args != null)
length = args.Length;
Type[] atypes = length == 0 ? Type.EmptyTypes : new Type [length];
for (int i = 0; i < length; ++i)
if (args [i] != null)
atypes [i] = args [i].GetType ();
if (binder == null)
binder = Binder.DefaultBinder;
ConstructorInfo ctor = (ConstructorInfo) binder.SelectMethod (bindingAttr, type.GetConstructors (bindingAttr), atypes, null);
if (ctor == null) {
// Not sure about this
if (type.IsValueType && atypes.Length == 0) {
return CreateInstanceInternal (type);
}
throw new MissingMethodException (Locale.GetText ("Constructor not found. Class: ") +
type.FullName);
}
CheckAbstractType (type);
if (activationAttributes != null && activationAttributes.Length > 0) {
if (!type.IsMarshalByRef) {
string msg = Locale.GetText ("Type '{0}' doesn't derive from MarshalByRefObject.", type.FullName);
throw new NotSupportedException (msg);
}
object newOb = ActivationServices.CreateProxyFromAttributes (type, activationAttributes);
if (newOb != null)
return ctor.Invoke (newOb, bindingAttr, binder, args, culture);
}
return ctor.Invoke (bindingAttr, binder, args, culture);
}
public static object CreateInstance (Type type, bool nonPublic)
{
CheckType (type);
#if NET_2_0
if (type.ContainsGenericParameters)
throw new ArgumentException (type + " is an open generic type", "type");
#endif
CheckAbstractType (type);
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
if (nonPublic)
flags |= BindingFlags.NonPublic;
ConstructorInfo ctor = type.GetConstructor (flags, null, CallingConventions.Any, Type.EmptyTypes, null);
if (ctor == null) {
if (type.IsValueType)
return CreateInstanceInternal (type);
throw new MissingMethodException (Locale.GetText ("Default constructor not found."),
".ctor() of " + type.FullName);
}
return ctor.Invoke (null);
}
private static void CheckType (Type type)
{
if (type == null)
throw new ArgumentNullException ("type");
if ((type == typeof (TypedReference)) || (type == typeof (ArgIterator)) || (type == typeof (void)) ||
(type == typeof (RuntimeArgumentHandle))) {
string msg = Locale.GetText ("CreateInstance cannot be used to create this type ({0}).", type.FullName);
throw new NotSupportedException (msg);
}
}
private static void CheckAbstractType (Type type)
{
if (type.IsAbstract) {
string msg = Locale.GetText ("Cannot create an abstract class '{0}'.", type.FullName);
#if NET_2_0
throw new MissingMethodException (msg);
#else
throw new MemberAccessException (msg);
#endif
}
}
[SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
public static object GetObject (Type type, string url)
{
if (type == null)
throw new ArgumentNullException ("type");
return RemotingServices.Connect (type, url);
}
[SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
public static object GetObject (Type type, string url, object state)
{
if (type == null)
throw new ArgumentNullException ("type");
return RemotingServices.Connect (type, url, state);
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal static extern object CreateInstanceInternal (Type type);
#if NET_1_1
void _Activator.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException ();
}
void _Activator.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
{
throw new NotImplementedException ();
}
void _Activator.GetTypeInfoCount (out uint pcTInfo)
{
throw new NotImplementedException ();
}
void _Activator.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
{
throw new NotImplementedException ();
}
#endif
}
}