Skip to content

Commit b26136a

Browse files
committed
Pluggable container and tests for Jroland#12
Here is a second attempt to Jroland#12: 1) refactored IContainer and its default implementation. Tests included. 2) Bus factory is not static anymore and can use abstact IContainer 3) Windsor adapter of IContainer
1 parent 63cbcab commit b26136a

21 files changed

+346
-46
lines changed

src/TestHarness/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Program
1010
{
1111
static void Main(string[] args)
1212
{
13-
var bus = BusFactory.Create(new KafkaOptions
13+
var bus = new BusFactory().Create(new KafkaOptions
1414
{
1515
Hosts = new[] {new Uri("http://CSDKAFKA01:9092"), new Uri("http://CSDKAFKA02:9092")}
1616
}, x => { });

src/kafka-net.sln

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 2013
4-
VisualStudioVersion = 12.0.30110.0
5-
MinimumVisualStudioVersion = 10.0.40219.1
3+
# Visual Studio 2012
64
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kafka-net", "kafka-net\kafka-net.csproj", "{1343EB68-55CB-4452-8386-24A9989DE1C0}"
75
EndProject
86
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kafka-tests", "kafka-tests\kafka-tests.csproj", "{D80AE407-BB81-4C11-BFDC-5DD463F8B1BF}"
@@ -28,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
2826
..\version = ..\version
2927
EndProjectSection
3028
EndProject
29+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kafka-net.windsor", "kafka-net.windsor\kafka-net.windsor.csproj", "{29ED0088-40F5-452F-95D4-9F8CD33156D3}"
30+
EndProject
3131
Global
3232
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3333
Debug|Any CPU = Debug|Any CPU
@@ -50,6 +50,10 @@ Global
5050
{FF7E1490-7453-47B0-A12E-64FED927825A}.Debug|Any CPU.Build.0 = Debug|Any CPU
5151
{FF7E1490-7453-47B0-A12E-64FED927825A}.Release|Any CPU.ActiveCfg = Release|Any CPU
5252
{FF7E1490-7453-47B0-A12E-64FED927825A}.Release|Any CPU.Build.0 = Release|Any CPU
53+
{29ED0088-40F5-452F-95D4-9F8CD33156D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
54+
{29ED0088-40F5-452F-95D4-9F8CD33156D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
55+
{29ED0088-40F5-452F-95D4-9F8CD33156D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
56+
{29ED0088-40F5-452F-95D4-9F8CD33156D3}.Release|Any CPU.Build.0 = Release|Any CPU
5357
EndGlobalSection
5458
GlobalSection(SolutionProperties) = preSolution
5559
HideSolutionNode = FALSE
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("kafka-net.windsor")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("kafka-net.windsor")]
13+
[assembly: AssemblyCopyright("Copyright © 2014")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("fdefc18c-e9e3-4150-aecf-bbe1da358dae")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Castle.MicroKernel.Registration;
2+
using Castle.Windsor;
3+
using KafkaNet.Configuration;
4+
5+
namespace KafkaNet.Windsor
6+
{
7+
public class WindsorAdapter : IContainer
8+
{
9+
private readonly IWindsorContainer _container;
10+
11+
public WindsorAdapter(IWindsorContainer container)
12+
{
13+
this._container = container;
14+
}
15+
16+
public T Resolve<T>() where T : class
17+
{
18+
try
19+
{
20+
return _container.Resolve<T>();
21+
}
22+
catch (Castle.MicroKernel.ComponentNotFoundException exception)
23+
{
24+
throw new ServiceNotFound(string.Format("No service of type {0} has been registered", typeof(T).Name), exception);
25+
}
26+
}
27+
28+
public IServiceRegistrator Register<T>(System.Func<IServiceProvider, T> factory) where T : class
29+
{
30+
if (!_container.Kernel.HasComponent(typeof(T)))
31+
{
32+
_container.Register(
33+
Component.For<T>().UsingFactoryMethod(() => factory(this)).LifeStyle.Singleton
34+
);
35+
}
36+
return this;
37+
38+
}
39+
}
40+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{29ED0088-40F5-452F-95D4-9F8CD33156D3}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>KafkaNet.Windsor</RootNamespace>
11+
<AssemblyName>kafka-net.windsor</AssemblyName>
12+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
15+
<RestorePackages>true</RestorePackages>
16+
</PropertyGroup>
17+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18+
<PlatformTarget>AnyCPU</PlatformTarget>
19+
<DebugSymbols>true</DebugSymbols>
20+
<DebugType>full</DebugType>
21+
<Optimize>false</Optimize>
22+
<OutputPath>bin\Debug\</OutputPath>
23+
<DefineConstants>DEBUG;TRACE</DefineConstants>
24+
<ErrorReport>prompt</ErrorReport>
25+
<WarningLevel>4</WarningLevel>
26+
</PropertyGroup>
27+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
28+
<PlatformTarget>AnyCPU</PlatformTarget>
29+
<DebugType>pdbonly</DebugType>
30+
<Optimize>true</Optimize>
31+
<OutputPath>bin\Release\</OutputPath>
32+
<DefineConstants>TRACE</DefineConstants>
33+
<ErrorReport>prompt</ErrorReport>
34+
<WarningLevel>4</WarningLevel>
35+
</PropertyGroup>
36+
<PropertyGroup>
37+
<StartupObject />
38+
</PropertyGroup>
39+
<ItemGroup>
40+
<Reference Include="Castle.Core">
41+
<HintPath>..\packages\Castle.Core.3.3.0\lib\net45\Castle.Core.dll</HintPath>
42+
</Reference>
43+
<Reference Include="Castle.Windsor">
44+
<HintPath>..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll</HintPath>
45+
</Reference>
46+
<Reference Include="System" />
47+
<Reference Include="System.Core" />
48+
<Reference Include="System.Xml.Linq" />
49+
<Reference Include="System.Data.DataSetExtensions" />
50+
<Reference Include="Microsoft.CSharp" />
51+
<Reference Include="System.Data" />
52+
<Reference Include="System.Xml" />
53+
</ItemGroup>
54+
<ItemGroup>
55+
<Compile Include="Properties\AssemblyInfo.cs" />
56+
<Compile Include="WindsorAdapter.cs" />
57+
</ItemGroup>
58+
<ItemGroup>
59+
<None Include="packages.config" />
60+
</ItemGroup>
61+
<ItemGroup>
62+
<ProjectReference Include="..\kafka-net\kafka-net.csproj">
63+
<Project>{1343eb68-55cb-4452-8386-24a9989de1c0}</Project>
64+
<Name>kafka-net</Name>
65+
</ProjectReference>
66+
</ItemGroup>
67+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
68+
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
69+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
70+
<PropertyGroup>
71+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
72+
</PropertyGroup>
73+
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
74+
</Target>
75+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
76+
Other similar extension points exist, see Microsoft.Common.targets.
77+
<Target Name="BeforeBuild">
78+
</Target>
79+
<Target Name="AfterBuild">
80+
</Target>
81+
-->
82+
</Project>

src/kafka-net.windsor/packages.config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="Castle.Core" version="3.3.0" targetFramework="net45" />
4+
<package id="Castle.Windsor" version="3.3.0" targetFramework="net45" />
5+
</packages>

src/kafka-net/Configuration/Bus.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
2-
using System.Collections.Concurrent;
3-
using System.Collections.Generic;
1+
using System.Collections.Generic;
42
using System.Threading;
53
using System.Threading.Tasks;
64
using KafkaNet.Protocol;

src/kafka-net/Configuration/BusFactory.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,24 @@
22

33
namespace KafkaNet.Configuration
44
{
5-
public static class BusFactory
5+
public class BusFactory
66
{
7-
public static IBus Create(IKafkaOptions settings, Action<IServiceRegistrator> configure)
7+
private readonly IContainer container;
8+
9+
public BusFactory(IContainer container)
10+
{
11+
this.container = container;
12+
}
13+
14+
public BusFactory() : this(new DefaultContainer())
15+
{
16+
}
17+
18+
public IBus Create(IKafkaOptions settings, Action<IServiceRegistrator> configure)
819
{
9-
var container = new DefaultContainer();
10-
DefaultServiceRegistrator.Register(container);
11-
container.Register(settings);
1220
configure(container);
21+
container.Register(_ => settings);
22+
DefaultServiceRegistrator.Register(container);
1323
return container.Resolve<IBus>();
1424
}
1525
}

src/kafka-net/Configuration/DefaultContainer.cs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,30 @@ namespace KafkaNet.Configuration
55
{
66
public class DefaultContainer : IContainer
77
{
8-
private readonly Dictionary<Type, object> _implementations = new Dictionary<Type, object>();
98
private readonly Dictionary<Type, object> _factories = new Dictionary<Type, object>();
9+
private readonly Dictionary<Type, object> _instances = new Dictionary<Type, object>();
1010

1111
public T Resolve<T>() where T: class
1212
{
13-
object implementation;
14-
if (_implementations.TryGetValue(typeof (T), out implementation))
15-
return (T) implementation;
13+
object instance;
14+
if (_instances.TryGetValue(typeof (T), out instance))
15+
return (T) instance;
1616
object factory;
17-
if (_factories.TryGetValue(typeof(T), out factory))
17+
if (_factories.TryGetValue(typeof (T), out factory))
1818
{
19-
var serviceFactory = (Func<IServiceProvider, T>)factory;
20-
var serviceImplementation = serviceFactory(this);
21-
_implementations.Add(typeof (T), serviceImplementation);
22-
return serviceImplementation;
19+
var newInstance = ((Func<IServiceProvider, T>) factory)(this);
20+
_instances.Add(typeof(T), newInstance);
21+
return newInstance;
2322
}
24-
throw new ServiceImplementationNotFound();
23+
throw new ServiceNotFound(string.Format("No service of type {0} has been registered", typeof(T).Name));
2524
}
2625

27-
public void Register<T>(T implementation) where T : class
28-
{
29-
_implementations.Add(typeof (T), implementation);
30-
}
31-
32-
public void Register<T>(Func<IServiceProvider, T> factory) where T : class
26+
public IServiceRegistrator Register<T>(Func<IServiceProvider, T> factory) where T : class
3327
{
28+
if(_factories.ContainsKey(typeof(T)))
29+
return this;
3430
_factories.Add(typeof(T), factory);
31+
return this;
3532
}
3633
}
3734
}

src/kafka-net/Configuration/DefaultServiceRegistrator.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ public static class DefaultServiceRegistrator
44
{
55
public static void Register(IServiceRegistrator registrator)
66
{
7-
registrator.Register<IKafkaLog>(new DefaultTraceLog());
8-
registrator.Register<IPartitionSelector>(new DefaultPartitionSelector());
9-
registrator.Register<IKafkaConnectionFactory>(x => new DefaultKafkaConnectionFactory(x.Resolve<IKafkaLog>()));
10-
registrator.Register<IBrokerRouter>(x => new BrokerRouter(x.Resolve<IKafkaOptions>(), x.Resolve<IKafkaLog>(), x.Resolve<IPartitionSelector>(), x.Resolve<IKafkaConnectionFactory>()));
11-
registrator.Register<IProducer>(x => new Producer(x.Resolve<IBrokerRouter>(), x.Resolve<IKafkaOptions>()));
12-
registrator.Register<IConsumerFactory>(x => new ConsumerFactory(x.Resolve<IBrokerRouter>(), x.Resolve<IKafkaLog>()));
13-
registrator.Register<IBus>(x => new Bus(x.Resolve<IProducer>(), x.Resolve<IConsumerFactory>()));
7+
registrator.Register<IKafkaLog>(_ => new DefaultTraceLog())
8+
.Register<IPartitionSelector>(_ => new DefaultPartitionSelector())
9+
.Register<IKafkaConnectionFactory>(x => new DefaultKafkaConnectionFactory(x.Resolve<IKafkaLog>()))
10+
.Register<IBrokerRouter>(x => new BrokerRouter(x.Resolve<IKafkaOptions>(), x.Resolve<IKafkaLog>(), x.Resolve<IPartitionSelector>(), x.Resolve<IKafkaConnectionFactory>()))
11+
.Register<IProducer>(x => new Producer(x.Resolve<IBrokerRouter>(), x.Resolve<IKafkaOptions>()))
12+
.Register<IConsumerFactory>(x => new ConsumerFactory(x.Resolve<IBrokerRouter>(), x.Resolve<IKafkaLog>()))
13+
.Register<IBus>(x => new Bus(x.Resolve<IProducer>(), x.Resolve<IConsumerFactory>()));
1414
}
1515
}
1616
}

src/kafka-net/Configuration/IServiceRegistrator.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ namespace KafkaNet.Configuration
44
{
55
public interface IServiceRegistrator
66
{
7-
void Register<T>(T implementation) where T : class;
8-
void Register<T>(Func<IServiceProvider, T> factory) where T : class;
7+
IServiceRegistrator Register<T>(Func<IServiceProvider, T> factory) where T : class;
98
}
109
}

src/kafka-net/Configuration/ServiceImplementationNotFound.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
3+
namespace KafkaNet.Configuration
4+
{
5+
public class ServiceNotFound : Exception
6+
{
7+
public ServiceNotFound(string message, Exception exception) : base(message, exception)
8+
{
9+
}
10+
11+
public ServiceNotFound(string message)
12+
: base(message)
13+
{
14+
}
15+
}
16+
}

src/kafka-net/kafka-net.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<Compile Include="Interfaces\IKafkaOptions.cs" />
5656
<Compile Include="Configuration\IServiceProvider.cs" />
5757
<Compile Include="Configuration\IServiceRegistrator.cs" />
58-
<Compile Include="Configuration\ServiceImplementationNotFound.cs" />
58+
<Compile Include="Configuration\ServiceNotFound.cs" />
5959
<Compile Include="Default\DefaultKafkaConnectionFactory.cs" />
6060
<Compile Include="Interfaces\IMetadataQueries.cs" />
6161
<Compile Include="Interfaces\IKafkaTcpSocket.cs" />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace kafka_tests.Configuration
2+
{
3+
public class AnotherService : IService
4+
{
5+
}
6+
}

0 commit comments

Comments
 (0)