New tests.
[mono.git] / mcs / class / corlib / System / Activator.cs
1 //
2 // System.Activator.cs
3 //
4 // Authors:
5 //   Nick Drochak II (ndrochak@gol.com)
6 //   Gonzalo Paniagua (gonzalo@ximian.com)
7 //
8 // (C) 2001 Nick Drochak II
9 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
10 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Globalization;
33 using System.Reflection;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.InteropServices;
36 using System.Security.Permissions;
37 using System.Security.Policy;
38 using System.Configuration.Assemblies;
39 using System.Text;
40 #if !MOONLIGHT
41 using System.Runtime.Remoting;
42 using System.Runtime.Remoting.Activation;
43 #endif
44
45 namespace System 
46 {
47         [ClassInterface (ClassInterfaceType.None)]
48         [ComVisible (true)]
49         [ComDefaultInterface (typeof (_Activator))]
50         public sealed class Activator : _Activator
51         {
52                 const BindingFlags _flags = BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance;
53                 const BindingFlags _accessFlags = BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase | 
54                                                                                         BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public |
55                                                                                         BindingFlags.Static;
56
57                 private Activator ()
58                 {
59                 }
60
61 #if !MOONLIGHT
62                 [MonoTODO ("No COM support")]
63                 public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
64                 {
65                         if (assemblyName == null)
66                                 throw new ArgumentNullException ("assemblyName");
67
68                         if (typeName == null)
69                                 throw new ArgumentNullException ("typeName");
70
71                         if (assemblyName.Length == 0)
72                                 throw new ArgumentException ("assemblyName");
73
74                         throw new NotImplementedException();
75                 }
76
77                 [MonoTODO("Mono does not support COM")]
78                 public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName,
79                                                                   byte []hashValue, AssemblyHashAlgorithm hashAlgorithm)
80                 {
81                         if (assemblyName == null)
82                                 throw new ArgumentNullException ("assemblyName");
83
84                         if (typeName == null)
85                                 throw new ArgumentNullException ("typeName");
86
87                         if (assemblyName.Length == 0)
88                                 throw new ArgumentException ("assemblyName");
89
90                         throw new NotImplementedException();
91                 }
92
93                 public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName)
94                 {
95                         return CreateInstanceFrom (assemblyFile, typeName, null);
96                 }
97
98                 public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, object [] activationAttributes)
99                 {
100                         return Activator.CreateInstanceFrom (assemblyFile, typeName, false, _flags, null, null, null,
101                                 activationAttributes, null);
102                 }
103
104 #if NET_4_0
105                 [Obsolete]
106 #endif
107                 public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
108                                                                BindingFlags bindingAttr, Binder binder, object [] args,
109                                                                CultureInfo culture, object [] activationAttributes,
110                                                                Evidence securityInfo)
111                 {
112                         Assembly assembly = Assembly.LoadFrom (assemblyFile, securityInfo);
113                         if (assembly == null)
114                                 return null;
115
116                         Type type = assembly.GetType (typeName, true, ignoreCase);
117                         if (type == null)
118                                 return null;
119
120                         object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
121                         return (obj != null) ? new ObjectHandle (obj) : null;
122                 }
123
124                 public static ObjectHandle CreateInstance (string assemblyName, string typeName)
125                 {
126                         if (assemblyName == null)
127                                 assemblyName = Assembly.GetCallingAssembly ().GetName ().Name;
128
129                         return Activator.CreateInstance (assemblyName, typeName, null);
130                 }
131
132                 public static ObjectHandle CreateInstance (string assemblyName, string typeName, object [] activationAttributes)
133                 {
134                         if (assemblyName == null)
135                                 assemblyName = Assembly.GetCallingAssembly ().GetName ().Name;
136
137                         return Activator.CreateInstance (assemblyName, typeName, false, _flags, null, null, null,
138                                 activationAttributes, null);
139                 }
140
141 #if NET_4_0
142                 [Obsolete]
143 #endif
144                 public static ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase,
145                                                            BindingFlags bindingAttr, Binder binder, object [] args,
146                                                            CultureInfo culture, object [] activationAttributes, Evidence securityInfo)
147                 {
148                         Assembly assembly = null;
149                         if(assemblyName == null)
150                                 assembly = Assembly.GetCallingAssembly ();
151                         else
152                                 assembly = Assembly.Load (assemblyName, securityInfo);
153                         Type type = assembly.GetType (typeName, true, ignoreCase);
154                         object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
155                         return (obj != null) ? new ObjectHandle (obj) : null;
156                 }
157
158                 [MonoNotSupported ("no ClickOnce in mono")]
159                 public static ObjectHandle CreateInstance (ActivationContext activationContext)
160                 {
161                         throw new NotImplementedException ();
162                 }
163
164                 [MonoNotSupported ("no ClickOnce in mono")]
165                 public static ObjectHandle CreateInstance (ActivationContext activationContext, string [] activationCustomData)
166                 {
167                         throw new NotImplementedException ();
168                 }
169
170                 // Cross-domain instance creation
171
172                 public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName)
173                 {
174                         if (domain == null)
175                                 throw new ArgumentNullException ("domain");
176                         return domain.CreateInstanceFrom (assemblyFile, typeName);
177                 }
178
179
180 #if NET_4_0
181                 [Obsolete]
182 #endif
183                 public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName,
184                                                                bool ignoreCase, BindingFlags bindingAttr, Binder binder,
185                                                                object [] args, CultureInfo culture,
186                                                                object [] activationAttributes,
187                                                                Evidence securityAttributes)
188                 {
189                         if (domain == null)
190                                 throw new ArgumentNullException ("domain");
191
192                         return domain.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
193                 }
194
195                 public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName)
196                 {
197                         if (domain == null)
198                                 throw new ArgumentNullException ("domain");
199                         return domain.CreateInstance (assemblyName, typeName);
200                 }
201
202 #if NET_4_0
203                 [Obsolete]
204 #endif
205                 public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName,
206                                                            bool ignoreCase, BindingFlags bindingAttr, Binder binder,
207                                                            object [] args, CultureInfo culture,
208                                                            object [] activationAttributes,
209                                                            Evidence securityAttributes)
210                 {
211                         if (domain == null)
212                                 throw new ArgumentNullException ("domain");
213                         return domain.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
214                 }
215 #endif // !NET_2_1
216
217                 public static T CreateInstance <T> ()
218                 {
219                         return (T) CreateInstance (typeof (T));
220                 }
221
222                 public static object CreateInstance (Type type)
223                 {
224                         return CreateInstance (type, false);
225                 }
226
227                 public static object CreateInstance (Type type, params object [] args)
228                 {
229                         return CreateInstance (type, args, new object [0]);
230                 }
231
232                 public static object CreateInstance (Type type, object [] args, object [] activationAttributes)
233                 {
234                         return CreateInstance (type, BindingFlags.Default, Binder.DefaultBinder, args, null, activationAttributes);
235                 }
236
237                 public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
238                                                      CultureInfo culture)
239                 {
240                         return CreateInstance (type, bindingAttr, binder, args, culture, new object [0]);
241                 }
242
243                 public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
244                                                      CultureInfo culture, object [] activationAttributes)
245                 {
246                         CheckType (type);
247
248                         if (type.ContainsGenericParameters)
249                                 throw new ArgumentException (type + " is an open generic type", "type");
250
251                         // It seems to apply the same rules documented for InvokeMember: "If the type of lookup
252                         // is omitted, BindingFlags.Public | BindingFlags.Instance will apply".
253                         if ((bindingAttr & _accessFlags) == 0)
254                                 bindingAttr |= BindingFlags.Public | BindingFlags.Instance;
255
256                         int length = 0;
257                         if (args != null)
258                                 length = args.Length;
259
260                         Type[] atypes = length == 0 ? Type.EmptyTypes : new Type [length];
261                         for (int i = 0; i < length; ++i)
262                                 if (args [i] != null)
263                                         atypes [i] = args [i].GetType ();
264
265                         if (binder == null)
266                                 binder = Binder.DefaultBinder;
267
268                         ConstructorInfo ctor = (ConstructorInfo) binder.SelectMethod (bindingAttr, type.GetConstructors (bindingAttr), atypes, null);
269
270                         if (ctor == null) {
271                                 // Not sure about this
272                                 if (type.IsValueType && atypes.Length == 0) {
273                                         return CreateInstanceInternal (type);
274                                 }
275
276                                 StringBuilder sb = new StringBuilder ();
277                                 foreach (Type t in atypes){
278                                                 sb.Append (t != null ? t.ToString () : "(unknown)");
279                                         sb.Append (", ");
280                                 }
281                                 if (sb.Length > 2)
282                                         sb.Length -= 2;
283                                 
284                                 throw new MissingMethodException (String.Format (Locale.GetText ("No constructor found for {0}::.ctor({1})"),
285                                                                                  type.FullName, sb));
286                         }
287
288                         CheckAbstractType (type);
289 #if !MOONLIGHT
290                         if (activationAttributes != null && activationAttributes.Length > 0) {
291                                 if (!type.IsMarshalByRef) {
292                                         string msg = Locale.GetText ("Type '{0}' doesn't derive from MarshalByRefObject.", type.FullName);
293                                         throw new NotSupportedException (msg);
294                                 }
295                                 object newOb = ActivationServices.CreateProxyFromAttributes (type, activationAttributes);
296                                 if (newOb != null) {
297                                         // This returns null
298                                         ctor.Invoke (newOb, bindingAttr, binder, args, culture);
299                                         return newOb;
300                                 }
301                         }
302 #endif
303                         return ctor.Invoke (bindingAttr, binder, args, culture);
304                 }
305
306                 public static object CreateInstance (Type type, bool nonPublic)
307                 { 
308                         CheckType (type);
309
310                         if (type.ContainsGenericParameters)
311                                 throw new ArgumentException (type + " is an open generic type", "type");
312
313                         CheckAbstractType (type);
314
315                         ConstructorInfo ctor;
316                         MonoType monoType = type as MonoType;
317
318                         if (monoType != null) {
319                                 ctor = monoType.GetDefaultConstructor ();
320                                 if (!nonPublic && ctor != null && !ctor.IsPublic)
321                                         ctor = null;
322                         } else {
323                                 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
324                                 if (nonPublic)
325                                         flags |= BindingFlags.NonPublic;
326                                 ctor = type.GetConstructor (flags, null, CallingConventions.Any, Type.EmptyTypes, null);
327                         }
328
329                         if (ctor == null) {
330                                 if (type.IsValueType)
331                                         return CreateInstanceInternal (type);
332
333                                 throw new MissingMethodException (Locale.GetText ("Default constructor not found for type " + 
334                                                         type.FullName + "."));
335                         }
336
337                         return ctor.Invoke (null);
338                 }
339
340                 private static void CheckType (Type type)
341                 {
342                         if (type == null)
343                                 throw new ArgumentNullException ("type");
344
345                         if ((type == typeof (TypedReference)) || (type == typeof (ArgIterator)) || (type == typeof (void)) ||
346                                 (type == typeof (RuntimeArgumentHandle))) {
347                                 string msg = Locale.GetText ("CreateInstance cannot be used to create this type ({0}).", type.FullName);
348                                 throw new NotSupportedException (msg);
349                         }
350                 }
351
352                 private static void CheckAbstractType (Type type)
353                 {
354                         if (type.IsAbstract) {
355                                 string msg = Locale.GetText ("Cannot create an abstract class '{0}'.", type.FullName);
356                                 throw new MissingMethodException (msg);
357                         }
358                 }
359
360 #if !MOONLIGHT
361                 [SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
362                 public static object GetObject (Type type, string url)
363                 {
364                         if (type == null)
365                                 throw new ArgumentNullException ("type");
366
367                         return RemotingServices.Connect (type, url);
368                 }
369
370                 [SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
371                 public static object GetObject (Type type, string url, object state)
372                 {
373                         if (type == null)
374                                 throw new ArgumentNullException ("type");
375
376                         return RemotingServices.Connect (type, url, state);
377                 }
378 #endif
379                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
380                 internal static extern object CreateInstanceInternal (Type type);
381
382                 void _Activator.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
383                 {
384                         throw new NotImplementedException ();
385                 }
386
387                 void _Activator.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
388                 {
389                         throw new NotImplementedException ();
390                 }
391
392                 void _Activator.GetTypeInfoCount (out uint pcTInfo)
393                 {
394                         throw new NotImplementedException ();
395                 }
396
397                 void _Activator.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
398                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
399                 {
400                         throw new NotImplementedException ();
401                 }
402
403 #if NET_4_0
404                 public static ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase,
405                                                            BindingFlags bindingAttr, Binder binder, object [] args,
406                                                            CultureInfo culture, object [] activationAttributes)
407                 {
408                         Assembly assembly = null;
409                         if(assemblyName == null)
410                                 assembly = Assembly.GetCallingAssembly ();
411                         else
412                                 assembly = Assembly.Load (assemblyName);
413                         Type type = assembly.GetType (typeName, true, ignoreCase);
414                         object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
415                         return (obj != null) ? new ObjectHandle (obj) : null;
416                 }
417
418                 public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName,
419                                                            bool ignoreCase, BindingFlags bindingAttr, Binder binder,
420                                                            object [] args, CultureInfo culture,
421                                                            object [] activationAttributes)
422                 {
423                         if (domain == null)
424                                 throw new ArgumentNullException ("domain");
425                         return domain.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes);
426                 }
427
428                 public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
429                                                                BindingFlags bindingAttr, Binder binder, object [] args,
430                                                                CultureInfo culture, object [] activationAttributes)
431                 {
432                         Assembly assembly = Assembly.LoadFrom (assemblyFile);
433                         if (assembly == null)
434                                 return null;
435
436                         Type type = assembly.GetType (typeName, true, ignoreCase);
437                         if (type == null)
438                                 return null;
439
440                         object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
441                         return (obj != null) ? new ObjectHandle (obj) : null;
442                 }
443
444                 public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName,
445                                                                bool ignoreCase, BindingFlags bindingAttr, Binder binder,
446                                                                object [] args, CultureInfo culture,
447                                                                object [] activationAttributes)
448                 {
449                         if (domain == null)
450                                 throw new ArgumentNullException ("domain");
451
452                         return domain.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes);
453                 }
454 #endif
455         }
456 }