By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,594 Members | 3,017 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,594 IT Pros & Developers. It's quick & easy.

How will we use .Net in future versions of Access

P: n/a
http://msdn.microsoft.com/library/de...llnetfrcom.asp

The Joy of Interoperability

Sometimes a revolution in programming forces you to abandon all that's
come before. To take an extreme example, suppose you have been writing
Visual Basic applications for years now. If you're like many
developers, you will have built up a substantial inventory of code in
that time. And if you've been following the recommendations from
various language gurus, that code is componentized. That is, by using
COM (Component Object Model)-formerly Microsoft®
ActiveX®-servers, you've broken your application into chunks of
callable functionality. Of course, you're also likely to have a
substantial investment in components, such as ActiveX controls, from
other developers and other companies.

But what if you decide on the radical move of switching development to
another operating system entirely? At that point, your entire
investment in COM becomes worthless. You can't use any of your existing
code, and you have to learn how to do everything on the new platform.
This would undoubtedly be a severe blow to your productivity.

Fortunately, switching from COM to .NET involves no such radical loss
of productivity. There are two key concepts that make it much easier to
move from COM development to .NET development, without any loss of code
base or productivity:

* .NET components can call COM components.
* COM components can call .NET components.

This two-way interoperability is the key to moving from COM to .NET. As
you learn the intricacies of .NET, you can continue to use COM
components. There are a number of situations where this
interoperability is useful:

* The switch to .NET won't be instant. It takes time to learn the
..NET programming concepts and implementation, so you will probably find
that you need to continue working with COM code while you, your
coworkers, and your suppliers come up to speed.
* The code that you can migrate to .NET can't be migrated all at
once. You'll want to migrate, and then test, each migrated component
individually.
* You may be using third-party COM components that you cannot
convert to .NET, and where the supplier has not yet released a .NET
version.
* Although Visual Basic 6.0 code will migrate to .NET, the
migration isn't perfect. You may have components that can't be moved to
..NET because of implementation or language quirks.

In this document, you'll learn the details of calling .NET servers from
COM clients. In another document in this series, Calling COM Components
from .NET Clients, you'll learn about calling in the other direction,
from .NET clients to COM servers.
Creating .NET Classes for Use in COM Applications

Although COM clients can call code that is exposed in a public class by
..NET servers, .NET code is not directly accessible to COM clients. In
order to use .NET code from a COM client, you need to create a proxy
known as a COM callable wrapper (CCW). In this section, you'll learn
about the CCW architecture, as well as the steps necessary to create
and deploy a .NET class to be used by COM clients.
COM Callable Wrappers

Code that operates within the .NET Common Language Runtime (CLR) is
called managed code. This code has access to all the services that the
CLR brings to the table, such as cross-language integration, security
and versioning support, and garbage collection. Code that does not
operate within the CLR is called unmanaged code. Because COM was
designed before the CLR existed, and COM code does not operate within
the infrastructure provided by the CLR, it can't use any of the CLR
services. All of your COM components are, by definition, unmanaged
code.

Managed code components not only depend on the CLR, they require the
components with which they interact to depend on the CLR. Because COM
components don't operate within the CLR, they are unable to call
managed code components directly. The unmanaged code simply cannot
reach into the CLR to directly call managed components.

The way out of this dilemma is to use a proxy. In general terms, a
proxy is a piece of software that accepts commands from a component,
modifies them, and forwards them to another component. The particular
type of proxy used in calling managed code from unmanaged code is known
as a COM callable wrapper, or CCW. Figure 1 shows schematically how
CCWs straddle the boundary between managed and unmanaged code. This
figure includes a COM program named ComUI.exe, two .NET components
named NETService.dll and Utility.dll, and the necessary technology that
connects them.

Figure 1. Calling managed code with CCWs
Prerequisites for COM Callable Classes

There are two prerequisites to keep in mind when creating a .NET class
that will be used by COM clients.

First, explicitly define an interface in your Visual Basic .NET code,
and have the class implement the interface. For example, this code
snippet defines an interface named iFile, and a class that implements
the interface:

Public Interface iFile
Property Length() As Integer
End Interface

Public Class TextFile
Implements iFile
' details omitted
End Class

Implementing functionality through interfaces has a major benefit for
COM clients. .NET keeps interfaces consistent with previous versions
when generating CCWs. This helps keep changes to your .NET server from
breaking COM clients.

Secondly, any class that is to be visible to COM clients must be
declared public. The tools that create the CCW only define types based
on public classes. The same rule applies to methods, properties, and
events that will be used by COM clients.

You should also consider signing .NET assemblies containing classes
that will be used by COM with a cryptographic key pair. Microsoft
refers to this as signing the assembly with a strong name. Signing an
assembly with a strong name helps .NET ensure that the code in the
assembly has not been changed since the assembly was published. This is
a requirement for all global assemblies, which are assemblies that are
to be shared by multiple clients, although unsigned assemblies can also
be called by COM clients.

Note It is possible to use an unsigned assembly from a COM client
by deploying the assembly directly to the COM client's directory as a
private assembly. This document does not cover the private assembly
approach, because global assemblies are more compatible than private
assemblies with the architecture of most COM applications.

It's good practice to sign all assemblies, even private assemblies.
This will help in generating better CLSIDs for managed classes, and
help avoid collisions between classes in different assemblies.

To create a strong name, you can use the sn tool. There are many
options for this command-line tool, and you can type sn /? at a command
prompt to see them all. The option you need for signing an assembly is
-k, which creates a key file. By default, key files use the extension
..snk. For example, to create a key file named NETServer.snk, you could
use this command line:

sn -k NETServer.snk

Deploying an Application for COM Access

After you've created a .NET assembly containing a class that will be
called by a COM client, there are three steps to make the class
available to COM.

First, you must create a type library for the assembly. A type library
is the COM equivalent of the metadata contained within a .NET assembly.
Type libraries are generally contained in files with the extension
..tlb. A type library contains the necessary information to allow a COM
client to determine which classes are located in a particular server,
as well as the methods, properties, and events supported by those
classes. The .NET Framework SDK includes a tool named tlbexp (type
library exporter) that can create a type library from an assembly.
Tlbexp includes a number of options, and you can type tlbexp /? at a
command prompt to see all of them. One of these options is the /out
option, which lets you specify the name of the generated type library.
(One is created for you if you don't choose to create your own name.)
For example, to extract the metadata from an assembly named
NETServer.dll to a type library named NETServer.tlb, you could use this
command line:

tlbexp NETServer.dll /out:NETServer.tlb

Secondly, you should use the Assembly Registration Tool (regasm) from
the .NET Framework SDK to both create the type library and register it
in a single operation. This is the easiest tool to use when you're
doing both .NET and COM development on a single computer. Like tlbexp,
there are a number of options for regasm; type regasm /? at a command
prompt to see them all. To create and register a type library using
regasm, use a command line such as this:

regasm /tlb:NETServer.tlb NETServer.dll

Thirdly, you must install the .NET assembly into the Global Assembly
Cache (GAC) so that it will be available as a shared assembly. To
install an assembly into the GAC, use the gacutil tool:

gacutil /i NETServer.dll

Again, you can get a list of all the options for gacutil by typing
gacutil /? at a command prompt.
Practice Calling a .NET Component From COM

In the following example, you will use properties and methods in a .NET
component from COM code. You will use regasm to create a type library
from the .NET assembly and to register an assembly, and you will use
gacutil to make the assembly globally available. You'll then see how
you can use this .NET assembly from within Visual Basic 6.0 COM code.
Create the .NET Assembly

To create the .NET assembly containing a public class, follow these
steps:

1. Open Microsoft® Visual Studio® .NET and click New Project on
the Start Page.
2. Select Visual Basic Project from the tree view on the left-hand
side of the screen.
3. Select Class Library as the project template.
4. Set the name of the application to PhysServer2 and click OK to
create the project.
5. Highlight the class called Class1.vb in the Solution Explorer
window and rename it to NETTemperature.vb.
6. Select the code for Class1 in NETTemperature.vb (this will be an
empty class definition) and replace it with the following code:

Public Interface iTemperature
Property Celsius() As Double
Property Fahrenheit() As Double
Function GetCelsius() As Double
Function GetFahrenheit() As Double
End Interface

Public Class NET_Temperature
Implements iTemperature

Private mdblCelsius As Double
Private mdblFahrenheit As Double

Public Property Celsius() As Double _
Implements iTemperature.Celsius
Get
Celsius = mdblCelsius
End Get
Set(ByVal Value As Double)
mdblCelsius = Value
mdblFahrenheit = ((Value * 9) / 5) + 32
End Set
End Property

Public Property Fahrenheit() As Double _
Implements iTemperature.Fahrenheit
Get
Fahrenheit = mdblFahrenheit
End Get
Set(ByVal Value As Double)
mdblFahrenheit = Value
mdblCelsius = ((Value - 32) * 5) / 9
End Set
End Property

Public Function GetCelsius() As Double _
Implements iTemperature.GetCelsius
GetCelsius = mdblCelsius
End Function

Public Function GetFahrenheit() As Double _
Implements iTemperature.GetFahrenheit
GetFahrenheit = mdblFahrenheit
End Function
End Class

This code starts by defining an interface named iTemperature. Because
the interface is defined with the Public keyword, it will be exported
to the type library you'll create from this assembly. You can think of
an interface definition as the skeleton for all or part of a class
definition. The interface definition can contain members (properties,
methods-either functions or subs-and events), just like a class.
But unlike a class, an interface definition contains no code for any of
these members. A class can implement one interface (as in this example)
or more than one interface.

This code defines the NET_Temperature class that uses the interface
iTemperature. In particular, this line in the class definition sets up
a contract between the class and the interface:

Implements iTemperature

The contract says that the class will implement all of the members of
the interface. It may also contain additional members that are not part
of the interface, but you'll get an error if you try to build a class
that does not completely implement an interface.

Note The class exposes two public properties and two public
methods. (For the basics of creating classes, methods, and properties,
see Creating Classes in Visual Basic .NET).

Notice the syntax used to associate members in the class with members
of the interface that the class implements. For example, the Celsius
property in the NET_Temperature class is defined this way:

Public Property Celsius() As Double _
Implements iTemperature.Celsius

That line of code defines a property that returns a Double, and tells
the compiler that this property is an implementation of the Celsius
property within the iTemperature interface.
Create a Key Pair and Sign the Assembly

To make the assembly globally available, you need to create a key pair
and use it to sign the assembly. In addition, you can make it easier to
work with the assembly by adding a title and description.

To sign the assembly, you can run the sn utility and add the name of
the key file by hand, or you can generate a strong name using the
Visual Studio .NET user interface. We'll use the latter method. To do
so, follow these steps:

1. In the Solution Explorer in Visual Studio .NET, double-click the
AssemblyInfo.vb file to open it in the editing window.
2. In the Assembly Attributes section at the top of this file,
modify the AssemblyTitle and AssemblyDescription lines to read:

<Assembly: AssemblyTitle("PhysServer2")>
<Assembly: AssemblyDescription(".NET Version of PhysServer")>

Tip! Assembly Attributes in Visual Basic .NET are the
equivalent of Project Properties in Visual Basic 6.0.

3. In the Solution Explorer, right-click the project node and choose
Properties. Click the Common Properties folder and then the Strong Name
property page. Select the box labeled Generate Strong Name Using. Click
Generate Key to generate a key file and add it to your project. Click
OK to close the property dialog box.

Now you're ready to create the assembly. Click Build or press
Ctrl+Shift+B to build the assembly.
Register the Assembly and Create a Type Library

At this point, you could use the new assembly and the NET_Temperature
class from another .NET application. But, you still have to make the
class and its members available to your COM applications. Open a Visual
Studio .NET command prompt (Click Start, then Programs, then Microsoft
Visual Studio .NET 7.0, then Visual Studio .NET Tools, and then Visual
Studio .NET Command Prompt), change to the project directory for
PhysServer2, and type:

regasm /tlb:PhysServer2.tlb PhysServer2.dll

The regasm utility will create a type library and register it in your
Windows registry to make the classes in PhysServer2.dll available to
COM clients.
Add the Assembly to the Global Assembly Cache

Finally, to make the newly registered assembly globally available to
all COM clients wherever they're located on your hard drive, switch
back to the Visual Studio .NET command prompt and type:

gacutil /I PhysServer2.dll

The gacutil utility will add the assembly to the GAC and print a status
message to tell you that it's done so.
Write Visual Basic 6.0 Code to Call the .NET Class

Now you're ready to write a COM client to use the NET_Temperature
class. Follow these steps:

1. Open Visual Basic 6.0 and in the New Project dialog box, click
New tab.
2. Select Standard EXE and click Open.
3. Highlight the form called Form1 in the Project Explorer window
and rename it to frmTemperature.
4. Create the form shown in Figure 2 by adding the appropriate
controls and setting the properties of those controls, as outlined in
Table 1.

Table 1. Controls for frmTemperature
Control Type Property Value
Label Name lblFahrenheit
Caption Fahrenheit
TextBox Name txtFahrenheit
Text (blank)
Button Name cmdConvertToC
Caption Convert to C
Label Name lblCelsius
Caption Celsius
TextBox Name txtCelsius
Text (blank)
Button Name cmdConvertToF
Caption Convert to F

Figure 2. The test form design
5. To use the class in PhysServer2 through the CCW, click Project,
and then click References to open the References dialog box. Select the
reference for the .NET Version of PhysServer, as shown in Figure 3.
Click OK to close the dialog box.

Figure 3. Setting a reference to the .NET component

Now you're ready to write code that uses the methods and properties of
the NET_Temperature class. On the View menu, click Code, and enter this
code in the form module for frmTemperature:

Private moTempClass As PhysServer2.NET_Temperature
Private moTemp As PhysServer2.iTemperature

Private Sub cmdConvertToC_Click()
With moTemp
.Fahrenheit = txtFahrenheit.Text
txtCelsius.Text = .GetCelsius
End With
End Sub

Private Sub cmdConvertToF_Click()
With moTemp
.Celsius = txtCelsius.Text
txtFahrenheit.Text = .GetFahrenheit
End With
End Sub

Private Sub Form_Load()
Set moTempClass = New PhysServer2.NET_Temperature
Set moTemp = moTempClass
End Sub

Remember, in the .NET project you defined the Net_Temperature class
using the iTemperature interface. This code demonstrates how you can
retrieve the interface (represented as an object named moTemp) back
from the object. Although this may look like extra code, if you
experiment in Visual Basic, you'll find that it's much more convenient
to work with the interface than it is with the object. That's because
the interface supports Microsoft® IntelliSense® command completion.
Try It Out

To see the NET_Temperature class in action, follow these steps:

1. Press F5 to start the project.
2. Enter 95 in the Fahrenheit textbox and click Convert to C. The
Celsius box should fill in with the value 35.
3. Enter -14 in the Celsius box and click Convert to F. The
Fahrenheit box should fill in with the value 6.8.
4. Close the form to stop the project.

What's New Since Visual Basic 6.0?

Of course, the entire process of calling .NET components from Visual
Basic 6.0 is new, because .NET didn't exist when Visual Basic 6.0 was
released. Visual Basic 6.0 does have the ability to create multiple
components connected by COM calls, and the .NET CCWs make the .NET
calls function like COM calls. The nice thing about the whole process
is that you don't need to risk the safety and stability of .NET
components to use them from COM code. By calling through the CLR, the
CCWs still give your .NET components all the benefits of managed code,
no matter where you use the .NET components.
Summary

Although .NET is an entirely new development environment, the designers
did not ignore the issue of compatibility with existing code. By
properly constructing your .NET components and using tools such as sn,
tlbexp, regasm, and gacutil, you can expose classes from a .NET
assembly to COM clients.

Calling a .NET component from a COM component is not a trivial
exercise. As you've seen in this document, you need to make explicit
code modifications to your .NET component to enable this scenario. But
the modifications are minor, and there are certainly benefits from
enabling COM clients to call .NET servers. If you're migrating a
complex application from COM to .NET one component at a time, you'll
find the techniques outlined in this document essential.

Feb 19 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Br
Lyle Fairfield wrote:
http://msdn.microsoft.com/library/de...llnetfrcom.asp


Wouldn't posting the link suffice? :)

<>
--
regards,

Br@dley
Feb 19 '06 #2

P: n/a
If someone were confused about the beatitudes would you be content with
Mt5: 3-12?

Feb 19 '06 #3

P: n/a
Br
Lyle Fairfield wrote:
Br@dley wrote:
Lyle Fairfield wrote:
http://msdn.microsoft.com/library/de...llnetfrcom.asp
Wouldn't posting the link suffice?
If someone were confused about the beatitudes would you be content
with Mt5: 3-12?


If the post is a copy/paste of a web site then a link is more than
sufficient (esp if the text is long).

Your consideration in this manner is appreciated.
--
regards,

Br@dley


Feb 19 '06 #4

P: n/a
"Lyle Fairfield" <ly***********@aim.com> wrote in
news:11**********************@o13g2000cwo.googlegr oups.com:
If someone were confused about the beatitudes would you be content
with Mt5: 3-12?


It would be just as good as posting the entire length if the person
doing the posting didn't make any effort to explain his point in
posting either the link or the full text.

I have to ask:

What was the point of your post?

At least, in relation to your chosen subject heading?

I see absolutely no clear applicability to Access development. I
could speculate on what you might mean, but I have neither the time
nor the interest.

This is typical of your posts, Lyle. You post something Sphynxlike
in its mystery, as if we should all know what you're trying to say,
instead of coming right out and telling us what your point is.

I'm apparently not nearly as clever as you, so I usually need a
roadmap to have a clue what you're talking about in these cases.

So, exactly what is it about .NET that you think will be some
transforming benefit to Access development? What existing problems
in Access development will it solve? What additional functionality
will it provide that could not be provided through simply adding to
the existing featureset (via COM, even)?

--
David W. Fenton http://www.dfenton.com/
usenet at dfenton dot com http://www.dfenton.com/DFA/
Feb 19 '06 #5

P: n/a
"David W. Fenton" <XX*******@dfenton.com.invalid> wrote in message
news:Xn**********************************@127.0.0. 1...

<snip>
So, exactly what is it about .NET that you think will be some
transforming benefit to Access development? What existing problems
in Access development will it solve? What additional functionality
will it provide that could not be provided through simply adding to
the existing featureset (via COM, even)?


Except for sharing of database engine features, and report, form and query
designers, there is no benefit of .Net to Access developers. General OOP is
overblown, especially for database centric application, and replacing VBA
with VB/C#.net makes no sense in this environment. I would like to see
Jet validation properties expanded with triggers and stored procedures (even
if executed locally), and inheritance of form/report related objects.

Steven

Feb 20 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.