Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Server.CreateObject in C#

Status
Not open for further replies.

jaybuffet

Technical User
May 22, 2003
31
US
In VBScript I could do

Set obj = Server.CreateObject("ns." + request.form("obj"))
response.write(obj.doSomething())

where request.form("obj") would change depending on what page I am on. When I try to do the same thing in Visual Studio, it won't compile saying "doSomething()" doesn't exist or something like that.

What are my options?

Thanks
Jason
 
Hi Jason

What is the object you wish to "create"? If this is a COM object then you will need to add a reference to this into your application using COMInterop and import the generated proxy class into the relevant .cs file to use it.

If you have VS.NET this is simple otherwise it can be a bit of a headache...

Rob

Go placidly amidst the noise and haste, and remember what peace there may be in silence - Erhmann 1927
 
Oh I get it. You want to dynamically instantiate an object based on form input yeah?

I don't think you can do this using string concatenation like you did in VB though. Could you get the form to return some sort of identifier e.g an integer and use that to direct some conditional logic to create the correct object like this..
Code:
object obj;
switch(Request.Form[["objType"]]){
  case 1: Class1 obj = new Class1();
  case 2: Class2 obj = new Class2();
  ....
  default: DefaultClass obj = new DefaultClass();
}
obj.DoSomething();

Anygood?

Rob


Go placidly amidst the noise and haste, and remember what peace there may be in silence - Erhmann 1927
 
Oh.

You'll need to cast the form value as an int to get the above to run...
Code:
switch((int) Request.Form[["objType"]]){

Rob

Go placidly amidst the noise and haste, and remember what peace there may be in silence - Erhmann 1927
 
I could do that, but I'm trying to avoid the whole conditional thing. So I will have an architecture established and when I want to add a component, all i have to do is create a .cs class file and add a row in the database (my web menu's come from the database dynamically, so I would add a row specifying what command to run)
 
Yeah I see where your going but not sure entirely wether its possible. I guess all your components will need to have the DoSomething() method though for this to work, though they will have different implementations of this method, yes?

If that is the case you can create an Interface which all the components implement and then look for all classes that implemetn the interface in your namespace?

I don't even know if this is possible but i'm pretty sure that is how the validation controls in a .aspx work. The Page looks for all controls which implement the IValidator interface when beginning validation.

I guess you could do something similar but not sure on the code. To be honest this is right at the limit of my OO knowledge! Maybe this will help you in the right direction. Of course I maybe complicating things and there could be a much simpler solution %-)

Rob

Go placidly amidst the noise and haste, and remember what peace there may be in silence - Erhmann 1927
 
If I understand correct you need at run time a set of objects to be available (created) by suplying their types e.g a factory class that will creates objects (instances) of the types that you eventualy defined.
You could implement your factory class but there is already something in C#:

If the type is a COM then you can use :
HttpServerUtility.CreateObject ("...");

For other types (class types, interface types, array types, value types, and enumeration types) you can use:

HttpServerUtility.CreateObject (Type type)

where Type is representing the object to create and is one of the followings:

System.Reflection.Emit.EnumBuilder
System.Reflection.Emit.TypeBuilder
System.Reflection.TypeDelegator

-obislavu-
 
So where would the "objType" come in. The string from request.form["objType"] I mean.
 
There are many ways to get type e.g. an instance of Type type:

1. From an existing object, object.GetType();
2. Using static Type.GetType( string );
3. Calling GetTypeFromProgID() or GetTypeFromCLSID() is the object is a COM
4. and many more

Example:
public class MyClass1
{
}
public class MyClass2
{
}
Type type1 = Type.GetType(MyClass1);
HttpServerUtility.CreateObject (type1) ;

Type type2 = Type.GetType(MyClass2);
HttpServerUtility.CreateObject (type2) ;

-obislavu-
 
Hi obislavu

This works well. Thank you. However, I can only get it working for types from within the same namespace. For example the following

Type type1 = Type.GetType("System.Web.UI.WebControls.Button", true);

throws the following excpetion

"Could not load type System.Web.UI.WebControls.Button from assembly NCS, Version=1.0.1514.16893, Culture=neutral, PublicKeyToken=null. "

as does

protected Button Button1;
Type type1 = Type.GetType(Button1.GetType().ToString(), true);

AND (more importantly)

Type type1 = Type.GetType("MyLibrary.AClass", true);

Why is this? And how can this be used to create objects from types outside of the namespace of the current execution?

Thanks

Rob

Go placidly amidst the noise and haste, and remember what peace there may be in silence - Erhmann 1927
 
Just to qualify.

"NCS" in the above exception is the assembly in which I tested this. I cannot seem to use Type.GetType on classes from other assemblies, even when they are fully qualified.

Rob

Go placidly amidst the noise and haste, and remember what peace there may be in silence - Erhmann 1927
 
Not working so well for me.


i do the following

Type type1 = Type.GetType("obj");
object tmp = Server.CreateObject(type1);
tmp.a = 1;

doesn't work. It says 'object' does not contain a definition for 'a'
 

> Type type1 = Type.GetType("MyLibrary.AClass", true);
The above call returns a Type object from a typename e.g.
"MyLibrary.AClass". The true means an error to be thrown if the Type cannot be loaded.

>AssemblyQualifiedName

If typeName includes only the name of the Type, this method searches in the calling object's assembly, then in the mscorlib.dll assembly. If typeName is fully qualified with the partial or complete assembly name, this method searches in the specified assembly.
AssemblyQualifiedName can return a fully qualified type name including nested types and the assembly name. All compilers that support the common language runtime will emit the simple name of a nested class, and reflection constructs a mangled name when queried, in accordance with the following conventions.

Delimiter Meaning
Backslash (\) Escape character.
Comma (,) Precedes the Assembly name.
Plus sign (+) Precedes a nested class.
Period (.) Denotes namespace identifiers.

For example, the fully qualified name for a class might look like this:
TopNamespace.SubNameSpace.ContainingClass+NestedClass,MyAssembly
If the namespace were TopNamespace.Sub+Namespace, then the string would have to precede the plus sign (+) with an escape character (\) to prevent it from being interpreted as a nesting separator.
Reflection emits this string as follows:

TopNamespace.Sub\+Namespace.ContainingClass+NestedClass,MyAssembly

A "++" becomes "\+\+", and a "\" becomes "\\".
This qualified name can be persisted and later used to load the Type. To search for and load a Type, use GetType either with the type name only or with the assembly qualified type name. GetType with the type name only will look for the Type in the caller's assembly and then in the System assembly. GetType with the assembly qualified type name will look for the Type in any assembly.
-obislavu-
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top