Skip to content

DIInstrumentationWithCastleWindsor

Michael Powell edited this page Jan 30, 2017 · 12 revisions

Castle Windsor reasoning

The decision to support Castle Windsor is a natural one extending from the fact that Castle Core is used to facilitate interception.

Dependency Injected Instrumentation with Castle Windsor

The fundamentals are the same as with ad-hoc instrumentation. The only difference is, you are telling Castle Windsor that measurements should be enabled.

Package References
MeasureIt.Castle.Windsor
MeasureIt.Castle.Interception
Castle.Windsor
MeasureIt.Castle.Interception
MeasureIt.Core
Castle.Core

There are several things that you can do once you adopt this library. We will discuss each one briefly.

Enabling the measurements

You have a couple different choices available to you from which to decide, depending on how specific you want to be when enabling measurements.

The first choice assumes InstrumentationDiscoveryOptions and MeasurementInterceptor as default options and interceptor. For most runtime usage you will want the IRuntimeInstrumentationDiscoveryService and RuntimeInstrumentationDiscoveryService, but there may be times when you also want the IInstallerInstrumentationDiscoveryService and InstallerInstrumentationDiscoveryService. You may provide an options factory as necessary, the default for which simply creates a new default instance.

public static IWindsorContainer EnableMeasurements<TInterface, TService>(
    this IWindsorContainer container
    , Func<InstrumentationDiscoveryOptions> createOptions = null)
    where TInterface : class, IRuntimeInstrumentationDiscoveryService
    where TService : class, TInterface;

This version allows you to also specify the TOptions.

public static IWindsorContainer EnableMeasurements<TInterface, TService, TOptions>(
    this IWindsorContainer container
    , Func<TOptions> createOptions = null)
    where TInterface : class, IRuntimeInstrumentationDiscoveryService
    where TService : class, TInterface
    where TOptions : class, IInstrumentationDiscoveryOptions, new();

Last but not least, you may also specify the TInterceptor.

public static IWindsorContainer EnableMeasurements<TInterface, TService, TOptions, TInterceptor>(
    this IWindsorContainer container
    , Func<TOptions> createOptions = null)
    where TInterface : class, IRuntimeInstrumentationDiscoveryService
    where TService : class, TInterface
    where TOptions : class, IInstrumentationDiscoveryOptions, new()
    where TInterceptor : class, IMeasurementInterceptor;

Example:

IWindsorContainer Container { get; }

That you have initialized:

Container = new WindsorContainer();

Now you want to enable measurements:

Container.EnableMeasurements<IRuntimeInstrumentationDiscoveryService
    , RuntimeInstrumentationDiscoveryService
    , InstrumentationDiscoveryOptions
    , MeasurementInterceptor>();

With this, now your container will be configured with the necessary resources to support measuring performance.

Now connect your ComponentRegistration<T>

Once you have enabled measurements, then you need to instruct your container to connect the dots with your component registrations.

The general form requires the base component registration, as well the TInterceptor being specified.

public static ComponentRegistration<T> MeasureUsing<T, TInterceptor>(
    this ComponentRegistration<T> registration)
    where T : class
    where TInterceptor : class, IMeasurementInterceptor;

The shorter form also takes the base component registration, but assumes that you want the default MeasurementInterceptor.

public static ComponentRegistration<T> Measure<T>(
    this ComponentRegistration<T> registration)
    where T : class;

In either case the component registration is returned so that you may further elaborate on it.

Example:

var serviceReg = Component.For<MyService>().Measure();
// Or:
var serviceReg = Component.For<MyService>().MeasureUsing<MyService, MeasurementInterceptor>();

Remember to pass this registration allong to your IWindsorContainer instance.

Container.Add(serviceReg);

Measure instances during activation

Most containers support an activation phase during which instances are created, and Castle Windsor is no exception. There may be circumstances where you want to measure a container provided instance during the container provision activation phase.

public static T MeasureInstance<T, TInterceptor>
    this IWindsorContainer container
    , T obj, Func<ProxyGenerationOptions> createGeneratorOptions = null)
    where T : class
    where TInterceptor : class, IMeasurementInterceptor;

Or the version that assumes you want the MeasurementInterceptor.

public static T MeasureInstance<T>
    this IWindsorContainer container
    , T obj, Func<ProxyGenerationOptions> createGeneratorOptions = null)
    where T : class;

In either case, you will have your base object and reference to your container. Invoke this method in order to install the appropriate measurement interceptor.

Example:

var service = Container.Resolve<MyService>();

And now connect the measurement with the service.

service = service.MeasureInstance();

Or with more specificity if you prefer:

service = service.MeasureInstance<MyService, MeasurementInterceptor>();