在asp.net中使用组件,也包括import和asemble的区别
2024-07-10 12:58:21
供稿:网友
if you're having conceptual difficulties with the @ import and @ assembly directives, you're not the only one. read this article to find out about the use of .net components in asp.net and forget you ever had doubts.
what has changed compared to asp classic?
if you've developed active server pages you will be familiar with the following notation:
components in asp classic
<script runat="server" language="vbscript">
dim fso
set fso = server.createobject("scripting.filesystemobject")
</script>
to create an instance of a class we use the createobject method of the server object. in the above code the variable fso is first declared and then assigned a reference to the filesystemobject object that can be found in the scripting library. for this to work it is necessary that the corresponding dll is installed and registered on the server. the registration of the filesystemobject object occurred automatically when the vbscript runtime was installed. if you want to use a 3rd-party component or one you created yourself, you will need to take care of installing and registering it.
let's now have a look at how the filesystemobject object, if it existed, would be instantiated in asp.net:
asp.net equivalent (vb.net)
<script runat="server" language="vb">
dim fso as scripting.filesystemobject = new scripting.filesystemobject()
</script>
asp.net equivalent (c#)
<script runat="server" language="c#">
scripting.filesystemobject fso = new scripting.filesystemobject();
</script>
as you can see, there are some differences to be found. the most important are:
vbscript has been dropped and replaced by the fully-fledged vb.net (a.k.a. vb 7.0).
while declaring a variable you can specify its type and initialize it.
to refer to a class, the notation namespace[.subnamespace].class notation is used. in the above example we are referring to the filesystemobject class that can be found in the scripting namespace. note that such namespace doesn't exist in the .net framework and therefore the above code will not work. on the other hand we could create our own scripting namespace and define the filesystemobject class in it.
what is a namespace?
in the previous section the word "namespace" has been used. by means of namespaces you can systematize classes into logically related units. as a rule, you will cluster classes that provide similar functionality or have a similar context. for instance the system.io namespace contains classes that are used to deal with input-output operations like reading, writing or deleting files. note that similar functionality and/or similar context is not a formal requirement. you are free to organize your namespaces along any rules, even no rules.
referring to .net components
as already noted, the first asp.net example was there for didactical reasons--it wouldn't work. let's now have a look at a working example:
creating the message object (vb.net)
<%@ assembly name="system.messaging.dll" %>
<script runat="server" language="vb">
dim mydir as system.messaging.message = new system.messaging.message()
</script>
creating the message object (c#)
<%@ assembly name="system.messaging.dll" %>
<script runat="server" language="c#">
system.messaging.message mydir = new system.messaging.message();
</script>
the @ assembly directive links an assembly to the current page, making all of the classes, interfaces and structures defined in the assembly available for use. in our example we are binding the system.messaging.dll assembly. this assembly contains the system.messaging namespace the classes of which provide access to the .net framework messaging functionality. we create an instance of the message class that provides access to message queuing message. if we were to create the message object in a code-behind file, here's what we would end up doing:
creting the message object in a code-behind file (vb.net)
public class mypage
inherits system.web.ui.page
dim mydir as system.messaging.message = new system.messaging.message()
end class
creting the message object in a code-behind file (c#)
public class mypage : system.web.ui.page {
system.messaging.message mydir = new system.messaging.message();
}
note that if we wanted to compile the class, we would need to provide the compiler with the reference to the system.messaging.dll and the system.web.dll file. assuming we save the class in a file named mypage.vb or mypage.cs for the vb.net or the c# version respectively, the compilation statement would look like this:
compiling the code-behind class
vbc mypage.vb /r:system.messaging.dll /r:system.web.dll
csc mypage.cs /r:system.messaging.dll /r:system.web.dll
the /r:system.messaging.dll and /r:system.web.dll options of the compiler play the same role as the @ assembly directive on a web form.
what is an assembly?
an assembly forms a logical unit of functionality. it is the fundamental, self-describing unit of deployment, version control, reuse, activation scoping, and security permissions. it contains the assembly manifest, which represents all the metadata needed to specify the version requirements, security identity, and other information.
importing namespaces
you will have noticed, that whenever we refer to the message object, we always need to provide the full namespace path (another words fully qualify the class name). it isn't hard to imagine that after a while this could be cumbersome and unnecessarily inflate the code. fortunately, there is a way to define the namespace path once per page thus saving a few keystrokes:
importing an assembly (vb.net)
<%@ assembly name="system.messaging.dll" %>
<%@ import namespace="system.messaging" %>
<script runat="server" language="vb">
dim mydir as message = new message()
</script>
importing an assembly (c#)
<%@ assembly name="system.messaging.dll" %>
<%@ import namespace="system.messaging" %>
<script runat="server" language="c#">
message mydir = new message();
</script>
our code-behind class could be rewritten as follows:
importing an assembly in a code-behind file (vb.net)
imports system.web.ui
imports system.messaging
public class mypage
inherits page
dim mydir as message = new message()
end class
importing an assembly in a code-behind file (c#)
using system.web.ui;
using system.messaging;
public class mypage : page {
message mydir = new message();
}
by means of the @ import directive as well as the imports or the using statements we can specify the namespace path to the classes we use. having done that we can later refer to the classes without fully qualifing the namespace path. note that if both the system.web.ui and the system.messaging namespace had a message class, we would have to qualify the class name.
it is very important to be aware of what importing a namespace does and what it doesn't. its only, albeit handy, use is to save the programmer some keystrokes and bestow the code with better readability. it alone is not sufficient to make classes inside of a namespace available to the code. the directive that actually links the namespace to the page is the @ assembly directive or the /r compiler option we have already talked about.
automation through configuration
using the @ assembly directive is not the only way to link assemblies to a web form. assemblies can be automatically linked to pages within an application. such assemblies do not require the @ assembly directive. the automatic linking is enabled by means of the <assemblies> section of the configuration file (config.web):
automatic linking in the config.web file
<configuration>
<compilation>
<assemblies>
<add assembly="system.messaging"/>
<add assembly="*"/>
</assemblies>
</compilation>
</configuration>
the asterisk instructs asp.net to link every assembly within an application's private assembly cache. by means of the <add> element you can link any namespace in that scope.
what is the application's private assembly cache?
the documentation defines the application's private assembly cache is as the /bin sub-directory of the application plus the microsoft .net framework install folder. my tests, though, have proven that only the /bin sub-folder is considered to be the private cache--in the sense that only for that folder will the asterisk wildcard work.
important note: if you have skipped the box above, there is one thing worth knowing: the asterisk in the <add> element will only link assemblies which are located in the /bin sub-folder of the application.
with the installation of the .net framework there comes a default config.web file. it automatically adds the following assemblies:
mscorlib
system
system.data
system.diagnostics
system.drawing
system.net
system.text.regularexpressions
system.web
system.web.services
system.xml
system.xml.serialization
microsoft.comservices
*
you can view the default config.web file on your system to confirm that. the following namespaces are automatically imported:
microsoft.visualbasic
system
system.collections
system.text
system.text.regularexpressions
system.web
system.web.caching
system.web.sessionstate
system.web.security
system.web.ui
system.web.ui.webcontrols
system.web.ui.htmlcontrols
unfortunately i wasn't able to determine where the automatic import is set. if you happen to know this, please drop me a line.