Safe way to get System.Web assembly reference - asp.net

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;

Related

Using CreateInstance for class in different project

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.

Assembly Information

Hi I am working in .net project.
I want to display the assembly information on the page.
User will enter the name of .net assembly in a textbox and then need to display information like all the properties, functions with parameters, constructors, destructor and inherited class names.
Please give some solution for this.
The solution is System.Reflection
using System.Reflection;
For loading assembly dynamically,use
Assembly asm=Assembly.LoadFile(#"Full path of .dll file");
Now to get all types in assembly,use
Type []alltypes=asm.GetTypes();
For information about methods, constructors,parameters,properties use
MethodInfo []GetMethods() ,ConstructorInfo []GetConstructors() ,ParameterInfo []GetParameter() ,PropertyInfo []GetProperty() etc and iterate.
And many more method are there,see the MSDN of System.Reflection

Creating WebControls from fully qualified path (assembly name?)

I have a webpage in ASP.NET 3.5 that will be creating WebControls dynamically. The WebControls that it will be creating will be known by their fully qualified path (ie - System.Web.UI.WebControls.whatever). The reason for this is because I am allowing the user to decide what controls will go on the webpage. Of course, there's more complexity than this, but that is it in a nutshell.
Simply put - how do I create a WebControl on a webpage by it's fully qualified path?
I realize that the answer will probably end up using reflection, but I have little experience using reflection and I don't want to shoot myself in the foot by making a newbie mistake.
try to call this way: Activator.CreateInstance(Type.GetType("TypeName"));
where TypeName is fully qualified name, including assembly. in my case it looked this way:
Activator.CreateInstance(Type.GetType("System.Web.UI.WebControls.Label, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"));
to be sure about full name in your case, try to output typeof(System.Web.UI.WebControls.Label).FullName and use it as a pattern
object widget = Activator.CreateInstance ( Assembly.GetType ( name ) );
where name is the string of the fully qualified type

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.

Using generic classes with ObjectDataSource

I have a generic Repository<T> class I want to use with an ObjectDataSource. Repository<T> lives in a separate project called DataAccess. According to this post from the MS newsgroups (relevant part copied below):
Internally, the ObjectDataSource is calling Type.GetType(string) to get the
type, so we need to follow the guideline documented in Type.GetType on how
to get type using generics. You can refer to MSDN Library on Type.GetType:
http://msdn2.microsoft.com/en-us/library/w3f99sx1.aspx
From the document, you will learn that you need to use backtick (`) to
denotes the type name which is using generics.
Also, here we must specify the assembly name in the type name string.
So, for your question, the answer is to use type name like follows:
TypeName="TestObjectDataSourceAssembly.MyDataHandler`1[System.String],TestObjectDataSourceAssembly"
Okay, makes sense. When I try it, however, the page throws an exception:
<asp:ObjectDataSource ID="MyDataSource" TypeName="MyProject.Repository`1[MyProject.MessageCategory],DataAccess" />
[InvalidOperationException: The type specified in the TypeName property of ObjectDataSource 'MyDataSource' could not be found.]
The curious thing is that this only happens when I'm viewing the page. When I open the "Configure Data Source" dialog from the VS2008 designer, it properly shows me the methods on my generic Repository class. Passing the TypeName string to Type.GetType() while debugging also returns a valid type. So what gives?
Do something like this.
Type type = typeof(Repository<MessageCategory);
string assemblyQualifiedName = type.AssemblyQualifiedName;
get the value of assemblyQualifiedName and paste it into the TypeName field. Note that Type.GetType(string), the value passed in must be
The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
So, it may work by passing in that string in your code, because that class is in the currently executing assembly (where you are calling it), where as the ObjectDataSource is not.
Most likely the type you are looking for is
MyProject.Repository`1[MyProject.MessageCategory, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null], DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null
I know this is an old post but I have recently had this problem myself. Another solution would be to replace the inheritance with object composition, e.g.
[DataObject]
public class DataAccessObject {
private Repository<MessageCategory> _repository;
// ctor omitted for clarity
// ...
[DataObjectMethod(DataObjectMethodType.Select)]
public MessageCategory Get(int key) {
return _repository.Get(key);
}
}
This way the ObjectDataSource doesn't know about the repository because its hidden within the class. I have a class library in my facade layer that is a perfectly reasonable place to put this code in the project I am working on.
In addition, if you are using Resharper and interfaces, its possible to get Resharper to do the refactoring using Resharpers "Implement using field" function.
Darren,
Many, many thanks for your post. I've been fighting with this all day. Strangely, in my case, I need to double the square brackets, e.g. for your piece of code:
MyProject.Repository`1[[MyProject.MessageCategory, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null]], DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null
Roger

Resources