Click or drag to resize

TenantPropagationBehaviorTTenantId Class

Behavior for WCF clients and service hosts that is used to propagate tenant ID from client to service.
Inheritance Hierarchy
SystemObject
  Autofac.Multitenant.WcfTenantPropagationBehaviorTTenantId

Namespace:  Autofac.Multitenant.Wcf
Assembly:  Autofac.Multitenant.Wcf (in Autofac.Multitenant.Wcf.dll) Version: 4.0.0-CI-234
Syntax
public class TenantPropagationBehavior<TTenantId> : IServiceBehavior, 
	IEndpointBehavior

Type Parameters

TTenantId
The type of the tenant ID to propagate. Must be nullable and serializable so it can be added to a message header.

The TenantPropagationBehaviorTTenantId type exposes the following members.

Constructors
  NameDescription
Public methodTenantPropagationBehaviorTTenantId
Initializes a new instance of the TenantPropagationBehaviorTTenantId class.
Top
Properties
  NameDescription
Public propertyTenantIdentificationStrategy
Gets the strategy used for identifying the current tenant.
Top
Methods
  NameDescription
Public methodAddBindingParameters(ServiceEndpoint, BindingParameterCollection)
Implement to pass data at runtime to bindings to support custom behavior.
Public methodAddBindingParameters(ServiceDescription, ServiceHostBase, CollectionServiceEndpoint, BindingParameterCollection)
Provides the ability to pass custom data to binding elements to support the contract implementation.
Public methodApplyClientBehavior
Public methodApplyDispatchBehavior(ServiceDescription, ServiceHostBase)
Public methodApplyDispatchBehavior(ServiceEndpoint, EndpointDispatcher)
Implements a modification or extension of the service across an endpoint.
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Public methodValidate(ServiceEndpoint)
Implement to confirm that the endpoint meets some intended criteria.
Public methodValidate(ServiceDescription, ServiceHostBase)
Provides the ability to inspect the service host and the service description to confirm that the service can run successfully.
Top
Remarks

This behavior applies the TenantPropagationMessageInspectorTTenantId to WCF clients and service hosts to automatically get the tenant ID on the WCF client end, add the ID to a header on the outbound message, and have the tenant ID read from headers on the service side and added to the operation context in an TenantIdentificationContextExtension. This allows you, on the service side, to use the OperationContextTenantIdentificationStrategy as your registered ITenantIdentificationStrategy.

Examples

In the following examples, the tenant ID is a String, so the TTenantId in the examples corresponds. In your application, your tenant ID may be a nullable GUID or some other object, so you'd need to update accordingly. That would mean passing a different type as TTenantId and implementing a custom ITenantIdentificationStrategy that parses the appropriate tenant ID from the execution context.

The following snippet shows what registration of this behavior might look like in an ASP.NET application that consumes WCF services.

C#
public class MvcApplication : HttpApplication, IContainerProviderAccessor
{
  private static IContainerProvider _containerProvider;

  public IContainerProvider ContainerProvider
  {
    get { return _containerProvider; }
  }

  public static void RegisterRoutes(RouteCollection routes)
  {
    // Register your routes as normal.
  }

  protected void Application_Start()
  {
    // Create a tenant ID strategy that will get the tenant from
    // your ASP.NET request context.
    var tenantIdStrategy = new RequestParameterTenantIdentificationStrategy("tenant");

    // Register application-level dependencies and controllers.
    var builder = new ContainerBuilder();
    builder.RegisterType<HomeController>();
    // ... and so on.

    // When you register the WCF service client, add the
    // TenantPropagationBehavior to the Opening event:

    builder.Register(
      c => new ChannelFactory<IMultitenantService>(
        new BasicHttpBinding(),
        new EndpointAddress("http://server/TheService.svc"))).SingleInstance();
    builder.Register(
      c =>
      {
        var factory = c.Resolve<ChannelFactory<IMultitenantService>>();
        factory.Opening +=
          (sender, args) =>
            factory.Endpoint.Behaviors.Add(
            new TenantPropagationBehavior<string>(tenantIdStrategy);
        return factory.CreateChannel()
      }).InstancePerHttpRequest();

    // Create the multitenant container.
    var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());

    // Register tenant specific overrides and set up the
    // application container provider.
    _containerProvider = new ContainerProvider(mtc);

    // Do other MVC setup like route registration, etc.
    ControllerBuilder.Current.SetControllerFactory(new AutofacControllerFactory(this.ContainerProvider));
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
  }
}

Note that much of the above code is the standard ASP.NET application wireup with Autofac. The important part is when you register the service client - it needs to have a TenantPropagationBehaviorTTenantId attached to it that can get the container provider from the current application.

The following snippet shows what registration of this behavior looks like in a WCF application hosted in IIS:

C#
public class Global : System.Web.HttpApplication
{
  protected void Application_Start(object sender, EventArgs e)
  {
      // Create the tenant ID strategy. Required for multitenant integration.
      var tenantIdStrategy = new OperationContextTenantIdentificationStrategy();

      // Register application-level dependencies and service implementations.
      var builder = new ContainerBuilder();
      builder.RegisterType<BaseImplementation>().As<IMultitenantService>();
      // ... and so on.

      // Create the multitenant container.
      var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());

      // Configure tenant-specific overrides and set the WCF host container.
      Autofac.Multitenant.Wcf.AutofacHostFactory.Container = mtc;

      // Add a behavior to service hosts that get created so incoming messages
      // get inspected and the tenant ID can be parsed from message headers.
      Autofac.Multitenant.Wcf.AutofacHostFactory.HostConfigurationAction =
        host =>
          host.Opening += (s, args) =>
            host.Description.Behaviors.Add(new TenantPropagationBehavior<string>(tenantIdStrategy));
  }
}

Note that it is also very similar to standard wireup with Autofac WCF integration, just that you use the multitenant WCF host, a multitenant container, and a behavior to get the tenant ID from the operation context.

See Also