NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Hosting classes in Windows 2000 Component Services

Hosting NGWS Components in PDC Tech Preview

In order to mark a managed type in such a way that it can get Component Services, a managed type can be marked with a new custom attribute ComEmulate. When users mark NGWS Components classes as being ComEmulate, they can leverage Windows 2000 Component Services, including transactions, activities, JIT activation, object pooling, and so forth.

Managed clients talk to all such instances via Interop. When the marked NGWS managed class is instantiated from managed code (newobj, Activator.CreateInstance, . . .), the EE will activate the object via CoCreateInstance.

For PDC TechPreview, when the CCW is re-introduced to managed code, we never unwrap it. (Normally a CCW over a managed object in the same appdomain / subprocess is unwrapped to produce a direct managed reference). Instead, we produce an RCW over the CCW. Then all calls between a managed client and one of these managed servers go through COM Interop. This allows the Windows 2000 Component Services Context engine to have full control.

Key Points

Today, MTS and Windows 2000 Component Services applications need to be registered and configured. ComEmulate enables NGWS Components to utilizes Windows 2000 Component Services. Just as today, with class COM components there are restrictions on deployment and configuration.

Hosting NGWS Components in Product Release

In Product Release some of the restrictions will disappear. In particular, the type would be a full managed type with inheritance, fields, etc. It's as natural as any other managed type that inherits from MarshalByRefObject.

All the operational nuisances related to the current ComEmulate types (either author a 2nd type or use special switches to TLBIMP the managed type) would also disappear. The operational nuisances that would remain are the same ones that exist today for classic COM types. Specifically, you must register these things into the Component Services catalog, thereby breaking xcopy deployment. And you retain many of the other Component Services restrictions, like threading limitations.

However, it's worth pointing out that some things are better than classic COM. For example, you don't have to worry about leaking references between contexts by storing them in statics. The runtime would make it impossible to leak, because the instance remains fully wrapped at all times. Also, we can perhaps make memory management simpler than with Component Services, particularly if we use the trick of making the cycle through COM Interop visible to the GC, in one direction.

We can also address the performance hit of pumping calls through COM Interop, and the lack of fidelity caused by marshaling arguments through COM Interop. Specifically, once we do the DCR work, we can efficiently short-circuit the case where the thread is already in the correct unmanaged context. And we think we may be able to pass the call through COM Interop without marshaling any arguments -- if the client and server are in the same managed process. This is a trick we've used in the past.

The lack of xcopy deployment is a serious problem, despite it already being a problem with existing COM+ 1.0 apps. It has been discussed about making xcopy deployment work for the case where the client is managed code. When JITting the "new MyComponent()", or when loading the class MyComponent, we would notice that the component is marked as ComEmulate. So we could register it with the catalog at that time, assuming that it has all the necessary custom attributes for TransactionAttribute(Requires), etc.

Unmanaged clients don't get xcopy deployment, of course, so it would be nice if Tools could assist with the deployment of these components so that they are automatically configured upon installation. The DCR work for ComEmulate types is the first step, but it would be great to have Tools to help out -- for instance by deploying users' apps and by providing wizards.

Finally, the final managed transaction story will be not significantly different than the COM+ 1.0 story based on ComEmulate. The fact that Component Services group is doing the work, and the fact that it will be built on top of the Runtime Transparent Proxies etc, means we can pretty much predict what the final managed story is going to look like. It's going to look a lot like where we'll be after we implement that DCR.

Steps to Host a managed class in Windows 2000 Component Services

Step1 – write the managed class

The elements in gray are needed for PDC Tech Preview

The elements in yellow are needed for Product Release

BankClassLibrary.cs

PDC Tech Preview Product Release
In PDC Tech Preview two classes are needed. The class with ComEmulate emulates the internal class. In Product Release only one class will be needed.
namespace BankClassLibrary

{

namespace BankClassLibrary

{

[guid(“1237e50f-6085-49f7-8293-3febb8580e78”)]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
 
public interface IMoveMoney
{

/*

lngPrimeAccount -   "From" Account
lngSecondAccount -  "To" Account
lngAmount -         Amount of transaction
lngTranType -       Transaction Type
1 = Withdrawal,
2 = Deposit,
3 = Transfer)
Returns:  String -        Account Balance
*/

  public String Perform (
                  int lngPrimeAccount, 
                  int lngSecondAccount, 
                  int lngAmount, 
                       int tranType);

}


public interface IMoveMoney
{

/*

lngPrimeAccount -   "From" Account
lngSecondAccount -  "To" Account
lngAmount -         Amount of transaction
lngTranType -       Transaction Type
1 = Withdrawal,
2 = Deposit,
3 = Transfer)
Returns:  String -        Account Balance
*/

  public String Perform (
                  int lngPrimeAccount, 
                  int lngSecondAccount, 
                  int lngAmount, 
                       int tranType);

}

[TransactionAttribute(TransactionOption.Required)]
[Guid(“b963fbbd-d1b1-4a2f-8501-89252dcb116f”)]
[ComEmulate(“BankClassLibrary.MoveMoneyInternal\0”)]
public class MoveMoney
{

}

internal class MoveMoneyInternal : IMoveMoney
{
  public String Perform (
         int lngPrimeAccount, 
         int lngSecondAccount, 
         int lngAmount, 
           int tranType)
  {
    // Use IAccount to move money 
    // between two accounts
  }

}

[TransactionAttribute(TransactionOption.Required)]
[ComEmulate()]
public class MoveMoney : IMoveMoney
{
  public String Perform (
         int lngPrimeAccount, 
         int lngSecondAccount, 
         int lngAmount, 
           int tranType)
  {
    // Use Account to move money 
    // between two accounts
  }

}

[Guid(“41ee971a-93f9-4111-89ee-4e0f4e0fca0a”)]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]

public interface IAccount
{
   public String Post (
              int lngAccountNo, 
              int lngAmount);

}

public interface IAccount
{
   public String Post (
              int lngAccountNo, 
              int lngAmount);

}

[TransactionAttribute(TransactionOption.Required)]
[Guid(“41ee971a-93f9-4111-89ee-4e0f4e0fca0a”)]
[ComEmulate(“BankClassLibrary.AccountInternal\0”)]
public class Account
{
} 


internal class AccountInternal
{
  public String Post(
          int lngAccountNo, 
          int lngAmount)
  {
    // Use ADO+ to post money into 
    // the account in the database.
  }

}

[TransactionAttribute(TransactionOption.Required)]
[ComEmulate()]
public class Account 
{
  public String Post(
          int lngAccountNo, 
          int lngAmount)
  {
    // Use ADO+ to post money into 
    // the account in the database.
  }

}

[Guid(“0bc94b5e-311d-4106-aa5f-70ace030ebc4”)]
[ComEmulate(“BankClassLibrary.TransferInternal\0”)]
public class Transfer
{
} 

internal class TransferInternal : IObjectControl
{
  public String DoSomeWork(
          int i, 
          int j)
  {
    // do some interesting work
  }

  void Activate()
  {
     //. . . 
  }

  void Deactivate()
  {
     //. . .
  }

  bool CanBePooled()
  {
     //. . .
  }
}
[ComEmulate()]
public class Transfer
{
} 

internal class TransferInternal : IObjectControl
{
  public String DoSomeWork(
          int i, 
          int j)
  {
    // do some interesting work
  }

  void Activate()
  {
     //. . . 
  }

  void Deactivate()
  {
     //. . .
  }

  bool CanBePooled()
  {
     //. . .
  }
}

Step2 – Write the managed Bank App

The App code does not change between PDC Tech Preview and Product Release.

MyBankApp.cs

using System;
using BankClassLibrary;

public MyApp
{
  public static Main(String[] args)
  {
    MoveMoney mm = new Foo();
    IMoveMoney imm = (IMoveMoney)mm;

    //Transfer $1000 from account 12345 to account 20566
    String balance = imm.Perform (
                       12345, 
                  20456, 
                  1000, 
                       3);
  }
}

Step3 – Deployment and Configuration - Host the Managed classes in Component Services

A Managed Assembly that needs to be part of a COM+ Library or Server Application needs have a strong name and placed in the Assembly cache.

Steps to add a managed assembly to a COM+ Server Application.

Description Command Line
Generate a key for the Assembly
sn -k TestKey.snk
Compile the Assembly passing in the key
Csc /debug /a.keyfile:Testkey.snk /t:library /r:Microsoft.ComServices.dll /out: BankClassLibrary.dll BankClassLibrary.cs
Register the Assembly in a NGWS Application
RegSvcs BankClassLibrary.dll SomeApp
Place the Assembly in the Assembly Cache
al /I:BankClassLibrary.dll
Optionally configured using Component Services Admin Tools  

For the product release the following capabilities will be enabled.

Product Release
The NGWS runtime will Dynamically Generate TLB on managed “new” or dropping into Component Services Admin Tools
TheNGWS runtime will Dynamic Register on managed “new” or dropping into Component Services Admin Tools.
Optionally configured using Component Services Admin Tools

Managed types that have managed context may be deployed and configured via NGWS configuration files. They require no registration and take full advantage of the xcopy deployment features of the NGWS, if all clients are managed.

Note: For PDC Tech Preview, Managed managed types that are marked as ComEmulate must be configured and registered just as in Component Services today.

Key Points

PDC Tech Preview Product Release
  • Classes which are ComEmulate will be registered in the COM+1.0 Catalog.
  • Classes which are ComEmulate may be registered in the COM+1.0 Catalog.
  • DllRegisterServer with “ComEmulate” clases is not supported, use RegAsm to register Assemblies (RegAsm is the new name for ComReg) or via the APIs that RegAsm uses to register managed classes.
  • We can do some work to make this easier.
  • Classes that are ComEmulate can optionally be configured though the Windows Component Services Admin Tool.
  • Classes that are ComEmulate can optionally be configured though the Windows Component Services Admin Tool.
  • Exposed simple Managed Custom Attribute to allow user to mark their classes to need certain services e.g. TransactionsRequired (similar to marking Transactions in an IDL file today).
  • Exposed simple Managed Custom Attribute to allow user to mark their classes to need certain services e.g. TransactionAttribute(Required) similar to marking Transactions in an IDL file today.
 
  • The Component Services could be made aware more aware of NGWS Components, by looking for additional custom attribute on the managed classes. This will help users significantly.
  • Programmatically manipulate the COM+ 1.0 Catalog via the COM Admin Interfaces to set Transactions etc.
  • Programmatically manipulate the COM+ 1.0 Catalog via the COM Admin Interfaces to set Transactions etc.
 
  • XCOPY deployment only works if a managed client activates the managed component. Under those circumstances, we have enough information to register the component when we JIT the callsite. But if an unmanaged client does a CoCreate, there is no reasonable pathway from the CLSID to the managed component. So XCOPY deployment doesn't work in that case. It is hoped that VS Tools might spit out an installer for components marked with ComEmulate, that properly puts them into the catalog.

Step4 – Run the managed application

Execute MyBankApp.exe

Security

The NGWS runtime supports role-based security mechanism similar to those provided in the earlier MTS and COM+1.0 services (see “Role-based Security in NGWS”). The NGWS runtime mechanisms were designed as an integral part of the managed application programming model and are specifically geared toward the needs of Internet-scale applications. These are summarized below.

We recognize that one may wish to write managed code extending an existing application using COM+1.0 security services. To accommodate this need, we provide mechanisms to integrate managed code with COM+1.0 security services. The NGWS and COM+1.0 role-based security mechanisms are independent and only one should be used within a single application.

NGWS Role-based security

NGWS role-based security services are integrated into managed code runtime environment. The model provides a great deal of flexibility while still being easy to use. The mechanisms are platform independent and do not assume any specific authentication or OS account infrastructure.

Key features include:

COM+ 1.0 Security Interoperability

Support is provided for managed code developers who need to integrate with COM+1.0 security. The primary reason using this mechanism is to extend existing COM+1.0 applications using managed code. This functionality is only available on Windows2000 and relies on the NT token associated with executing code as the basis for identity.

To simplify use of COM+1.0 security, we provide a managed code wrapper so a managed application can easily access the COM+1.0 ISecurityContext. Applications using this mechanism will need to:

Developers should be cognizant of the following issues:

One can also use the earlier MTS security functionality available on NT 4 with the Option Pack installed. We do not, however, provide managed code objects to assist in using MTS security and using applications will need to be aware of the additional limitations imposed relative to COM+1.0.