text:
O'Reilly Book Excerpts: COM and .NET Component Services
.NET Serviced Componentsby Juval Löwy
This excerpt is Chapter 10 from COM and .NET Component Services, published in September 2001 by O'Reilly.
.NET is the new platform from Microsoft used to build component-based applications, from standalone desktop applications to web-based applications and services. The platform will be available on forthcoming Microsoft operating systems and supported by the next release of Visual Studio, called Visual Studio.NET. In addition to providing a modern object-oriented framework for building distributed applications, .NET also provides several specialized application frameworks. These frameworks include Windows Forms for rich Windows clients, ADO.NET for data access, and ASP.NET for dynamic web applications. Another important framework is Web Services, which is used to expose and consume remote objects using the emerging SOAP and other XML-based protocols.
.NET is Microsoft's next-generation component technology. It is designed from the ground up to simplify component development and deployment, as well as to support interoperability between programming languages.
Related Reading
COM and .NET Component Services
Despite its innovations and modern design, .NET is essentially a component technology. Like COM, .NET provides you with the means to rapidly build binary components, and Microsoft intends for .NET to eventually succeed COM. Like COM, .NET does not provide its own component services. Instead, .NET relies on COM+ to provide it with instance management, transactions, activity-based synchronization, granular role-based security, disconnected asynchronous queued components, and loosely coupled events. The .NET namespace that contains the types necessary to use COM+ services was named System.EnterpriseServices to reflect the pivotal role it plays in building .NET enterprise applications.
A .NET component that uses COM+ services is called a serviced component to distinguish it from the standard managed components in .NET. If you are not familiar with .NET, you should first read Appendix C or pick up a copy of .NET Framework Essentials by Thuan Thai and Hoang Lam (O'Reilly, 2001).
If you are already familiar with the basic .NET concepts, such as the runtime, assemblies, garbage collection, and C# (pronounced "C sharp"), continue reading. This chapter shows you how to create .NET serviced components that can take advantage of the COM+ component services that you have learned to apply throughout this book.
A .NET component that takes advantage of COM+ services needs to derive from the .NET base class
ServicedComponent is defined in the
System.EnterpriseServices namespace. Example 10-1 demonstrates how to write a .NET serviced component that implements the
IMessage interface and displays a message box with "Hello" in it when the interface's
ShowMessage( ) method is called.
Example 10-1: A simple .NET serviced component
namespace MyNamespace
using System.EnterpriseServices;
using System.Windows.Forms;//for the MessageBox class
public interface IMessage
void ShowMessage( );
/// <summary>
/// Plain vanilla .NET serviced component
/// </summary>
public class MyComponent:ServicedComponent,IMessage
public MyComponent( ) {}//constructor
public void ShowMessage( )
WARNING: A serviced component is not allowed to have parameterized constructors. If you require such parameters, you can either design around them by introducing a
Create( )method that accepts parameters, or use a constructor string.
There are two ways to configure a serviced component to use COM+ services. The first is COM-like: you derive from
ServicedComponent, add the component to a COM+ application, and configure it there. The second way is to apply special attributes to the component, configuring it at the source-code level. When the component is added to a COM+ application, it is configured according to the values of those attributes. Attributes are discussed in greater detail throughout this chapter as you learn about configuring .NET components to take advantage of the various COM+ services.
Related Reading
COM and .NET Component Services
.NET allows you to apply attributes to your serviced components with great flexibility. If you do not apply your own attributes, a serviced component is configured using default COM+ settings when it is added to a COM+ application. You can apply as many attributes as you like. A few COM+ services can only be configured via the Component Services Explorer. These services are mostly deployment-specific configurations, such as persistent subscriptions to COM+ Events and allocation of users to roles. In general, almost everything you can do with the Component Services Explorer can be done with attributes. I recommend that you put as many design-level attributes as possible (such as transaction support or synchronization) in the code and use the Component Services Explorer to configure deployment-specific details.
When you wish to take advantage of COM+ component services, you must map the assembly containing your serviced components to a COM+ application. That COM+ application then contains your serviced components, just like any other component--COM+ does not care whether the component it provides services to is a managed .NET serviced component or a classic COM, unmanaged, configured component. A COM+ application can contain components from multiple assemblies, and an assembly can contribute components to more than one application, as shown in Figure 10-1. Compare Figure 10-1 to Figure 1-8. There is an additional level of indirection in .NET because an assembly can contain multiple modules.
However, setting up an assembly to contribute components to more than one COM+ application is not straightforward and is susceptible to future registrations of the assembly. As a rule, avoid mapping an assembly to more than one COM+ application.
To add the serviced components in your assembly to a COM+ application, you need to register that assembly with COM+. You can perform that registration in three ways:
Regardless of the technique you use, the registration process adds your serviced components to a COM+ application and configures them according to the default COM+ settings or according to their attributes (if present in the code). If the assembly contains incompatible attributes, the incompatibility is detected during registration and the registration is aborted. Future versions of the .NET compilers may detect incompatibilities during compilation time.
Signing Assembly and Assembly Location
To add an assembly to a COM+ application, the assembly must be signed (have a strong name) so the assembly resolver can map a client activation request to the corresponding assembly. Although in theory you need not install the assembly in the global assembly cache (GAC), in practice you should install it because the assembly DLL must be in a known location--either the system directory (for server applications that run in DllHost) or the hosting client process directory (if the client is not a COM+ server application). The other known location that the assembly resolver uses is the GAC. To maintain flexibility (to change from server to library application) and consistency, make sure you always install your serviced component assembly in the GAC.
You can provide .NET with an assembly attribute, specifying the name of the COM+ application you would like your components to be part of, by using the
ApplicationName assembly attribute:
[assembly: ApplicationName("MyApp")]
If you do not provide an application name, .NET uses the assembly name. The
ApplicationName attribute (and the rest of the serviced components attributes) is defined in the
System.EnterpriseServices namespace. You must add this namespace to your project references and reference that namespace in your assembly information file:
using System.EnterpriseServices;
Before exploring the three registration options, you need to understand the relationship between an assembly's version and COM+ components.
Every managed client of your assembly is built against the particular version of the assembly that contains your components, whether they are serviced or regular managed components. .NET zealously enforces version compatibility between the client's assembly and any other assembly it uses. The assembly's version is the product of its version number (major and minor numbers, such as 3.11) and the build and revision numbers. The version number is provided by the developer as an assembly attribute, and the build or revision numbers can be generated by the compiler--or the developer can provide them himself.
Related Reading
COM and .NET Component Services
The semantics of the version and build or revision numbers tell .NET whether two particular assembly versions are compatible with each other, and which of the two assemblies is the latest. Assemblies are compatible if the version number is the same. The default is that different build and revision numbers do not indicate incompatibility, but a difference in either major or minor number indicates incompatibility. A client's manifest contains the version of each assembly it uses. At runtime, .NET loads for the client the latest compatible assemblies to use, and latest is defined using the build and revision numbers.
All this is fine while everything is under tight control of the .NET runtime. But how would .NET guarantee compatibility between the assembly's version and the configuration of the serviced components in the COM+ Catalog? The answer is via the COM+ component's ID.
The first time a serviced component is added to a COM+ application, the registration process generates a CLSID for it, based on a hash of the class definition and its assembly's version and strong name. Subsequent registration of the same assembly with an incompatible version is considered a new registration for that serviced component, and the component is given a new CLSID.
This way, the serviced component's CLSID serves as its configuration settings version number. Existing managed clients do not interfere with one another because each gets to use the assembly version it was compiled with. Each managed client also uses a particular set of configuration parameters for the serviced components, captured with a different CLSID. When a managed client creates a serviced component, the .NET runtime creates for it a component from an assembly with a compatible version and applies the COM+ configuration of the matching CLSID.
To register your component manually, use the RegSvcs.exe command-line utility. (In the future, Visual Studio.NET will probably allow you to invoke RegSvcs from the visual environment itself.) RegSvcs accepts as a parameter the name of the file containing your assembly's metadata. In a single DLL assembly, that file is simply the assembly file. If you do not specify as an assembly attribute the name of the COM+ application that should host your components, RegSvcs must be told that name explicitly as a command-line parameter, using the
/appname: switch.
For example, if your single DLL assembly resides in MyAssembly.dll and you wish to add the serviced components in that assembly to the MyApp COM+ application, you would use RegSvcs in this manner:
RegSvcs.exe /appname:MyApp MyAssembly.dll
The command-line application name is ignored if the assembly contains an application name.
In any case, you must create that COM+ application in the Component Services Explorer beforehand; otherwise, the previous command line will fail. You can instruct RegSvcs to create the application for you using the
/c switch:
RegSvcs.exe /c MyApp MyAssembly.dll
Or if the name is specified in the assembly:
RegSvcs.exe /c MyAssembly.dll
When using the
/c switch, RegSvcs creates a COM+ application, names it accordingly, and adds the serviced components to it. If the Catalog already contains an application with that name, the registration fails.
You can also ask RegSvcs to try to find a COM+ application with that name and, if none is found, create one. This is done using the
/fc switch:
RegSvcs.exe /fc MyApp MyAssembly.dll
Or if the name is specified in the assembly:
RegSvcs.exe /fc MyAssembly.dll
If you don't specify a COM+ application name, either in the assembly or as a command-line parameter, RegSvcs uses the assembly name for the application name. If your assembly is called MyAssembly, RegSvcs adds the components to the MyAssembly COM+ application. This behavior is the same for all the command-line switches.
By default, RegSvcs does not override the existing COM+ application (and its components) settings. If that assembly version is already registered with that COM+ application, then RegSvcs does nothing. If that version is not registered yet, it adds the new version and assigns new CLSIDs. Reconfiguring an existing version is done explicitly using the
/reconfig switch:
RegSvcs.exe /reconfig /fc MyApp MyAssembly.dll
/reconfig switch causes RegSvcs to reapply any application, component, interface, and method attributes found in the assembly to the existing version and use the COM+ default settings for the rest, thus reversing any changes you made using the Component Services Explorer.
When RegSvcs adds a serviced component to the COM+ Catalog, it must give it a class-ID (CLSID) and a prog-ID. RegSvcs creates a GUID for every component (based on the assembly's version and the class definition) and names it
<Component name
>. For example, when you add the serviced component in Example 10-1 to the COM+ Catalog, RegSvcs names it MyNamespace.MyComponent. You can also specify the CLSID and the prog-ID of your serviced components using attributes.
In addition to adding the serviced components in the assembly to a COM+ application, RegSvcs creates a type library. This library contains interface and CoClass definitions to be used by nonmanaged clients (COM clients). The default type library filename is <Assembly name>.tlb--the name of the assembly with a .tlb extension.
When a managed client creates a serviced component, the .NET runtime resolves which assembly version to use for that client. Next, the runtime verifies that the required version is registered with COM+. If it is not registered, the runtime installs it automatically. This process is called dynamic registration. As with RegSvcs, if the assembly contains an application name, then that name is used; if it does not, then the assembly's name is used for the COM+ application's name.
Note that only .NET clients can rely on having dynamic registration done when they instantiate a .NET serviced component. For COM clients, you must use the RegSvcs utility. Another limitation of dynamic registration is that serviced components in the assembly are configured according to the attributes in the assembly and the COM+ defaults. If you require configuring some services (such as events subscriptions) using the Component Services Explorer for your application to function properly, you must use RegSvcs to register your components and provide the additional configuration using the Component Services Explorer. Only then can clients use your serviced components. As a result, dynamic registration is only useful for serviced components that contain all the service configurations they need in their code through the use of attributes. Finally, dynamic registration requires that the user invoking the call that triggers dynamic registration be a member of the Windows 2000 Administrator group. It has this requirement because dynamic registration makes changes to the COM+ Catalog; if the user invoking it is not a member of the Windows 2000 Administrator group, dynamic registration will fail.
In general, you should use RegSvcs and the Component Services Explorer rather than relying on dynamic registration. If you want to rely on dynamic registration of your serviced components, you should increment the version number of your assembly every time you make a change to one of the components' attributes, to ensure that you trigger dynamic registration.
Both RegSvcs and dynamic registration use a .NET class called
RegistrationHelper to perform the registration.
RegistrationHelper implements the
IRegistrationHelper interface, whose methods are used to register and unregister assemblies. For example, the
InstallAssembly( ) method registers the specified assembly in the specified COM+ application (or the application specified in the assembly). This method is defined as:
public void InstallAssembly(string assembly,
ref string application,
ref string tlb,
InstallationFlags installFlags );
The installation flags correspond to the various RegSvcs switches. See the MSDN Library for additional information on
RegistrationHelper. You can use
RegistrationHelper yourself as part of your installation program; for more information, see the section "Programming the COM+ Catalog" later in this chapter.
Every COM+ application has a GUID identifying it called the application ID. You can provide an assembly attribute specifying the application ID in addition to the application name:
[assembly: ApplicationID("8BE192FA-57D0-49a0-8608-6829A314EEBE")]
Unlike the application name, the application ID is guaranteed to be unique, and you can use it alongside the application name. Once an application ID is specified, all searches for the application during registration are done using the application ID only, and the application name is only useful as a human-readable form of the application identity. Using application ID comes in handy when deploying the assembly in foreign markets--you can provide a command-line localized application name for every market while using the same application ID for your administration needs internally. The
ApplicationID attribute is defined in the
System.EnterpriseServices namespace.
Instead of having the registration process generate a CLSID for your serviced component, you can specify one for it using the
Guid attribute:
using System.Runtime.InteropServices;
public class MyComponent :ServicedComponent,IMyInterface
Guid attribute is defined in the
System.Runtime.InteropServices namespace.
When you specify a class ID, subsequent registrations of the assembly don't generate a new CLSID for the component, regardless of the version of the assembly being registered. Registrations always reconfigure the same component in the COM+ Catalog. Specifying a class ID is useful during development, when you have multiple cycles of code-test-fix. Without it, every invocation by the test client triggers a dynamic registration--you very quickly clutter the COM+ application with dozens of components, when you actually only use the latest one.
Instead of having the registration process generate a name for your serviced component (namespace plus component name), you can specify one for it using the
ProgID attribute:
using System.Runtime.InteropServices;
[ProgId("My Serviced Component")]
public class MyComponent :ServicedComponent,IMyInterface
ProgId attribute is defined in the
System.Runtime.InteropServices namespace.
You can use various .NET attributes to configure your serviced components to take advantage of COM+ component services. The rest of this chapter demonstrates this service by service, according to the order in which the COM+ services are presented in this book.
To specify the COM+ application's activation type, you can use the
ApplicationActivation assembly attributes. You can request that the application be a library or a server application:
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationActivation(ActivationOption.Library)]
If you do not provide the
ApplicationActivation attribute, then .NET uses a library activation type by default. Note that this use differs from the COM+ default of creating a new application as a server application.
TIP: The next release of Windows 2000, Windows XP (see Appendix B), allows a COM+ application to be activated as a system service, so I expect that
ApplicationActivationwill be extended to include the value of
Before I describe other serviced components attributes, you need to understand what attributes are. Every .NET attribute is actually a class, and the attribute class has a constructor (maybe even a few overloaded constructors) and, usually, a few properties you can set. The syntax for declaring an attribute is different from that of any other class. In C#, you specify the attribute type between square brackets
[...]. You specify constructor parameters and the values of the properties you wish to set between parentheses
In the case of the
ApplicationActivation attribute, there are no properties and the constructor must accept an enum parameter of type
ActivationOption, defined as:
enum ActivationOption{Server,Library}
There is no default constructor for the
ApplicationActivation attribute.
ApplicationActivation attribute is defined in the
System.EnterpriseServices namespace. Your must add this namespace to your project references and reference that namespace in your assembly information file:
using System.EnterpriseServices;
The rest of this chapter assumes that you have added these references and will not mention them again.
TIP: A client assembly that creates a serviced component or uses any of its base class
ServicedComponentmethods must add a reference to
System.EnterpriseServicesto its project. Other clients, which only use the interfaces provided by your serviced components, need not add the reference.
Related Reading
COM and .NET Component Services
Description attribute allows you to add text to the description field on the General Properties tab of an application, component, interface, or method. Example 10-2 shows how to apply the
Description attribute at the assembly, class, interface, and method levels. After registration, the assembly-level description string becomes the content of the hosting COM+ application's description field; the class description string becomes the content of the COM+ component description field. The interface and method descriptions are mapped to the corresponding interface and method in the Component Services Explorer.
Example 10-2: Applying the Description attribute at the assembly, class, interface, and method levels
[assembly: Description("My Serviced Components Application")]
[Description("IMyInterface description")]
public interface IMyInterface
[Description("MyMethod description")]
void MyMethod( );
[Description("My Serviced Component description")]
public class MyComponent :ServicedComponent,IMyInterface
public void MyMethod( ){}
To access the COM+ context object's interfaces and properties, .NET provides you with the helper class
ContextUtil. All context object interfaces (including the legacy MTS interfaces) are implemented as public static methods and public static properties of the
ContextUtil class. Because the methods and properties are static, you do not have to instantiate a
ContextUtil object--you should just call the methods. For example, if you want to trace the current COM+ context ID (its GUID) to the Output window, use the
ContextId static property of
using System.Diagnostics;//For the Trace class
Guid contextID = ContextUtil.ContextId;
String traceMessage = "Context ID is " + contextID.ToString( );
ContextUtil has also properties used for JITA deactivation, transaction voting, obtaining the transactions and activity IDs, and obtaining the current transaction object. You will see examples for how to use these
ContextUtil properties later in this chapter.
You can decorate (apply attributes to) your class with two context-related attributes. The attribute
MustRunInClientContext informs COM+ that the class must be activated in its creator's context:
public class MyComponent :ServicedComponent
When you register the class above with COM+, the "Must be activated in caller's context" checkbox on the component's Activation tab is selected in the Component Services Explorer. If you do not use this attribute, the registration process uses the default COM+ setting when registering the component with COM+ --not enforcing same-context activation. As a result, using
MustRunInClientContext with a
false parameter passed to the constructor is the same as using the COM+ default:
Using attributes with the COM+ default values (such as constructing the
MustRunInClientContext attribute with
false) is useful when you combine it with the
/reconfig switch of RegSvcs. For example, you can undo any unknown changes made to your component configuration using the Component Services Explorer and restore the component configuration to a known state.
MustRunInClientContext attribute class has an overloaded default constructor. If you use
MustRunInClientContext with no parameters, the default constructor uses
true for the attribute value. As a result, the following two statements are equivalent:
The second COM+ context-related attribute is the
EventTrackingEnabled attribute. It informs COM+ that the component supports events and statistics collection during its execution:
public class MyComponent2:ServicedComponent
The statistics are displayed in the Component Services Explorer. When you register this class with COM+, the "Component supports events and statistics" checkbox on the component's Activation tab is checked in the Component Services Explorer. If you do not use this attribute, the registration process does not use the default COM+ setting of supporting events when registering the component with COM+. The .NET designers made this decision consciously to minimize creation of new COM+ contexts for new .NET components; a component that supports statistics is usually placed in it own context.
EventTrackingEnabled attribute class also has an overloaded default constructor. If you construct it with no parameters, the default constructor uses
true for the attribute value. As a result, the following two statements are equivalent:
ObjectPooling attribute is used to configure every aspect of your component's object pooling. The
ObjectPooling attribute enables or disables object pooling and sets the minimum or maximum pool size and object creation timeout. For example, to enable object pooling of your component's objects with a minimum pool size of 3, a maximum pool size of 10, and a creation timeout of 20 milliseconds, you would write:
[ObjectPooling(MinPoolSize = 3,MaxPoolSize = 10,CreationTimeout = 20)]
public class MyComponent :ServicedComponent
Related Reading
COM and .NET Component Services
MaxPoolSize, and
CreationTimeout properties are public properties of the
ObjectPooling attribute class. If you do not specify values for these properties (all or just a subset) when your component is registered, the default COM+ values are used for these properties (a minimum pool size of 0, a maximum pool size of 1,048,576, and a creation timeout of 60 seconds).
ObjectPooling attribute has a Boolean property called the
Enabled property. If you do not specify a value for it (
true or
false), the attribute's constructor sets it to
true. In fact, the attribute's constructor has a few overloaded versions--a default constructor that sets the
Enabled property to
true and a constructor that accepts a Boolean parameter. All constructors set the pool parameters to the default COM+ value. As a result, the following three statements are equivalent:
[ObjectPooling(Enabled = true)]
TIP: If your pooled component is hosted in a library application, then each hosting Application Domain will have its own pool. As a result, you may have multiple pools in a single physical process, if that process hosts multiple Application Domains.
Under COM, the pooled object returns to the pool when the client releases its reference to it. Managed objects do not have reference counting--.NET uses garbage collection instead. A managed pooled object returns to the pool only when it is garbage collected. The problem with this behavior is that a substantial delay between the time the object is no longer needed by its client and the time the object returns to the pool can occur. This delay may have serious adverse effects on your application scalability and throughput. An object is pooled because it was expensive to create. If the object spends a substantial portion of its time waiting for the garbage collector, your application benefits little from object pooling.
There are two ways to address this problem. The first solution uses COM+ JITA (discussed next). When you use JITA, the pooled object returns to the pool after every method call from the client. The second solution requires client participation.
ServicedComponent has a public static method called
DisposeObject( ), defined as:
public static void DisposeObject(ServicedComponent sc);
When the client calls
DisposeObject( ), passing in an instance of a pooled serviced component, the object returns to the pool immediately.
DisposeObject( ) has the effect of notifying COM+ that the object has been released. Besides returning the object to the pool,
DisposeObject( ) disposes of the context object hosting the pooled object and of the proxy the client used.
For example, if the component definition is:
public interface IMyInterface
void MyMethod( );
public class MyComponent : ServicedComponent,IMyInterface
public void MyMethod( ){}
When the client is done using the object, to expedite returning the object to the pool, the client should call
DisposeObject( ):
IMyInterface obj;
Obj = (IMyInterface) new MyComponent( );
obj.MyMethod( );
ServicedComponent sc = obj as ServicedComponent;
If(sc != null)
However, calling
DisposeObject( ) directly is ugly. First, the client has to know that it is dealing with an object derived from
ServicedComponent, which couples the client to the type used and renders many benefits of interface-based programming useless. Even worse, the client only has to call
DisposeObject( ) if this object is pooled, which couples the client to the serviced component's configuration. What if you use object pooling in only one customer site, but not in others? This situation is a serious breach of encapsulation--the core principle of object-oriented programming.
The solution is to have
ServicedComponent implement a special interface (defined in the
System namespace) called
IDisposable, defined as:
public interface IDisposable
void Dispose( );
ServicedComponent implementation of
Dispose( ) returns the pooled object to the pool.
Having the
Dispose( ) method on a separate interface allows the client to query for the presence of
IDisposable and always call it, regardless of the object's actual type:
IMyInterface obj;
obj = (IMyInterface) new MyComponent( );
obj.MyMethod( );
//Client wants to expedite whatever needs expediting:
IDisposable disposable = obj as IDisposable;
if(disposable != null)
disposable.Dispose( );
IDisposable technique is useful not only with serviced components, but also in numerous other places in .NET. Whenever your component requires deterministic disposal of the resources and memory it holds,
IDisposable provides a type-safe, component-oriented way of having the client dispose of the object without being too coupled to its
.NET managed components can use COM+ JITA to efficiently handle rich clients (such as .NET Windows Forms clients), as discussed in Chapter 3.
To enable JITA support for your component, use the
JustInTimeActivation attribute:
public class MyComponent :ServicedComponent
When you register this component with COM+, the JITA checkbox in the Activation tab on the Component Services Explorer is selected. If you do not use the
JustInTimeActivation attribute, JITA support is disabled when you register your component with COM+ (unlike the COM+ default of enabling JITA). The
JustInTimeActivation class default constructor enables JITA support, so the following two statements are equivalent:
[JustInTimeActivation (true)]
Enabling JITA support is just one thing you need to do to use JITA. You still have to let COM+ know when to deactivate your object. You can deactivate the object by setting the done bit in the context object, using the
DeactivateOnReturn property of the
ContextUtil class. As discussed at length in Chapter 3, a JITA object should retrieve its state at the beginning of every method call and save it at the end. Example 10-3 shows a serviced component using JITA.
Example 10-3: A serviced component using JITA
public interface IMyInterface
void MyMethod(long objectIdentifier);
public class MyComponent :ServicedComponent,IMyInterface
public void MyMethod(long objectIdentifier)
DoWork( );
//inform COM+ to deactivate the object upon method return
ContextUtil.DeactivateOnReturn = true;
//other methods
protected void GetState(long objectIdentifier){...}
protected void DoWork( ){...}
protected void SaveState(long objectIdentifier){...}
You can also use the Component Services Explorer to configure the method to use auto-deactivation. In that case, the object is deactivated automatically upon method return, unless you set the value of the
DeactivateOnReturn property to
If your serviced component uses object pooling or JITA (or both), it may also need to know when it is placed in a COM+ context to do context-specific initialization and cleanup. Like a COM+ configured component, the serviced component can use
IObjectControl for that purpose. The .NET base class
ServicedComponent already implements
IObjectControl, and its implementation is virtual--so you can override the implementation in your serviced component, as shown in Example 10-4.
Example 10-4: A serviced component overriding the ServicedComponent implementation of IObjectControl
public class MyComponent :ServicedComponent
public override void Activate( )
//Do context specific initialization here
public override void Deactivate( )
//Do context specific cleanup here
public override bool CanBePooled( )
return true;
//other methods
If you encounter an error during
Activate( ) and throw an exception, then the object's activation fails and the client is given an opportunity to catch the exception.
To maintain JITA semantics, when the object deactivates itself, .NET calls
DisposeObject( ) on it explicitly, thus destroying it. Your object can do specific cleanup in the
Finalize( ) method (the destructor in C#), and
Finalize( ) will be called as soon as the object deactivates itself, without waiting for garbage collection. If the object is a pooled object (as well as a JITA object), then it is returned to the pool after deactivation, without waiting for the garbage collection.
You can also override the
ServicedComponent implementation of
IObjectControl.Deactivate( ) and perform your cleanup there.
In any case, you end up with a deterministic way to dispose of critical resources without explicit client participations. This situation makes sharing your object among clients much easier because now the clients do not have to coordinate who is responsible for calling
Dispose( ).
TIP: COM+ JITA gives managed components deterministic finalization, a service that nothing else in .NET can provide out of the box.
Any COM+ configured component that implements the
IObjectConstruct interface has access during construction to a construction string (discussed in Chapter 3), configured in the Component Services Explorer. Serviced components are no different. The base class,
ServicedComponent, already implements the
IObjectConstruct interface as a virtual method (it has only one method). Your derived serviced component can override the
Construct( ) method, as shown in this code sample:
public class MyComponent :ServicedComponent
public override void Construct(string constructString)
//use the string. For example:
If the checkbox "Enable object construction" on the component Activation tab is selected, then the
Construct( ) method is called after the component's constructor, providing it with the configured construction string.
You can also enable construction string support and provide a default construction string using the
ConstructionEnabled attribute:
[ConstructionEnabled(Enabled = true,Default = "My String")]
public class MyComponent :ServicedComponent
public override void Construct(string constructString)
ConstructionEnabled attribute has two public properties.
Enabled enables construction string support for your serviced component in the Component Services Explorer (once the component is registered) and
Default provides an initial string value. When your component is registered with COM+, the registration process assigns the default string to the constructor string field on the component Activation tab. The default string has no further use after registration. New instances of your component receive as a constructor string the current value of the constructor string field. For example, if the default string is String A, when the serviced component is registered, the value of the constructor string field is set to String A. If you set it to a different value, such as String B, new instances of the component get String B as their construction string. They receive the current value, not the default value.
ConstructionEnabled attribute has two overloaded constructors. One constructor accepts a Boolean value for the
Enabled property; the default constructor sets the value of the
Enabled property to
true. You can also set the value of the
Enabled property explicitly. As a result, the following three statements are equivalent:
[ConstructionEnabled(Enabled = true)]
You can configure your serviced component to use the five available COM+ transaction support options by using the
Transaction attribute. The
Transaction attribute's constructor accepts an enum parameter of type
TransactionOption, defined as:
public enum TransactionOption
For example, to configure your serviced component to require a transaction, use the
TransactionOption.Required value:
public class MyComponent :ServicedComponent
The five enum values of
TransactionOption map to the five COM+ transaction support options discussed in Chapter 4.
When you use the
Transaction attribute to mark your serviced component to use transactions, you implicitly set it to use JITA and require activity-based synchronization as well.
Transaction attribute has an overloaded default constructor, which sets the transaction support to
TransactionOption.Required. As a result, the following two statements are equivalent:
Not surprisingly, you use the
ContextUtil class to vote on the transaction's outcome.
ContextUtil has a static property of the enum type
TransactionVote called
TransactionVote is defined as:
public enum TransactionVote {Abort,Commit}
Example 10-5 shows a transactional serviced component voting on its transaction outcome using
ContextUtil. Note that the component still has to do all the right things that a well-designed transactional component has to do (see Chapter 4); it needs to retrieve its state from a resource manager at the beginning of the call and save it at the end. It must also deactivate itself at the end of the method to purge its state and make the vote take effect.
Example 10-5: A transactional serviced component voting on its transaction outcome using the ContextUtil MyTransactionVote property
public interface IMyInterface
void MyMethod(long objectIdentifier);
public class MyComponent :ServicedComponent,IMyInterface
public void MyMethod(long objectIdentifier)
DoWork( );
ContextUtil.MyTransactionVote = TransactionVote.Commit;
ContextUtil.MyTransactionVote = TransactionVote.Abort;
//Let COM+ deactivate the object once the method returns
ContextUtil.DeactivateOnReturn = true;
//helper methods
protected void GetState(long objectIdentifier){...}
protected void DoWork( ){...}
protected void SaveState(long objectIdentifier){...}
Related Reading
COM and .NET Component Services
Compare Example 10-5 to Example 4-3. A COM+ configured component uses the returned
HRESULT from the
DoWork( ) helper method to decide on the transaction's outcome. A serviced component, like any other managed component, does not use
HRESULT return codes for error handling; it uses exceptions instead. In Example 10-5 the component catches any exception that was thrown in the
try block by the
DoWork( ) method and votes to abort in the
catch block.
Alternatively, if you do not want to write exception-handling code, you can use the programming model shown in Example 10-6. Set the context object's consistency bit to
false (vote to abort) as the first thing the method does. Then set it back to
true as the last thing the method does (vote to commit). Any exception thrown in between causes the method exception to end without voting to commit.
Example 10-6: Voting on the transaction without exception handling
public interface IMyInterface
void MyMethod(long objectIdentifier);
public class MyComponent :ServicedComponent,IMyInterface
public void MyMethod(long objectIdentifier)
//Let COM+ deactivate the object once the method returns and abort the
//transaction. You can use ContextUtil.SetAbort( ) as well
ContextUtil.DeactivateOnReturn = true;
ContextUtil.MyTransactionVote = TransactionVote.Abort;
DoWork( );
ContextUtil.MyTransactionVote = TransactionVote.Commit;
//helper methods
protected void GetState(long objectIdentifier){...}
protected void DoWork( ){...}
protected void SaveState(long objectIdentifier){...}
Example 10-6 has another advantage over Example 10-5: having the exception propagated up the call chain once the transaction is aborted. By propagating it, callers up the chain know that they can also abort their work and avoid wasting more time on a doomed transaction.
Your serviced components can take advantage of COM+ method auto-deactivation using the
AutoComplete method attribute. During the registration process, the method is configured to use COM+ auto-deactivation when
AutoComplete is used on a method, and the checkbox "Automatically deactivate this object when the method returns" on the method's General tab is selected. Serviced components that use the
AutoComplete attribute do not need to vote explicitly on their transaction outcome. Example 10-7 shows a transactional serviced component using the
AutoComplete method attribute.
Example 10-7: Using the AutoComplete method attribute
public interface IMyInterface
void MyMethod(long objectIdentifier);
public class MyComponent : ServicedComponent,IMyInterface
public void MyMethod(long objectIdentifier)
DoWork( );
//helper methods
protected void GetState(long objectIdentifier){...}
protected void DoWork( ){...}
protected void SaveState(long objectIdentifier){...}
When you configure the method to use auto-deactivation, the object's interceptor sets the done and consistency bits of the context object to
true if the method did not throw an exception and the consistency bit to
false if it did. As a result, the transaction is committed if no exception is thrown and aborted otherwise.
Nontransactional JITA objects can also use the
AutoComplete attribute to deactivate themselves automatically on method return.
AutoComplete attribute has an overloaded default constructor that uses
true for the attribute construction. Consequently, the following two statements are equivalent:
AutoComplete attribute can be applied on a method as part of an interface definition:
public interface IMyInterface
//Avoid this:
void MyMethod(long objectIdentifier);
However, you should avoid using the attribute this way. An interface and its methods declarations serve as a contract between a client and an object; using auto completion of methods is purely an implementation decision. For example, one implementation of the interface on one component may chose to use autocomplete and another implementation on another component may choose not to.
Related Reading
COM and .NET Component Services
A nontransactional managed client creating a few transactional objects faces a problem discussed in Chapter 4 (see the section "Nontransactional Clients"). Essentially, if the client wants to scope all its interactions with the objects it creates under one transaction, it must use a middleman to create the objects for it. Otherwise, each object created will be in its own separate transaction. COM+ provides a ready-made middleman called
TransactionContext. Managed clients can use
TransactionContext as well. To use the
TransactionContext object, add to the project references the COM+ services type library. The
TransactionContext class is in the
COMSVCSLib namespace.
TransactionContext class is especially useful in situations in which the class is a managed .NET component that derives from a class other than
ServicedComponent. Remember that a .NET component can only derive from one concrete class and since the class already derives from a concrete class other than
ServicedComponent, it cannot use the
Transaction attribute. Nevertheless, the
TransactionContext class gives this client an ability to initiate and manage a transaction.
Example 10-8 demonstrates usage of the
TransactionContext class, using the same use-case as Example 4-6.
Example 10-8: A nontransactional managed client using the TransactionContext helper class to create other transactional objects
using COMSVCSLib;
IMyInterface obj1,obj2,obj3;
ITransactionContext transContext;
transContext = (ITransactionContext) new TransactionContext( );
obj1 = (IMyInterface)transContext.CreateInstance("MyNamespace.MyComponent");
obj2 = (IMyInterface)transContext.CreateInstance("MyNamespace.MyComponent");
obj3 = (IMyInterface)transContext.CreateInstance("MyNamespace.MyComponent");
obj1.MyMethod( );
obj2.MyMethod( );
obj3.MyMethod( );
transContext.Commit( );
catch//Any error - abort the transaction
transContext.Abort( );
Note that the client in Example 10-8 decides whether to abort or commit the transaction depending on whether an exception is thrown by the internal objects.
Though this chapter focuses on serviced components, it is worth noting that COM+ transactions are used by other parts of the .NET framework besides serviced components--in particular, ASP.NET and Web Services.
Web services are the most exciting piece of technology in the entire .NET framework. Web services allow a middle-tier component in one web site to invoke methods on another middle-tier component at another web site, with the same ease as if that component were in its own assembly. The underlying technology facilitating web services serializes the calls into text format and transports the call from the client to the web service provider using HTTP. Because web service calls are text based, they can be made across firewalls. Web services typically use a protocol called Simple Object Access Protocol (SOAP) to represent the call, although other text-based protocols such as HTTP-POST and HTTP-GET can also be used. .NET successfully hides the required details from the client and the server developer; a web service developer only needs to use the
WebMethod attribute on the public methods exposed as web services. Example 10-9 shows the
MyWebService web service that provides the
MyMessage web service--it returns the string "Hello" to the caller.
Example 10-9: A trivial web service that returns the string "Hello"
using System.Web.Services;
public class MyWebService : WebService
public MyWebService( ){}
public string MyMessage( )
return "Hello";
The web service class can optionally derive from the
WebService base class, defined in the
System.Web.Services namespace (see Example 10-9). The
WebService base class provides you with easy access to common ASP.NET objects, such as those representing application and session states. Your web service probably accesses resource managers and transactional components. The problem with adding transaction support to a web service that derived from
WebService is that it is not derived from
ServicedComponent, and .NET does not allow multiple inheritance of implementation.
To overcome this hurdle, the
WebMethod attribute has a public property called
TransactionOption, of the enum type
Enterprise.Services.TransactionOption discussed previously.
The default constructor of the
WebMethod attribute sets this property to
TransactionOption.Disabled, so the following two statements are equivalent:
[WebMethod(TransactionOption = TransactionOption.Disabled)]
If your web service requires a transaction, it can only be the root of a transaction, due to the stateless nature of the HTTP protocol. Even if you configure your web method to only require a transaction and it is called from within the context of an existing transaction, a new transaction is created for it. Similarly, the value of
TransactionOption.Supported does not cause a web service to join an existing transaction (if called from within one).
Consequently, the following statements are equivalent--all four amount to no transaction support for the web service:
[WebMethod(TransactionOption = TransactionOption.Disabled)]
[WebMethod(TransactionOption = TransactionOption.NotSupported)]
[WebMethod(TransactionOption = TransactionOption.Supported)]
Moreover, the following statements are also equivalent--creating a new transaction for the web service:
[WebMethod(TransactionOption = TransactionOption.Required)]
[WebMethod(TransactionOption = TransactionOption.RequiresNew)]
The various values of
TransactionOption are confusing. To avoid making them the source of errors and misunderstandings, use
TransactionOption.RequiresNew when you want transaction support for your web method; use
TransactionOption.Disabled when you want to explicitly demonstrate to a reader of your code that the web service does not take part in a transaction. The question is, why did Microsoft provide four overlapping transaction modes for web services? I believe that it is not the result of carelessness, but rather a conscious design decision. Microsoft is probably laying down the foundation in .NET for a point in the future when it will be possible to propagate transactions across web sites.
Finally, you do not need to explicitly vote on a transaction from within a web service. If an exception occurs within a web service method, the transaction is automatically aborted. Conversely, if no exceptions occur, the transaction is committed automatically (as if you used the
AutoComplete attribute). Of course, the web service can still use
ContextUtil to vote explicitly to abort instead of throwing an exception, or when no exception occurred and you still want to abort.
An ASP.NET web form may access resource managers (such as databases) directly, and it should do so under the protection of a transaction. The page may also want to create a few transactional components and compose their work into a single transaction. The problem again is that a web form derives from the
Page base class, not from
ServicedComponent, and therefore cannot use the
[Transaction] attribute.
To provide transaction support for a web form, the Page base class has a write-only property called
TransactionMode of type
TransactionOption. You can assign a value of type
TransactionOption to
TransactionMode, to configure transaction support for your web form. You can assign
TransactionMode programmatically in your form contractor, or declaratively by setting that property in the visual designer. The designer uses the Transaction page directive to insert a directive in the aspx form file. For example, if you set the property using the designer to
RequiresNew, the designer added this line to the beginning of the aspx file:
<@% Page Transaction="RequiresNew" %>
Be aware that programmatic setting will override any designer setting. The default is no transaction support (disabled).
The form can even vote on the outcome of the transaction (based on its interaction with the components it created) by using the
ContextUtil methods. Finally, the form can subscribe to events notifying it when a transaction is initiated and when a transaction is aborted.
Multithreaded managed components can use .NET-provided synchronization locks. These are classic locks, such as mutexes and events. However, these solutions all suffer from the deficiencies described at the beginning of Chapter 5. .NET serviced components should use COM+ activity-based synchronization by adding the
Synchronization attribute to the class definition. The
Synchronization attribute's constructor accepts an enum parameter of type
SynchronizationOption, defined as:
public enum SynchronizationOption
For example, use the
SynchronizationOption.Required value to configure your serviced component to require activity-based synchronization:
public class MyComponent :ServicedComponent
The five enum values of
SynchronizationOption map to the five COM+ synchronization support options discussed in Chapter 5.
Synchronization attribute has an overloaded default constructor, which sets synchronization support to
SynchronizationOption.Required. As a result, the following two statements are equivalent:
TIP: The
System.Runtime.Remoting.Contextnamespace contains a context attribute called
Synchronizationthat can be applied to context-bound .NET classes. This attribute accepts synchronization flags similar to
SynchronizationOption, and initially looks like another version of the
Synchronizationclass attribute. However, the
Synchronizationattribute in the
Contextnamespace provides synchronization based on physical threads, unlike the
Synchronizationattribute in the
EnterpriseServicesnamespace, which uses causalities. As explained in Chapter 5, causality and activities are a more elegant and fine-tuned synchronization strategy.
Related Reading
COM and .NET Component Services
You can access the COM+ Catalog from within any .NET managed component (not only serviced components). To write installation or configuration code (or manage COM+ events), you need to add to your project a reference to the COM+ Admin type library. After you add the reference, the Catalog interfaces and objects are part of the
COMAdmin namespace. Example 10-10 shows how to create a catalog object and use it to iterate over the application collection, tracing to the Output window the names of all COM+ applications on your computer.
Example 10-10: Accessing the COM+ Catalog and tracing the COM+ application names
using COMAdmin;
ICOMAdminCatalog catalog;
ICatalogCollection applicationCollection;
ICatalogObject application;
int applicationCount;
int i;//Application index
catalog = (ICOMAdminCatalog)new COMAdminCatalog( );
applicationCollection = (ICatalogCollection)catalog.GetCollection("Applications");
//Read the information from the catalog
applicationCollection.Populate( );
applicationCount = applicationCollection.Count;
for(i = 0;i< applicationCount;i++)
//Get the current application
application= (ICatalogObject)applicationCollection.get_Item(i);
int index = i+1;
String traceMessage = index.ToString()+". "+application.Name.ToString( );
TIP: The
System.EnterpriseServices.Adminnamespace contains the COM+ Catalog object and interface definitions. However, in the Visual Studio.NET Beta 2, the interfaces are defined as private to that assembly. As a result, you cannot access them. The obvious workaround is to import the COM+ Admin type library yourself, as demonstrated in Example 10-10. In the future, you will probably be able to use
System.EnterpriseServices.Adminnamespace directly. The resulting code, when programming directly using the
System.EnterpriseServices.Adminnamespace, is almost identical to Example 10-10.
.NET has an elaborate component-oriented security model. .NET security model manages what the component is allowed to do and what permissions are given to the component and all its clients up the call chain. You can (and should) still manage the security attributes of your hosting COM+ application to authenticate incoming calls, authorize callers, and control impersonation level.
.NET also has what .NET calls role-based security, but that service is limited compared with COM+ role-based security. A role in .NET is actually a Windows NT user group. As a result, .NET role-based security is only as granular as the user groups in the hosting domain. Usually, you do not have control over your end customer's IT department. If you deploy your application in an environment where the user groups are coarse, or where they do not map well to actual roles users play in your application, then .NET role-based security is of little use to you. COM+ roles are unrelated to the user groups, allowing you to assign roles directly from the application business domain.
The assembly attribute
ApplicationAccessControl is used to configure all the settings on the hosting COM+ application's Security tab.
You can use
ApplicationAccessControl to turn application-level authentication on or off:
[assembly: ApplicationAccessControl(true)]
ApplicationAccessControl attribute has a default constructor, which sets authorization to
true if you do not provide a construction value. Consequently, the following two statements are equivalent:
[assembly: ApplicationAccessControl]
[assembly: ApplicationAccessControl(true)]
If you do not use the
ApplicationAccessControl attribute at all, then when you register your assembly, the COM+ default takes effect and application-level authorization is turned off.
ApplicationAccessControl attribute has three public properties you can use to set the access checks, authentication, and impersonation level. The
AccessChecksLevel property accepts an enum parameter of type
AccessChecksLevelOption, defined as:
public enum AccessChecksLevelOption
AccessChecksLevel is used to set the application-level access checks to the process only (
AccessChecksLevelOption.Application) or process and component level (
AccessChecksLevelOption.ApplicationComponent). If you do not specify an access level, then the
ApplicationAccessControl attribute's constructors set the access level to
AccessChecksLevelOption.ApplicationComponent, the same as the COM+ default.
Authentication property accepts an enum parameter of type
AuthenticationOption, defined as:
public enum AuthenticationOption
The values of
AuthenticationOption map to the six authentication options discussed in Chapter 7. If you do not specify an authentication level or if you use the
Default value, the
ApplicationAccessControl attribute's constructors set the authentication level to
AuthenticationOption.Packet, the same as the COM+ default.
Impersonation property accepts an enum parameter of type
ImpersonationLevelOption, defined as:
public enum ImpersonationLevelOption
The values of
ImpersonationLevelOption map to the four impersonation options discussed in Chapter 7. If you do not specify an impersonation level or if you use the
Default value, then the
ApplicationAccessControl attribute's constructors set the impersonation level to
ImpersonationLevelOption.Impersonate, the same as the COM+ default.
Example 10-11 demonstrates using the
ApplicationAccessControl attribute with a server application. The example enables application-level authentication and sets the security level to perform access checks at the process and component level. It sets authentication to authenticate incoming calls at the packet level and sets the impersonation level to
Example 10-11: Configuring a server application security
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(
true,//Authentication is on
A library COM+ application has no use for impersonation level, and it can only choose whether it wants to take part in its hosting process authentication level (that is, it cannot dictate the authentication level). To turn authentication off for a library application, set the authentication property to
AuthenticationOption.None. To turn it on, use any other value, such as
AuthenticationOption.Packet. Example 10-12 demonstrates how to use the
ApplicationAccessControl to configure the security setting of
a library application.
Example 10-12: Configuring a library application security
[assembly: ApplicationActivation(ActivationOption.Library)]
[assembly: ApplicationAccessControl(
//use AuthenticationOption.None to turn off authentication,
//and any other value to turn it on
The component attribute
ComponentAccessControl is used to enable or disable access checks at the component level. Recall from Chapter 7 that this is your component's role-based security master switch. The
ComponentAccessControl attribute's constructor accepts a Boolean parameter, used to turn access control on or off. For example, you can configure your serviced component to require component-level access checks:
public class MyComponent :ServicedComponent
ComponentAccessControl attribute has an overloaded default constructor that uses
true for the attribute construction. Consequently, the following two statements are equivalent:
Related Reading
COM and .NET Component Services
You can use the Component Services Explorer to add roles to the COM+ application hosting your serviced components. You can also use the
SecurityRole attribute to add the roles at the assembly level. When you register the assembly with COM+, the roles in the assembly are added to the roles defined for the hosting COM+ application. For example, to add the Manager and Teller roles to a bank application, simply add the two roles as assembly attributes:
[assembly: SecurityRole("Manager")]
[assembly: SecurityRole("Teller")]
SecurityRole attribute has two public properties you can set. The first is
Description. Any text assigned to the
Description property will show up in the Component Services Explorer in the Description field on the role's General tab:
[assembly: SecurityRole("Manager",Description = "Can access all components")]
[assembly: SecurityRole("Teller",Description = "Can access IAccountsManager only")]
The second property is the
SetEveryoneAccess Boolean property. If you set
SetEveryoneAccess to
true, then when the component is registered, the registration process adds the user Everyone as a user for that role, thus allowing everyone access to whatever the role is assigned to. If you set it to
false, then no user is added during registration and you have to explicitly add users during deployment using the Component Services Explorer. The
SecurityRole attribute sets the value of
SetEveryoneAccess by default to
true. As a result, the following statements are equivalent:
[assembly: SecurityRole("Manager")]
[assembly: SecurityRole("Manager",true)]
[assembly: SecurityRole("Manager",SetEveryoneAccess = true)]
Automatically granting everyone access is a nice debugging feature; it eliminates security problems, letting you focus on analyzing your domain-related bug. However, you must suppress granting everyone access in a release build, by setting the
SetEveryoneAccess property to
#if DEBUG
[assembly: SecurityRole("Manager")]
[assembly: SecurityRole("Manager",SetEveryoneAccess = false)]
SecurityRole attribute is also used to grant access for a role to a component, interface, or method. Example 10-13 shows how to grant access to Role1 at the component level, to Role2 at the interface level, and to Role3 at the method level.
Example 10-13: Assigning roles at the component, interface, and method levels
[assembly: SecurityRole("Role1")]
[assembly: SecurityRole("Role2")]
[assembly: SecurityRole("Role3")]
interface IMyInterface
void MyMethod( );
public class MyComponent :ServicedComponent,IMyInterface
Figure 10-2 shows the resulting role assignment in the Component Services Explorer at the method level. Note that Role1 and Role2 are inherited from the component and interface levels.
If you only assign a role (at the component, interface, or method level) but do not define it at the assembly level, then that role is added to the application automatically during registration. However, you should define roles at the assembly level to provide one centralized place for roles description and
Sometimes it
is useful to verify programmatically the caller's role membership before granting it access. Your serviced components can do that just as easily as configured COM components. .NET provides you the helper class
SecurityCallContext that gives you access to the security parameters of the current call.
SecurityCallContext encapsulates the COM+ call-object's implementation of
ISecurityCallContext, discussed in Chapter 7. The class
SecurityCallContext has a public static property called
CurrentCall is a read-only property of type
SecurityCallContext (it returns an instance of the same type). You use the
SecurityCallContext object returned from
CurrentCall to access the current call. Example 10-14 demonstrates the use of the security call context to verify a caller's role membership, using the same use-case as Example 7-1.
Example 10-14: Verifying the caller's role membership using the SecurityCallContext class
public class Bank :ServicedComponent,IAccountsManager
void TransferMoney(int sum,ulong accountSrc,ulong accountDest)
bool callerInRole = false;
callerInRole = SecurityCallContext.CurrentCall.IsCallerInRole("Customer");
if(callerInRole)//The caller is a customer
if(sum > 5000)
throw(new UnauthorizedAccessException(@"Caller does not have sufficient
credentials to transfer this sum"));
DoTransfer(sum,accountSrc,accountDest);//Helper method
//Other methods
You should use the Boolean property
IsSecurityEnabled of
SecurityCallContext to verify that security is enabled before accessing the
IsCallerInRole( ) method:
bool securityEnabled = SecurityCallContext.CurrentCall.IsSecurityEnabled;
//the rest of the verification process
Related Reading
COM and .NET Component Services
.NET has a built-in mechanism for invoking a method call on an object: using a delegate asynchronously. The client creates a delegate class that wraps the method it wants to invoke synchronously, and the compiler provides definition and implementation for a
BeginInvoke( ) method, which asynchronously calls the required method on the object. The compiler also generates the
EndInvoke( ) method to allow the client to poll for the method completion. Additionally, .NET provides a helper class called
AsyncCallback to manage asynchronous callbacks from the object once the call is done.
Compared with COM+ queued components, the .NET approach leaves much to be desired. First, .NET does not support disconnected work. Both the client and the server have to be running at the same time, and their machines must be connected to each other on the network. Second, the client's code in the asynchronous case is very different from the usual synchronous invocation of the same method on the object's interface. Third, there is no built-in support for transactional forwarding of calls to the server, nor is there an auto-retry mechanism. In short, you should use COM+ queued components if you want to invoke asynchronous method calls in .NET.
ApplicationQueuing assembly attribute is used to configure queuing support for the hosting COM+ application. The
ApplicationQueuing attribute has two public properties that you can set. The Boolean
property corresponds to the Queued checkbox on the application's queuing tab. When set to
true, it instructs COM+ to create a public message queue, named as the application, for the use of any queued components in the assembly. The second public property of
ApplicationQueuing is the Boolean
QueueListenerEnabled property. It corresponds to the Listen checkbox on the application's queuing tab. When set to
true, it instructs COM+ to activate a listener for the application when the application is launched. For example, here is how you enable queued component support for your application and enable a listener:
//Must be a server application to use queued components
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationQueuing(Enabled = true,QueueListenerEnabled = true)]
ApplicationQueuing attribute has an overloaded default constructor that sets the
Enabled attribute to
true and the
QueueListenerEnabled attribute to
false. As a result, the following two statements are equivalent:
[assembly: ApplicationQueuing]
[assembly: ApplicationQueuing(Enabled = true,QueueListenerEnabled = false)]
In addition to enabling queued component support at the application level, you must mark your interfaces as capable of receiving queued calls. You do that by using the
InterfaceQueuing attribute.
InterfaceQueuing has one public Boolean property called
Enabled that corresponds to the Queued checkbox on the interface's Queuing tab.
[InterfaceQueuing(Enabled = true)]
public interface IMyInterface
void MyMethod( );
InterfaceQueuing attribute has an overloaded default constructor that sets the
Enabled property to
true and a constructor that accepts a Boolean parameter. As a result, the following three statements are equivalent:
[InterfaceQueuing(Enabled = true)]
Note that your interface must adhere to the queued components design guidelines discussed in Chapter 8, such as no
out or
ref parameters. If you configure your interface as a queued interface using the
InterfaceQueuing attribute and the interface is incompatible with queuing requirements, the registration process fails.
The client of a queued component cannot create the queued component directly. It must create a recorder for its calls using the
queue moniker. A C++ or a Visual Basic 6.0 program uses the
CoGetObject( ) or
GetObject( ) calls. A .NET managed client can use the static method
BindToMoniker( ) of the
Marshal class, defined as:
public static object BindToMoniker(string monikerName);
BindToMoniker( ) accepts a moniker string as a parameter and returns the corresponding object. The
Marshal class is defined in the
System.Runtime.InteropServices namespace.
BindToMoniker( ) method of the
Marshal class makes writing managed clients for a queued component as easy as if it were a COM client:
using System.Runtime.InteropServices;//for the Marshal class
IMyInterface obj;
obj =(IMyInterface)Marshal.BindToMoniker("queue:/new:MyNamespace.MyComponent");
obj.MyMethod( );//call is recorded
In the case of a COM client, the recorder records the calls the client makes. The recorder only dispatches them to the queued component queue (more precisely, to its application's queue) when the client releases the recorder. A managed client does not use reference counting, and the recorded calls are dispatched to the queued component queue when the managed wrapper around the recorder is garbage collected. The client can expedite dispatching the calls by explicitly forcing the managed wrapper around the recorder to release it, using the static
DisposeObject( ) method of the
ServicedComponent class, passing in the recorder object:
using System.Runtime.InteropServices;//for the Marshal class
IMyInterface obj;
obj =(IMyInterface)Marshal.BindToMoniker("queue:/new:MyNamespace.MyComponent");
obj.MyMethod( );//call is recorded
//Expedite dispatching the recorded calls by disposing of the recorder
ServicedComponent sc = obj as ServicedComponent;
If(sc !=null)
You can use the
IDisposable interface instead of calling
Due to the nature of an asynchronous queued call, managing a failure on both the client's side (failing to dispatch the calls) and the server's side (repeatedly failing to execute the call--a poison message) requires a special design approach. As discussed in Chapter 8, both the clients and server can use a queued component exception class to handle the error. You can also provide your product administrator with an administration utility for moving messages between the retry queues.
You can designate a managed class as the exception class for your queued component using the
ExceptionClass attribute. Example 10-15 demonstrates using the
ExceptionClass attribute.
Example 10-15: Using the ExceptionClass attribute to designate an error-handling class for your queued component
using COMSVCSLib;
public class MyQCException : IPlaybackControl,IMyInterface
public void FinalClientRetry( ) {...}
public void FinalServerRetry( ) {...}
public void MyMethod( ){...}
public class MyComponent :ServicedComponent,IMyInterface
In Example 10-15, when you register the assembly containing
MyComponent with COM+, on the component's Advanced tab, the Queuing exception class field will contain the name of its exception class--in this case,
MyQCException, as shown in Figure 10-3.
You need to know a few more things about designating a managed class as a queued component's exception class. First, it has nothing to do with .NET error handling via exceptions. The word exception is overloaded. As far as .NET is concerned, a queued component's exception class is not a .NET exception class. Second, the queued component exception class has to adhere to the requirements of a queued component exception class described in Chapter 8. These requirements include implementing the same set of queued interfaces as the queued component itself and implementing the
IPlaybackControl interface. To add
IPlaybackControl to your class definition you need to add a reference in your project to the COM+ Services type library.
IPlaybackControl is defined in the
COMSVCSLib namespace.
As explained in Chapter 8, COM+ provides you with the
IMessageMover interface, and a standard implementation of it, for moving all the messages from one retry queue to another. Managed clients can access this implementation by importing the COM+ Services type library and using the
MessageMover class, defined in the
COMSVCSLib namespace. Example 10-16 implements the same use-case as Example 8-2.
Example 10-16: MessageMover is used to move messages from the last retry queue to the application's queue
using COMSVCSLib;
IMessageMover messageMover;
int moved;//How many messages were moved
messageMover = (IMessageMover) new MessageMover( );
//Move all the messages from the last retry queue to the application's queue
messageMover.SourcePath = @".\PRIVATE$\MyApp_4";
messageMover.DestPath = @".\PUBLIC$\MyApp";
moved = messageMover.MoveMessages( );
.NET provides managed classes with an easy way to hook up a server that fires events with client sinks. The .NET mechanism is certainly an improvement over the somewhat cumbersome COM connection point protocol, but the .NET mechanism still suffers from all the disadvantages of tightly coupled events, as explained at the beginning of Chapter 9. Fortunately, managed classes can easily take advantage of COM+ loosely coupled events.
Related Reading
COM and .NET Component Services
EventClass attribute is used to mark a serviced component as a COM+ event class, as shown in Example 10-17.
Example 10-17: Designating a serviced component as an event class using the EventClass attribute
public interface IMySink
void OnEvent1( );
void OnEvent2( );
public class MyEventClass : ServicedComponent,IMySink
public void OnEvent1( )
throw(new NotImplementedException(exception));
public void OnEvent2( )
throw(new NotImplementedException(exception));
const string exception = @"You should not call an event class directly.
Register this assembly using RegSvcs /reconfig";
The event class implements a set of sink interfaces you want to publish events on. Note that it is pointless to have any implementation of the sink interface methods in the event class, as the event class's code is never used. It is used only as a template, so that COM+ could synthesize an implementation, as explained in Chapter 9 (compare Example 10-17 with Example 9-1). This is why the code in Example 10-17 throws an exception if anybody tries to actually call the methods (maybe as a result of removing the event class from the Component Services Explorer).
When you register the assembly with COM+, the event class is added as a COM+ event class, not as a regular COM+ component. Any managed class (not just serviced components) can publish events. Any managed class can also implement the sink's interfaces, subscribe, and receive the events. For example, to publish events using the event class from Example 10-17, a managed publisher would write:
IMySink sink;
sink = (IMySink)new MyEventClass( );
sink.OnEvent1( );
OnEvent1( ) method returns once all subscribers have been notified, as explained in Chapter 9.
Persistent subscriptions are managed directly via the Component Services Explorer because adding a persistent subscription is a deployment-specific activity. Transient subscriptions are managed in your code, similar to COM+ transient subscribers.
EventClass attribute has two public Boolean properties you can set, called
AllowInprocSubscribers and
FireInParallel. These two properties correspond to the Fire in parallel and Allow in-process subscribers, respectively, on the event class's Advanced tab. You can configure these values on the event class definition:
[EventClass(AllowInprocSubscribers = true,FireInParallel=true)]
public class MyEventClass : ServicedComponent,IMySink
EventClass attribute has an overloaded default constructor. If you do not specify a value for the
AllowInprocSubscribers and
FireInParallel properties, it sets them to
true and
false, respectively. Consequently, the following two statements are equivalent:
[EventClass(AllowInprocSubscribers = true,FireInParallel=false)]
Throughout this book, you have learned that you should focus your development efforts on implementing business logic in your components and rely on COM+ to provide the component services and connectivity they need to operate. With .NET, Microsoft has reaffirmed its commitment to this development paradigm. From a configuration management point of view, the .NET integration with COM+ is superior to COM under Visual Studio 6.0 because .NET allows you to capture your design decisions in your code, rather than use the separate COM+ Catalog. This development is undoubtedly just the beginning of seamless support and better integration of the .NET development tools, runtime, component services, and the component administration environment. COM+ itself (see Appendix B) continues to evolve, both in features and in usability, while drawing on the new capabilities of the .NET platform. The recently added ability to expose any COM+ component as a web service is only a preview of the tighter integration of .NET and COM+ we can expect to see in the future.
Copyright © 2009 O'Reilly Media, Inc.


text:
"Internet Purchases Only"
"Not a Retail Store Stock Item"
This item is viewable at our retail store in LEXINGTON, KY. It may be on display and is
available for immediate purchase and pick-up.
*Please Note!! Many of our pictures are stock photos provided to us by the manufacturer and do not necessarily represent the actual item being purchased. Please verify this picture accurately reflects the product described by the title and description on this page before you place your order.
By adding this item to your Wish List, you will be notified automatically via email when this item is back in stock.
Our Sales staff cannot forecast price or availability of Wish List items. Calls or emails about this item will not receive a response.
New In Box. Part Number:50660
Buds Item Number: 46284
Product Details & Specifications
Mossberg 9 Shot 12 Ga/20" Cylinder Bore Barrel/Heat Shield/Matte Blue
Special Purpose shotguns provide modern, state of the art design for
the most serious and potentially prolonged defense situations. A full
range of popular models offered in 20" barrel length with blued finish.
Mfg Item Num: 50660
Action :Pump
Gauge :12 GA
Barrel Length :20"
Capacity :(8 + 1 2 3/4") (7 + 1 3")
Chamber :3"
Length :41"
Weight :7 1/4 lbs
Drop :1 1/2" @ Comb & 2 1/8" @ Heel
Stock :Black Synthetic
Finish :Matte Blue
Gun Accessories, Ammunition, Gun Safes, Handguns, Left Hand Guns, Youth Guns, Reserves, Rifles, Shotguns, Scopes / Optics, Gun Closeouts, Factory Certified Guns, Used Guns, MAP, Bud's Mobile
A A & E Leathercraft, ADCO International, Advanced Technology, Aearo Company, Aimshot, Aimtech Mount Systems, Alexander Arms, Allen Company, Aluma Sport, Beretta, Browning, CZ USA, Leupold, Remington, Ruger, Savage Arms, Smith & Wesson, Springfield, Taurus Handguns, The American Outdoorsman, ULTRADOT DISTRIBUTION,
Uncle Mike's Michaels of Orego, US FIREARMS, USA MAGAZINES, VANGUARD USA
Copyright © 2003-2016 Budsgunshop.com. All Rights Reserved. (CW1)
Register now

subset: commoncrawl


text:
Would you guys be good enough to vote for this Youth League.
I have been posting on the International Forum with little success.
Voting closes on th 29th Nov,we need all the votes we can get to qualify.Cheers.
You can vote on the above link.
Edited by frank, 28 November 2012 - 06:32 PM.


text:
Melo is better than our whole team. Everyone. We are winning because we have Stat and Felton. Everyone else is a role player. Melo gives us three powerhouse players. U can always find role players. However, I do agree, we should not give em everything. Which I doubt DW does. In the end, id be happy with the team growing together if Den plays hardball. And getting Mayo maybe. But if we can get Melo, for our price, we should def do it.
And seriously Metro, name the 4 players on our team he's worse than..
I gotta see this nonsense.
*Edit* the above should read, name the 3 players on our team Melo's worse than.
Last edited by ronoranina; Dec 26, 2010 at 15:08.
Best fraud who ever played the game. I'll take him on my team any day..
I'm not the biggest Melo guy, but he ain't no fraud. As it stands now, he averages 24.8 ppg for his career. Dude does what he does. He is a fine player. And like all players, he is not w/out his deficient areas.
This thread is a deficiency.
Last edited by ronoranina; Dec 26, 2010 at 10:37.
Gotta give Metrocard credit...as much as I disagree with him on Carmelo the whole "add 'sexual' to the name of any disliked person and make it an insult" is actually pretty funny.
Last edited by ronoranina; Dec 27, 2010 at 08:34.
I always felt like Melo is overrated. Then again, I always felt that way about Amare and he has certainly proven me wrong. In the end of the day, he is the closest thing to a superstar available at the moment but I still would not give up anybody for him except for maybe Curry and Chandler (probably can't resign) because we have the opportunity of getting him for nothing over the summer. I want the Knicks to become a DYNASTY and getting Melo and possibly CP3 or Deron next summer will bring us closer to becoming one. Getting Melo and giving up all of our assets will not get us past Boston or Miami. Sorry, I don't see that happening unless Melo suddenly steps up his game even further which is a big if.
This dude is so full of **** he can't read or add


text: "Criticism is particularly objectionable when it is directed toward church authorities, general or local…It is quite another thing to criticize or depreciate a person for the performance of an office to which he or she has been called of God. It does not matter that the criticism is true…Our individual, personal testimonies are based on the witness of the spirit, not on any combination or accumulation of historical facts. If we are so grounded, no alteration of historical facts can shake our testimonies." – Dallin H. Oaks, "Elder Decries Criticism of LDS Leaders," quoted in The Salt Lake Tribune, Sunday August 18, 1985, p. 2B.In this case, altering Church history would entail negating the false, incomplete and inaccurate history that is knowingly and strategically propagated by the Mormon religion, bringing to cessation the false and misleading propaganda strategically disseminated by the Mormon media machine, openly disclosing the real theology and history of the Mormon religion and assuming responsibility for the myriad of atrocious acts that the Mormon religion has perpetrated against "Gentile America", which are hypocritically and fallaciously referred to as "religious persecution" and the "intolerance of the gentile". Such a policy of openness and honesty may finally result in a true awakening that maybe Mormonism really is a great world religion after all. Think of the cost savings in propaganda, and the elimination of the ridiculous "doublespeak". Most Mormon subjects are decent hard-working Americans who are completely unaware of Mormonism's dark side, and they're also tired of being lied to and subjugated; perhaps that's what the Mormon hierarchy is really worried about. Wait until these subjects realize the Constitution of the United States already grants them the freedoms and rights that are not actually granted by the Mormon religion. As Dallin Oaks stated so eloquently, "Our individual, personal testimonies are based on the witness of the spirit, not on any combination or accumulation of historical facts. If we are so grounded, no alteration of historical facts can shake our testimonies", or was that doublespeak?


text:
Washington's candidates for governor are taking different approaches to funding education without taxes.
Republican Rob McKenna and Democrat Jay Inslee outlined their proposals in a high-profile debate Thursday night. Both oppose tax increases but have different tactics for restoring needed cash to the school system.
McKenna said he would cap growth in other areas of state government at 6 percent per biennium and use the savings to fund education. Inslee said he'd like to find savings in health care growth and improved performance of state government.
McKenna and Inslee are locked in what is widely considered one of the most competitive races for governor in the country. Both sides have raised about $10 million, and a recent Elway Poll showed the candidates running about even.


text:
Finding and fixing performance bottlenecks in PHP web applications can be both time-consuming and difficult. Fortunately, free tools like Xdebug and Webgrind allow you to easily find and visualize bottlenecks in your PHP scripts.
Webgrind is an Xdebug profiling web frontend in PHP5. It implements a subset of the features of kcachegrind and installs in seconds and works on all platforms.–Webgrind


text:
This may not be the right place, but when can LO have water?
As he gets older my pumping has gone down so I was wondering if it's okay to give water in a sippy cup to a 6 month old when he eats mid-day. He would drink BM and nurse the remainder of the day (totaling 6-9 bottles or nursing sessions)


text:
Phoenix VI
Destination: Orange Beach
Type: Condo/Villa
Number of Floors: 15
Bedrooms: 1-2
Baths: 1-2
Located in the heart of Orange Beach, Alabama, the Phoenix VI complex combines a great beach location with bountiful conveniences and ample amenities.
Phoenix VI features extensive recreational facilities. Onsite options such as indoor and outdoor pools, hot tubs, a sauna, a fitness room and lighted tennis courts help guests stay active while here. Additionally, conveniences such as gazebos with barbecue grills and nearby grocery stores or restaurants within minutes mean that meals are a cinch.
Shopaholics will be delighted that The Wharf is just 5 minutes away with eclectic shopping and attractions in an outdoor mall setting, and the Tanger Outlet Mall is close, too.
Beach fun on sugar-white sands, spectacular sunsets over the glorious Gulf of Mexico and playing a round on any of the 24 championship golf courses in the area are all must-do activities during an Orange Beach, Alabama vacation. Or, venture out and take advantage of the area's plethora of amusement parks, water activities such as parasailing or dolphin watching, visit the zoo or cast a line on a deep-sea fishing trip.
The total cost of reservations at Phoenix VI does not include the cost of Parking Passes. Passes must be purchased on site upon entry into the complex.
|Pool/Hot Tub/Sauna
|Complex Features
|Parking Features
|Additional Amenities
|Closest Airport: PNS
|Nearest City: Pensacola
|"Phoenix VI" Check-In Office
|Check-In Information
|Check-In Office Name: Gulf Shores Office
1557 Gulf Shores Parkway
Gulf Shores, AL
Check-In Time: 3:00 PM
Check-Out Time: 10:00 AM
Open: Monday - Sunday 8:00AM - 8:00PM
251-968-6868 (check-in line)
251-968-6868 (office)
After Hours Check-In Procedure:
Pick up telephone next to office door. Telephone automatically rings to after hours call center. Customer service agents assists with check-in via lock box next to telephone.
888-217-1509(after hours phone)
Phoenix VI - by Wyndham Vacation Rentals
Diane G. | 09/17/2012
Last Minute December Beach Savings 2016
Save 20% off
Promo Code: LASTMINDEC
Travel Start Date: 12/01/2016
Travel End Date: 01/02/2017
Minimum Night Stay: 2
Coastal Christmas 2016
Save 30% In Gulf Shores & Orange Beach
Promo Code: COASTAL16
Travel Start Date: 11/28/2016
Travel End Date: 01/05/2017
Minimum Night Stay: 3
Gulf Coast Dining Package
15% Savings PLUS Added Value for Food Lovers in Gulf Shores & Orange Beach!
Promo Code: DINING17
Travel Start Date: 01/01/2017
Travel End Date: 03/31/2017
Minimum Night Stay: 3
Military Members Appreciation
As a salute for your service, take an extra 5% off†* any active promotion
Promo Code: MILITARY
Travel Start Date: 01/24/2014
Travel End Date: 12/31/2016
Minimum Night Stay: 3
Hangout Music Fest 2017!
Save 20% on your HMF17 accommodations for a limited time!
Promo Code: HMF2017
Travel Start Date: 05/15/2017
Travel End Date: 05/27/2017
Minimum Night Stay: 3
Stay & Play Golf Package
Customized golf packages starting from $115/pp/pn†*
Promo Code: GOLF
Travel Start Date: 01/01/2014
Travel End Date: 01/01/2017
Bedrooms: 1
Extra Sleeping Area: Other
Baths: 1 Full
Type: Condo/Villa
Sleeps: 4
Bedrooms: 2
Extra Sleeping Area: Other
Baths: 2 Full
Type: Condo/Villa
Sleeps: 8
2 BR | 2 BA | Sleeps 6


text:
"One day, on my way back from work, I tuned-in to what used to be my favorite station and started listening to Catholic Answers Live. Slowly, the hard shell that had been built around me started breaking apart every time I listened to your show. There have been several programs that have touched me very deeply, even to the point of tears."
~ Joe, Clute, TX
0 results sorted by popularity
"I did not think anything like it or anything so holy could be received in this life."
~ Richard Rolle of Hampole, 14th century solitary and writer, in describing passage through the purgative, illuminative and contemplative ways.


text:
February Art Walk Reception: February 5th, 2013 from 6pm-8pm
Light in the Bay; Views in MarinJoy PerrinI paint "plein air," on location in Northern California, and I feature seascapes and beaches, bridge-scapes, mountain views, farm views, and townscapes. I love sharing the freshness, immediacy, and joy of the plein air experience.
In watercolor, the combination of surrender and control is a fine balancing act, with the ever-changing light, the wet-to-dry continuum, and the varying properties of the paints themselves. It's invigorating to be internalizing the physics of the process and expanding in the freedom to paint more and more intuitively. I'm mostly self-taught, but paying attention. For me it's about impressions of light and rhythm, color, composition and value, and the delicious feeling of successfully capturing a fleeting magical moment, in a painting.
© 2016 Mill Valley Public Library | 375 Throckmorton Ave | Mill Valley, CA 94941 | (415) 389-4292
Contact the Library | Privacy Policy & Disclaimer | Website developed by Vision Internet


text:
Items where Author is "Krizova, V"
|Up a level
Group by: Item Type | No Grouping
Jump to: Article
Number of items: 1.
Abdull Razis, AF, Hanlon, N, Soltys, E, Krizova, V, Iori, R, Plant, KE, Plant, N and Ioannides, C (2012) The naturally occurring aliphatic isothiocyanates sulforaphane and erucin are weak agonists but potent non-competitive antagonists of the aryl hydrocarbon receptor. Archives of Toxicology, 86 (10). 1505 - 1514. ISSN 0340-5761
Information about this web site
© The University of Surrey, Guildford, Surrey, GU2 7XH, United Kingdom.
+44 (0)1483 300800
+44 (0)1483 300800


text:
"I recently found you through my smartphone and I'm hooked. I find the program very interesting as I try to deepen my faith and knowledge of the Catholic Church. I have a lot of friends who converted to Protestant churches. I will continue to learn every day, and hopefully I can share what I've learned with them."
~ Seri, South Korea
0 results
Subscribe to Catholic Answers Magazine
"For the Scripture says 'Holy, holy, holy Lord of hosts; full is every creature of his glory'. And we, led by conscience, gathered together in one place in concord, cry to Him continuously as from one mouth, that we may become sharers in His great and glorious promises."
~ The Sanctus, here described by Pope Clement I (from his I Cor., 34:6-7) circa A.D. 95, is one of the most ancient parts of the sacred liturgy, tracing back to the time of the apostles.


text:
Hello, ladies.
DD is 6 weeks old and has been supplemented with formula since her first week appt. I could just kick myself for following their advice. They told me she needed to be supplemented with formula versus expressed breast milk because 'it would give her a bit more of what she needs'. She weighed 5.12 at birth and went down to 5.5 and then back up to 5.8 by the end of the first week. They were concerned that she hadn't gained all of her weight back. In retrospect I think she would have been FINE with supplements of breast milk.
Anyway, we were working on slowly cutting out the formula and increasing my supply, but now she is hitting a growth spurt and we're back to square one. I'm having a REALLY difficult time because I am finding it hard to find the extra time to pump..I also have a 3 year old and a 23 month old and a 10 month old puppy lol..DH works 12 hour days 6 days a week right now as well.
I was using the SNS, but DS would come along and play with it and pull it off
I'm just getting frustrated because I know what I need to do, but can't seem to do it!! aargh! Has anyone been in this situation before?? I feel the grey hairs sprouting..I don't want to give up nursing and I really don't want her having the formula, either!! She will nurse and then still suck down 4 oz


text:
Order by 22.12. for delivery by 24.12. - more*
$ 599.00
Unfortunately this product is currently not available.
This luxurious creation is ideal for parties and other dress-up occasions. Specifications: case - yellow-gold PVD, 30mm; dial - white silver-colored sunray pattern; numbers - hand-applied clear crystals, Swan logo at 12 o'clock; strap - clear Crystal Mesh; movement - Swiss quartz.


text:
On Tap Today: The Big Gig is back on
What did you get to do on your day off from Summerfest?
Milwaukee musician Sam McCue remembers days playing with Phil Everly
Phil Everly didn't just sing "All I Have to Do Is Dream."
He helped Sam McCue live his. »Read Full Article(6)
New York City music exec tells of longtime love of Packers
His professional routine involves bringing hip-hop to the masses, but his Sunday routine revolves around the Packers.
Lyor Cohen, the former head of Def Jam records, was profiled by the New York Times in this week's "Sunday Routine" column, which notes that Cohen is a "passionate fan of the Green Bay Packers" and "everything gets thrown off" when the team is playing. »Read Full Blog Post


text:
Your shopping cart is empty!
Mexico 2012-13 Women green/red track top. Features embroidered team crest on left and embroidered classic Adidas logo on the right chest, Fully zip with 2 zippered side pockets.3 white ribbon Adidas design is stitched down from the back of the neck to the lower waist.100% polyester.
Soccerplus first opened in 1994. We were one of the first soccer websites to hit the webView more
Address: 1640 E. Washington Blvd.
Pasadena, Ca 91104, USA
Phone: 1-800-945-7291
Get Direct


text:
"Metaphors in Motion," Features JMU's Virginia Repertory Dance Company
Fri, 7 Dec 2012 8:00 PM - 10:00 PM
Dec. 6-9
8 p.m. Thursday-Saturday, 2 p.m. Sunday
Mainstage Theatre, Forbes Center for the Performing Arts
Praised by the Richmond Times-Dispatch for its "range and versatility," this pre-professional ensemble will present a kaleidoscope of works by national and international guest artists, including Carol Finley from Raleigh, N.C., James Hansen and JMU alumna Donna Costello from New York and Virginia choreographer Alan Arnett. As part of a cultural exchange residency, noted Chinese choreographer Wei Chen will stage a special dance for the company
For tickets, check http://www.jmu.edu/jmuarts/events/120912_metaphors.shtml or call (540) 568-7000.
- Nov 16: - Jan 5: College for Kids
- Nov 16: - Jan 12: Saturday Morning Physics
- Nov 27: - Dec 14: Institute for Visual Studies Exhibition