Using CreateInstance for class in different project - asp.net

I have a solution with 3 projects. In project1 when I refer to a class in the local project CreateInstance works fine.
Dim oo As New Object = Assembly.GetExecutingAssembly().CreateInstance("TestClass", True)
oo.TestSub()
But when it's in one of other projects it returns "Nothing".
Dim oo As New Object = Assembly.GetExecutingAssembly().CreateInstance("Project2.Business.TestClass", True)
oo.TestSub()
Any ideas?
Thanks!

Types are stored per assembly (usually a project). GetExecutingAssembly always refers to the assembly that the currently executing code is a part of. If you want to create an instance of a type froma different assembly you will need a reference to THAT assembly, or call GetExecutingAssembly from inside that assembly.
You can use 'Assembly.Load' to get a reference to an assembly (even if it is already loaded) and call '.CreateInstance' on that.

Related

GetType When Type Is Provided As A String

I understand that C# is a staticly typed language and I already read the answers to this SO posting:
initialize a class by string variable in c#?
My question is a bit different, however. I'm working with a T4 template that provides me with the name of a class as a string parameter. I would give the template code here but what's important is that the type is in a string, so it's the same as having this statement in any C# module:
string s = "MyNamespace.Customer.Model";
Using that string, I need to get the type into a Type variable. Normally, I would use this code when I have access to the actual type:
Type typeModel = typeof(MyNamespace.Customer.Model);
How would I be able to obtain the Type given a string? In other words, my code would ideally look something like this (I know this doesn't work because "s" is a string):
Type typeModel = typeof(s);
(I do know what assembly the type is in, by the way, so I can use that information; also, the assembly containing the Type in question is referenced by the template, for what that's worth...)
Note: I do not want to create an object instance of the Type so please don't suggest a solution that requires using Activator.CreateInstance unless that's the only solution...
Thank you for any ideas you can provide.
The method Type.GetType(string typeName) does what you want, but if you only provide the FullName (namespace and name) of the type, it will only resolve types from the current assembly or mscorlib.
You would need to supply an AssemblyQualifiedName if you want to resolve types outside the current assembly. The problem of course is that multiple assemblies can contain different types with the same name and namespace (thanks Steven Liekens):
string aqn = Assembly.CreateQualifiedName(assemblyName, namespaceAndNameOfType);
Type t = Type.GetType(aqn);
If you don't know the assembly beforehand, you could deal with this by:
Loading all assemblies from the current AppDomain.BaseDirectory, or
Using AppDomain.GetAssemblies() for the currently loaded assemblies
And then iterating over each assembly's GetTypes() method.

Safe way to get System.Web assembly reference

I am currently using the following line of code in a web server control to get a reference to the loaded System.Web assembly:
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.Single(i => i.FullName.Contains("System.Web,"));
I am a bit concerned that there could be an occasion where the Single method call fails because (1) the assembly can't be found, or (2) more than one assembly is returned. In the debugger, it looks like there is only one assembly that matches the selector (I've included the comma after System.Web as all of the others show as "System.Web.Whatever"), but this doesn't mean that the FullName of all assemblies loaded will never contain this text).
Is there a better way to identify the reference that I'm looking for so I know that it will always find it correctly?
Thanks.
The best way would be to use a type that you know is in the System.Web assembly, e.g.:
var assembly = typeof(System.Web.HttpContext).Assembly;

how can I avoid the circular reference in vs.net?

I am using an asp.net 3.5 web solution with js which contains 2 projects ProjectA and ProjectB. ProjectA has a reference to ProjectB. Now I would like to use a class that sits in ProjectA from somewhere in ProjectB? Vs.net wont let me refer to ProjectA now because of a circular reference? Do I have to refactor of is there a way?
Move common code to Project C and add reference to it from Projects A & B.
Or merge both projects into one.
I encountered this type of error before because I was Declaring a variable Globally inside a class referencing ProjectA. I resolve it by instead of declaring variable Globally, I declared it inside a Sub/Function
Project B
Public Sub ReferenceProjectA()
Dim objProjectA As New ProjectA
objProjectA.ProjectAFunction("")
End Sub

Casting UserControl ASP.control_name_ascx vs Control_Name - Advantages/Disadvantages?

Recently I dealt with a commercially available ASP.NET product that shall go unnamed. When poking around in the code, I noticed that there was usercontrol casting that looked like this:
Dim ctl As ASP.modules_controls_addressinput_ascx = DirectCast(Me.FindControl("AddressInput1"), ASP.modules_controls_addressinput_ascx)
More recently I needed to cast a usercontrol to its specific type in one of my own projects so I could access its public properties and naturally I copied the casting method from above, since I had not seen another way to do it.
However, when deploying the project with this type of casting it would "Build", but failed when I tried to "Publish" with the error "Unknown Type". After some tinkering, I realized that the type of the declared class would work as follows:
Dim ctl As Modules_Controls_AddressInput = DirectCast(Me.FindControl("AddressInput1"), Modules_Controls_AddressInput)
Where the usercontrol is declared like this in its ascx.vb file:
Partial Class Modules_Controls_AddressInput
Inherits System.Web.UI.UserControl
And indeed, this also fixed the issue with publishing.
My question is what would compel someone to cast the first way vs the second way, especially when it means that publishing the project will fail?
I am not sure but the first approach will cast your control to the compiled code in asp.net temp folder C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\ProjectName but the second approach will cast it to a the class itself. In my work usually I use LoadControl("UserControlPath") to create an instance of any user control
Dim ctrl As MyControl = CType(Page.LoadControl("MyControl.ascx"), MyControl)
ctrl.Property1 = value1
ctrl.Property2 = value2
for more further information about user controls in ASP.Net you can refer to this post http://msdn.microsoft.com/en-us/library/ms972975.aspx

how to call an dll file dynamically from code behind(.cs)

i have an microsoft .office.interop.excel(dll) located at an directory d:\abc. now i do not want to add them as an web reference in my projet and call them
rather call the dll dynamically from my code behind(.cs)
is ther any way we can do dynmically
anyhelp would be great
thank you
Yes, but you will need to use reflection because if you don't add the assembly as reference it won't be known at compile time. Take a look at LoadFrom method.
var assembly = Assembly.LoadFrom(#"d:\abc\microsoft.office.interop.excel.dll");
var someType = assembly.GetType("Namespace.Type");
var instance = Activator.CreateInstance(type);
someType.InvokeMember(... // the reflection pain goes on
Take a look in Assembly.Load() method.
I want to discourage you from doing that. It can definitely be done if read the dll into a byte[] and call AppDomain.CurrentDomain.Load(byte[]). However you will find that you can only work with the types of that assembly through reflection. Otherwise your code behind file will not compile. So if at all possible you should add a reference (not a web reference) to the dll.

Resources