Add a more functional (i.e. fewer-stubs) implementation of System.Data.Linq.
[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.Remoting;
35 using System.Runtime.Remoting.Activation;
36 using System.Runtime.CompilerServices;
37 using System.Runtime.InteropServices;
38 using System.Security.Permissions;
39 using System.Security.Policy;
40 using System.Configuration.Assemblies;
41 using System.Text;
42
43 namespace System 
44 {
45         [ClassInterface (ClassInterfaceType.None)]
46 #if NET_2_0
47         [ComVisible (true)]
48         [ComDefaultInterface (typeof (_Activator))]
49 #endif
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                 [MonoTODO ("No COM support")]
62                 public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
63                 {
64                         if (assemblyName == null)
65                                 throw new ArgumentNullException ("assemblyName");
66
67                         if (typeName == null)
68                                 throw new ArgumentNullException ("typeName");
69
70                         if (assemblyName.Length == 0)
71                                 throw new ArgumentException ("assemblyName");
72
73                         throw new NotImplementedException();
74                 }
75
76 #if NET_1_1
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 #endif
93
94                 public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName)
95                 {
96                         return CreateInstanceFrom (assemblyFile, typeName, null);
97                 }
98
99                 public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, object [] activationAttributes)
100                 {
101                         return Activator.CreateInstanceFrom (assemblyFile, typeName, false, _flags, null, null, null,
102                                 activationAttributes, null);
103                 }
104
105                 public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
106                                                                BindingFlags bindingAttr, Binder binder, object [] args,
107                                                                CultureInfo culture, object [] activationAttributes,
108                                                                Evidence securityInfo)
109                 {
110                         Assembly assembly = Assembly.LoadFrom (assemblyFile, securityInfo);
111                         if (assembly == null)
112                                 return null;
113
114                         Type type = assembly.GetType (typeName, true, ignoreCase);
115                         if (type == null)
116                                 return null;
117
118                         object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
119                         return (obj != null) ? new ObjectHandle (obj) : null;
120                 }
121
122                 public static ObjectHandle CreateInstance (string assemblyName, string typeName)
123                 {
124                         if (assemblyName == null)
125                                 assemblyName = Assembly.GetCallingAssembly ().GetName ().Name;
126
127                         return Activator.CreateInstance (assemblyName, typeName, null);
128                 }
129
130                 public static ObjectHandle CreateInstance (string assemblyName, string typeName, object [] activationAttributes)
131                 {
132                         if (assemblyName == null)
133                                 assemblyName = Assembly.GetCallingAssembly ().GetName ().Name;
134
135                         return Activator.CreateInstance (assemblyName, typeName, false, _flags, null, null, null,
136                                 activationAttributes, null);
137                 }
138
139                 public static ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase,
140                                                            BindingFlags bindingAttr, Binder binder, object [] args,
141                                                            CultureInfo culture, object [] activationAttributes, Evidence securityInfo)
142                 {
143                         Assembly assembly = null;
144                         if(assemblyName == null)
145                                 assembly = Assembly.GetCallingAssembly ();
146                         else
147                                 assembly = Assembly.Load (assemblyName, securityInfo);
148                         Type type = assembly.GetType (typeName, true, ignoreCase);
149                         object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
150                         return (obj != null) ? new ObjectHandle (obj) : null;
151                 }
152
153 #if NET_2_0
154                 [MonoNotSupported ("no ClickOnce in mono")]
155                 public static ObjectHandle CreateInstance (ActivationContext activationContext)
156                 {
157                         throw new NotImplementedException ();
158                 }
159
160                 [MonoNotSupported ("no ClickOnce in mono")]
161                 public static ObjectHandle CreateInstance (ActivationContext activationContext, string [] activationCustomData)
162                 {
163                         throw new NotImplementedException ();
164                 }
165
166                 // Cross-domain instance creation
167
168                 public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName)
169                 {
170                         if (domain == null)
171                                 throw new ArgumentNullException ("domain");
172                         return domain.CreateInstanceFrom (assemblyFile, typeName);
173                 }
174
175                 public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName,
176                                                                bool ignoreCase, BindingFlags bindingAttr, Binder binder,
177                                                                object [] args, CultureInfo culture,
178                                                                object [] activationAttributes,
179                                                                Evidence securityAttributes)
180                 {
181                         if (domain == null)
182                                 throw new ArgumentNullException ("domain");
183
184                         return domain.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
185                 }
186
187                 public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName)
188                 {
189                         if (domain == null)
190                                 throw new ArgumentNullException ("domain");
191                         return domain.CreateInstance (assemblyName, typeName);
192                 }
193
194                 public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName,
195                                                            bool ignoreCase, BindingFlags bindingAttr, Binder binder,
196                                                            object [] args, CultureInfo culture,
197                                                            object [] activationAttributes,
198                                                            Evidence securityAttributes)
199                 {
200                         if (domain == null)
201                                 throw new ArgumentNullException ("domain");
202                         return domain.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
203                 }
204
205                 public static T CreateInstance <T> ()
206                 {
207                         return (T) CreateInstance (typeof (T));
208                 }
209 #endif
210
211                 public static object CreateInstance (Type type)
212                 {
213                         return CreateInstance (type, false);
214                 }
215
216 #if NET_2_0
217                 public static object CreateInstance (Type type, params object [] args)
218 #else
219                 public static object CreateInstance (Type type, object [] args)
220 #endif
221                 {
222                         return CreateInstance (type, args, new object [0]);
223                 }
224
225                 public static object CreateInstance (Type type, object [] args, object [] activationAttributes)
226                 {
227                         return CreateInstance (type, BindingFlags.Default, Binder.DefaultBinder, args, null, activationAttributes);
228                 }
229
230                 public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
231                                                      CultureInfo culture)
232                 {
233                         return CreateInstance (type, bindingAttr, binder, args, culture, new object [0]);
234                 }
235
236                 public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
237                                                      CultureInfo culture, object [] activationAttributes)
238                 {
239                         CheckType (type);
240
241 #if NET_2_0
242                         if (type.ContainsGenericParameters)
243                                 throw new ArgumentException (type + " is an open generic type", "type");
244 #endif
245                         // It seems to apply the same rules documented for InvokeMember: "If the type of lookup
246                         // is omitted, BindingFlags.Public | BindingFlags.Instance will apply".
247                         if ((bindingAttr & _accessFlags) == 0)
248                                 bindingAttr |= BindingFlags.Public | BindingFlags.Instance;
249
250                         int length = 0;
251                         if (args != null)
252                                 length = args.Length;
253
254                         Type[] atypes = length == 0 ? Type.EmptyTypes : new Type [length];
255                         for (int i = 0; i < length; ++i)
256                                 if (args [i] != null)
257                                         atypes [i] = args [i].GetType ();
258
259                         if (binder == null)
260                                 binder = Binder.DefaultBinder;
261
262                         ConstructorInfo ctor = (ConstructorInfo) binder.SelectMethod (bindingAttr, type.GetConstructors (bindingAttr), atypes, null);
263
264                         if (ctor == null) {
265                                 // Not sure about this
266                                 if (type.IsValueType && atypes.Length == 0) {
267                                         return CreateInstanceInternal (type);
268                                 }
269
270                                 StringBuilder sb = new StringBuilder ();
271                                 foreach (Type t in atypes){
272                                                 sb.Append (t != null ? t.ToString () : "(unknown)");
273                                         sb.Append (", ");
274                                 }
275                                 if (sb.Length > 2)
276                                         sb.Length -= 2;
277                                 
278                                 throw new MissingMethodException (String.Format (Locale.GetText ("No constructor found for {0}::.ctor({1})"),
279                                                                                  type.FullName, sb));
280                         }
281
282                         CheckAbstractType (type);
283
284                         if (activationAttributes != null && activationAttributes.Length > 0) {
285                                 if (!type.IsMarshalByRef) {
286                                         string msg = Locale.GetText ("Type '{0}' doesn't derive from MarshalByRefObject.", type.FullName);
287                                         throw new NotSupportedException (msg);
288                                 }
289                                 object newOb = ActivationServices.CreateProxyFromAttributes (type, activationAttributes);
290                                 if (newOb != null) {
291                                         // This returns null
292                                         ctor.Invoke (newOb, bindingAttr, binder, args, culture);
293                                         return newOb;
294                                 }
295                         }
296
297                         return ctor.Invoke (bindingAttr, binder, args, culture);
298                 }
299
300                 public static object CreateInstance (Type type, bool nonPublic)
301                 { 
302                         CheckType (type);
303 #if NET_2_0
304                         if (type.ContainsGenericParameters)
305                                 throw new ArgumentException (type + " is an open generic type", "type");
306 #endif
307                         CheckAbstractType (type);
308
309                         BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
310                         if (nonPublic)
311                                 flags |= BindingFlags.NonPublic;
312
313                         ConstructorInfo ctor = type.GetConstructor (flags, null, CallingConventions.Any, Type.EmptyTypes, null);
314
315                         if (ctor == null) {
316                                 if (type.IsValueType)
317                                         return CreateInstanceInternal (type);
318
319                                 throw new MissingMethodException (Locale.GetText ("Default constructor not found."),
320                                                                 ".ctor() of " + type.FullName);
321                         }
322
323                         return ctor.Invoke (null);
324                 }
325
326                 private static void CheckType (Type type)
327                 {
328                         if (type == null)
329                                 throw new ArgumentNullException ("type");
330
331                         if ((type == typeof (TypedReference)) || (type == typeof (ArgIterator)) || (type == typeof (void)) ||
332                                 (type == typeof (RuntimeArgumentHandle))) {
333                                 string msg = Locale.GetText ("CreateInstance cannot be used to create this type ({0}).", type.FullName);
334                                 throw new NotSupportedException (msg);
335                         }
336                 }
337
338                 private static void CheckAbstractType (Type type)
339                 {
340                         if (type.IsAbstract) {
341                                 string msg = Locale.GetText ("Cannot create an abstract class '{0}'.", type.FullName);
342 #if NET_2_0
343                                 throw new MissingMethodException (msg);
344 #else
345                                 throw new MemberAccessException (msg);
346 #endif
347                         }
348                 }
349
350                 [SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
351                 public static object GetObject (Type type, string url)
352                 {
353                         if (type == null)
354                                 throw new ArgumentNullException ("type");
355
356                         return RemotingServices.Connect (type, url);
357                 }
358
359                 [SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
360                 public static object GetObject (Type type, string url, object state)
361                 {
362                         if (type == null)
363                                 throw new ArgumentNullException ("type");
364
365                         return RemotingServices.Connect (type, url, state);
366                 }
367
368                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
369                 internal static extern object CreateInstanceInternal (Type type);
370
371 #if NET_1_1
372                 void _Activator.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
373                 {
374                         throw new NotImplementedException ();
375                 }
376
377                 void _Activator.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
378                 {
379                         throw new NotImplementedException ();
380                 }
381
382                 void _Activator.GetTypeInfoCount (out uint pcTInfo)
383                 {
384                         throw new NotImplementedException ();
385                 }
386
387                 void _Activator.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
388                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
389                 {
390                         throw new NotImplementedException ();
391                 }
392 #endif
393         }
394 }