Skip to content

Commit

Permalink
Initial working Spring.NET integration
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Jul 10, 2011
1 parent 584a125 commit e94c623
Show file tree
Hide file tree
Showing 20 changed files with 99,455 additions and 2 deletions.
120 changes: 120 additions & 0 deletions Rhino.ServiceBus.Spring/ApplicationContextExtensions.cs
@@ -0,0 +1,120 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

using Spring.Context;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;

namespace Rhino.ServiceBus.Spring
{
[CLSCompliant(false)]
public static class ApplicationContextExtensions
{
public static T Get<T>(this IConfigurableApplicationContext context)
{
return (T) Get(context, typeof(T));
}

public static IEnumerable<T> GetAll<T>(this IConfigurableApplicationContext context)
{
IDictionary objectsOfType = context.GetObjectsOfType(typeof(T));
return objectsOfType.Values.Cast<T>();
}

public static object Get(this IApplicationContext context, Type type)
{
string[] objectNamesForType = context.GetObjectNamesForType(type);
if ((objectNamesForType == null) || (objectNamesForType.Length == 0))
{
throw new NoSuchObjectDefinitionException(type.FullName, "Requested Type not defined in the context.");
}
return context.GetObject(objectNamesForType[0]);
}

public static T Get<T>(this IApplicationContext context, string name)
{
return (T) context.GetObject(name);
}

public static void RegisterPrototype<T>(this IConfigurableApplicationContext context)
{
ObjectDefinitionBuilder definitionBuilder = ObjectDefinitionBuilder.RootObjectDefinition(new DefaultObjectDefinitionFactory(), typeof(T))
.SetAutowireMode(AutoWiringMode.AutoDetect)
.SetSingleton(false);
context.ObjectFactory.RegisterObjectDefinition(Guid.NewGuid().ToString(), definitionBuilder.ObjectDefinition);
}

public static void RegisterSingletons<TBasedOn>(this IConfigurableApplicationContext context, Assembly assembly)
{
assembly.GetTypes()
.Where(t => typeof (TBasedOn).IsAssignableFrom(t)
&& !t.IsInterface
&& !t.IsAbstract)
.ToList()
.ForEach(type => RegisterSingleton(context, type));
}

public static void RegisterSingleton(this IConfigurableApplicationContext context, Type type)
{
ObjectDefinitionBuilder definitionBuilder = ObjectDefinitionBuilder.RootObjectDefinition(new DefaultObjectDefinitionFactory(), type)
.SetAutowireMode(AutoWiringMode.AutoDetect)
.SetSingleton(true);
context.ObjectFactory.RegisterObjectDefinition(type.FullName, definitionBuilder.ObjectDefinition);
}

public static void RegisterSingleton(this IConfigurableApplicationContext context, Type type, string name, params object[] constructorArguments)
{
ObjectDefinitionBuilder definitionBuilder = ObjectDefinitionBuilder.RootObjectDefinition(new DefaultObjectDefinitionFactory(), type)
.SetAutowireMode(AutoWiringMode.AutoDetect)
.SetSingleton(true);
if (constructorArguments != null && constructorArguments.Length > 0)
{
foreach (object argument in constructorArguments)
{
definitionBuilder.AddConstructorArg(argument);
}
}

context.ObjectFactory.RegisterObjectDefinition(name, definitionBuilder.ObjectDefinition);
}

public static void RegisterSingleton<T>(this IConfigurableApplicationContext context, Func<T> creator)
{
RegisterSingleton(context, Guid.NewGuid().ToString(), creator);
}

public static void RegisterSingleton<T>(this IConfigurableApplicationContext context, string name, Func<T> creator)
{
context.ObjectFactory.RegisterSingleton(name, new FuncBasedObjectCreator<T>(creator));
}

private class FuncBasedObjectCreator<T> : IFactoryObject
{
private readonly Func<T> creator;

public FuncBasedObjectCreator(Func<T> creator)
{
this.creator = creator;
}

public object GetObject()
{
return creator();
}

public Type ObjectType
{
get { return typeof(T); }
}

public bool IsSingleton
{
get { return true; }
}
}
}
}
39 changes: 39 additions & 0 deletions Rhino.ServiceBus.Spring/ConsumerInterceptor.cs
@@ -0,0 +1,39 @@
using System;

using Rhino.ServiceBus.Config;
using Rhino.ServiceBus.Internal;

using Spring.Context;
using Spring.Objects.Factory.Config;

namespace Rhino.ServiceBus.Spring
{
[CLSCompliant(false)]
public class ConsumerInterceptor : IObjectPostProcessor
{
private readonly IConsumerInterceptor interceptor;
private readonly IConfigurableApplicationContext applicationContext;

public ConsumerInterceptor(IConsumerInterceptor interceptor, IConfigurableApplicationContext applicationContext)
{
this.interceptor = interceptor;
this.applicationContext = applicationContext;
}

public object PostProcessBeforeInitialization(object instance, string name)
{
return instance;
}

public object PostProcessAfterInitialization(object instance, string objectName)
{
var type = instance.GetType();
if (typeof(IMessageConsumer).IsAssignableFrom(type))
{
var transient = !applicationContext.ObjectFactory.GetObjectDefinition(objectName).IsSingleton;
interceptor.ItemCreated(type, transient);
}
return instance;
}
}
}
24 changes: 24 additions & 0 deletions Rhino.ServiceBus.Spring/Extensions.cs
@@ -0,0 +1,24 @@
using System;
using Rhino.ServiceBus.Impl;
using Rhino.ServiceBus.Spring;

using Spring.Context;
using Spring.Context.Support;

namespace Rhino.ServiceBus
{
public static class Extensions
{
public static AbstractRhinoServiceBusConfiguration UseSpring(this AbstractRhinoServiceBusConfiguration configuration)
{
return UseSpring(configuration, new StaticApplicationContext());
}

[CLSCompliant(false)]
public static AbstractRhinoServiceBusConfiguration UseSpring(this AbstractRhinoServiceBusConfiguration configuration, IConfigurableApplicationContext container)
{
new SpringBuilder(configuration, container);
return configuration;
}
}
}
82 changes: 82 additions & 0 deletions Rhino.ServiceBus.Spring/Rhino.ServiceBus.Spring.csproj
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E18B8442-40AF-F3A1-9FB0-F1C5FC994CEA}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Rhino.ServiceBus.Spring</RootNamespace>
<AssemblyName>Rhino.ServiceBus.Spring</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\ayende-open-source.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(LibDir)' == '' ">
<LibDir>..\SharedLibs\4.0\</LibDir>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common.Logging">
<HintPath>..\SharedLibs\Common.Logging.dll</HintPath>
</Reference>
<Reference Include="Rhino.Queues, Version=1.2.0.0, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
<HintPath>$(LibDir)Rhino.Queues.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="Spring.Core">
<HintPath>$(LibDir)Spring.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Messaging" />
<Reference Include="System.Transactions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ApplicationContextExtensions.cs" />
<Compile Include="ConsumerInterceptor.cs" />
<Compile Include="SpringBootStrapper.cs" />
<Compile Include="SpringBuilder.cs" />
<Compile Include="SpringLoadBalancerBootStrapper.cs" />
<Compile Include="SpringServiceLocator.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Rhino.ServiceBus\Rhino.ServiceBus.csproj">
<Project>{1B21C8A5-5E0E-412B-A7F4-9F28B4427F21}</Project>
<Name>Rhino.ServiceBus</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
101 changes: 101 additions & 0 deletions Rhino.ServiceBus.Spring/SpringBootStrapper.cs
@@ -0,0 +1,101 @@
using System;
using System.Linq;

using Rhino.ServiceBus.Actions;
using Rhino.ServiceBus.Hosting;
using Rhino.ServiceBus.Impl;
using Rhino.ServiceBus.Internal;

using Spring.Context;
using Spring.Context.Support;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;

namespace Rhino.ServiceBus.Spring
{
[CLSCompliant(false)]
public abstract class SpringBootStrapper : AbstractBootStrapper
{
private IConfigurableApplicationContext applicationContext;

public SpringBootStrapper()
{
}

public SpringBootStrapper(IConfigurableApplicationContext applicationContext)
{
this.applicationContext = applicationContext;
}

protected IConfigurableApplicationContext ApplicationContext
{
get { return applicationContext; }
}

protected override void ConfigureBusFacility(AbstractRhinoServiceBusConfiguration configuration)
{
configuration.UseSpring(applicationContext);
}

public override void ExecuteDeploymentActions(string user)
{
foreach (IDeploymentAction action in applicationContext.GetAll<IDeploymentAction>())
{
action.Execute(user);
}
}

public override void ExecuteEnvironmentValidationActions()
{
foreach (IEnvironmentValidationAction action in applicationContext.GetAll<IEnvironmentValidationAction>())
{
action.Execute();
}
}

public override T GetInstance<T>()
{
return applicationContext.Get<T>();
}

public override void Dispose()
{
applicationContext.Dispose();
}

public override void CreateContainer()
{
if (applicationContext == null)
applicationContext = new StaticApplicationContext();

ConfigureContainer();
}

protected virtual void ConfigureContainer()
{
applicationContext.RegisterSingletons<IDeploymentAction>(Assembly);
applicationContext.RegisterSingletons<IEnvironmentValidationAction>(Assembly);
RegisterConsumers();
}

protected virtual void RegisterConsumers()
{
Assembly.GetTypes()
.Where(t => typeof (IMessageConsumer).IsAssignableFrom(t)
&& !typeof (IOccasionalMessageConsumer).IsAssignableFrom(t)
&& IsTypeAcceptableForThisBootStrapper(t)
&& !t.IsInterface
&& !t.IsAbstract)
.ToList()
.ForEach(type =>
{
ObjectDefinitionBuilder definitionBuilder = ObjectDefinitionBuilder
.RootObjectDefinition(new DefaultObjectDefinitionFactory(), type)
.SetAutowireMode(AutoWiringMode.Constructor)
.SetSingleton(false);
applicationContext.ObjectFactory.RegisterObjectDefinition(type.FullName, definitionBuilder.ObjectDefinition);
}
);
}
}
}

0 comments on commit e94c623

Please sign in to comment.