Skip to content

Commit

Permalink
Merge pull request #1 from ziyasal/dev
Browse files Browse the repository at this point in the history
Parallel and isolated handler executin process are implemented and presented to user via a configuration parameter which was sent over Bus constructor.
  • Loading branch information
bugthesystem committed Mar 14, 2016
2 parents 568133c + 95b1eae commit cbdd8a7
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .vs/config/applicationhost.config
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
</site>
<site name="Sample.MvcApp" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\sc\github\FunnyBus\Samples\MvcApp" />
<virtualDirectory path="/" physicalPath="C:\Workspace\FunnyBus\Samples\MvcApp" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:1039:localhost" />
Expand Down
38 changes: 33 additions & 5 deletions FunnyBus.Integration.Autofac/AutofacFunnyDependencyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ namespace FunnyBus.Integration.Autofac
{
public class AutofacFunnyDependencyResolver : IFunnyDependencyResolver
{
private readonly IContainer _container;
private readonly ILifetimeScope _rootScope;
private List<AutofacFunnyDependencyResolver> _childs = new List<AutofacFunnyDependencyResolver>();

/// <summary>
/// C'tor
/// </summary>
/// <param name="container">Autofac container instance</param>
public AutofacFunnyDependencyResolver(IContainer container)
public AutofacFunnyDependencyResolver(ILifetimeScope container)
{
_container = container;
_rootScope = container;
}

/// <summary>
Expand All @@ -24,7 +26,7 @@ public AutofacFunnyDependencyResolver(IContainer container)
/// <returns></returns>
public object GetService(Type serviceType)
{
return _container.Resolve(serviceType);
return _rootScope.Resolve(serviceType);
}

/// <summary>
Expand All @@ -35,9 +37,35 @@ public object GetService(Type serviceType)
public IEnumerable<object> GetServices(Type serviceType)
{
var enumerableServiceType = typeof(IEnumerable<>).MakeGenericType(serviceType);
var instance = _container.Resolve(enumerableServiceType);
var instance = _rootScope.Resolve(enumerableServiceType);

return (IEnumerable<object>)instance;
}

public IFunnyDependencyResolver BeginNewScope()
{
AutofacFunnyDependencyResolver newScope = new AutofacFunnyDependencyResolver(_rootScope.BeginLifetimeScope());
_childs.Add(newScope);
return newScope;
}

public void Dispose()
{
if (_childs != null && _childs.Count > 0)
{
foreach (AutofacFunnyDependencyResolver dependencyScope in _childs)
{
if (dependencyScope != null)
{
dependencyScope.Dispose();
}
}
}

if (_rootScope != null)
{
_rootScope.Dispose();
}
}
}
}
66 changes: 61 additions & 5 deletions FunnyBus/Bus.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FunnyBus.Exceptions;
using FunnyBus.Infrastructure;
using FunnyBus.Infrastructure.Store;
using FunnyBus.Infrastructure.Reflection;
using FunnyBus.Infrastructure.Configuration;
Expand Down Expand Up @@ -165,9 +169,21 @@ public void Publish(object message)

if (_store.IsActionHandler(messageType))
{
foreach (var handlerDefinition in _store.GetActionHandlerDefinitionsByMessageType(messageType))
List<ActionHandlerDefinition> handlerDefinitions = _store.GetActionHandlerDefinitionsByMessageType(messageType);

if (handlerDefinitions != null && handlerDefinitions.Any())
{
handlerDefinition.ProxyAction(message);
if (ParallelHandlerExecution)
{
Parallel.ForEach(handlerDefinitions, (handlerDefinition) => handlerDefinition.ProxyAction(message));
}
else
{
foreach (ActionHandlerDefinition actionHandlerDefinition in handlerDefinitions)
{
actionHandlerDefinition.ProxyAction(message);
}
}
}
}
else
Expand All @@ -176,10 +192,8 @@ public void Publish(object message)

if (handlerTypeAsIHandle == null) { throw new HandlerNotFoundException(messageType); }

dynamic handlerInstance = DependencyResolver.GetService(handlerTypeAsIHandle);
handlerInstance.Handle((dynamic)message);
StartExecutionProcess(message, handlerTypeAsIHandle);
}

}

internal IFunnyDependencyResolver DependencyResolver { get; set; }
Expand All @@ -201,6 +215,10 @@ public void SetResolver(IFunnyDependencyResolver funnyDependencyResolver)
/// </summary>
public bool AutoScanHandlers { private get; set; }

public bool ParallelHandlerExecution { private get; set; }

public bool IsolatedHandlerScopes { private get; set; }

#endregion

private void UnSubscribeImpl(Type key)
Expand All @@ -219,5 +237,43 @@ private void AddToRegistry(Type handler)
Guard.AgainstNullArgument("handler", handler);
_store.Add(handler);
}

private void ExecuteHandlers(IFunnyDependencyResolver scope, Type handlerTypeAsIHandle, object message)
{
IEnumerable<dynamic> handlers = scope.GetServices(handlerTypeAsIHandle);

if (handlers != null && handlers.Any())
{
if (ParallelHandlerExecution)
{
Parallel.ForEach(handlers, (handler) => handler.Handle((dynamic)message));
}
else
{
foreach (dynamic handler in handlers)
{
handler.Handle((dynamic)message);
}
}
}
}

private void StartExecutionProcess(object message, Type handlerTypeAsIHandle)
{
if (IsolatedHandlerScopes)
{
Task.Factory.StartNew(() =>
{
using (var scope = DependencyResolver.BeginNewScope())
{
ExecuteHandlers(scope, handlerTypeAsIHandle, message);
}
});
}
else
{
ExecuteHandlers(DependencyResolver, handlerTypeAsIHandle, message);
}
}
}
}
1 change: 1 addition & 0 deletions FunnyBus/FunnyBus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<Compile Include="Exceptions\HandlerNotFoundException.cs" />
<Compile Include="Guard.cs" />
<Compile Include="Infrastructure\ActionHandlerDefinition.cs" />
<Compile Include="Infrastructure\DependencyInjection\IFunnyDependencyScope.cs" />
<Compile Include="Infrastructure\TypedHandlerDefinition.cs" />
<Compile Include="Infrastructure\IHandleDefinition.cs" />
<Compile Include="Infrastructure\Reflection\HandlerScanner.cs" />
Expand Down
1 change: 1 addition & 0 deletions FunnyBus/Infrastructure/ActionHandlerDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace FunnyBus.Infrastructure
internal class ActionHandlerDefinition : IHandleDefinition
{
public Action<object> ProxyAction { get; set; }

public Type MessageType { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ public interface IConfigurationContext
{
void SetResolver(IFunnyDependencyResolver funnyDependencyResolver);
bool AutoScanHandlers { set; }
bool ParallelHandlerExecution { set; }
bool IsolatedHandlerScopes { set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

namespace FunnyBus.Infrastructure.DependencyInjection
{
public interface IFunnyDependencyResolver
public interface IFunnyDependencyResolver : IDisposable
{
object GetService(Type serviceType);

IEnumerable<object> GetServices(Type serviceType);

IFunnyDependencyResolver BeginNewScope();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;

namespace FunnyBus.Infrastructure.DependencyInjection
{
public interface IFunnyDependencyScope : IDisposable
{
T Resolve<T>();

T Resolve<T>(string key);

IFunnyDependencyScope CreateNew();
}
}
8 changes: 4 additions & 4 deletions FunnyBus/Infrastructure/Reflection/HandlerScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public bool RegisterHandlerDefinitions(Action<Type> addToRegistry)
{
foreach (Type @interface in definedType.GetInterfaces())
{
//#if NET40
#if NET40
Type[] genericTypeArguments = @interface.GetGenericArguments();
//#else
// Type[] genericTypeArguments = @interface.GenericTypeArguments;
//#endif
#else
Type[] genericTypeArguments = @interface.GenericTypeArguments;
#endif
Type genericType = null;

switch (genericTypeArguments.Count())
Expand Down
3 changes: 2 additions & 1 deletion Samples/ConsoleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public static void Main()
builder.Register(context => Bus.Instance).As<IBus>();

IContainer container = builder.Build();
Bus.Configure(context => context.SetResolver(new AutofacFunnyDependencyResolver(container)));
Bus.Configure(c => c.SetResolver(new AutofacFunnyDependencyResolver(container)));
Bus.Configure(c => c.ParallelHandlerExecution = true);

var bus = container.Resolve<IBus>();

Expand Down
14 changes: 14 additions & 0 deletions Samples/Data/AnotherProductHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using FunnyBus.Infrastructure;
using Sample.Contracts;

namespace Sample.Data
{
public class AnotherProductHandler : IHandle<CreateProductMessage>
{
public void Handle(CreateProductMessage message)
{
Console.WriteLine(String.Join(" ", "AnotherProductHandler", message.Name));
}
}
}
1 change: 1 addition & 0 deletions Samples/Data/Sample.Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AnotherProductHandler.cs" />
<Compile Include="ShoppingCartHandler.cs" />
<Compile Include="ProductHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down
6 changes: 5 additions & 1 deletion Samples/MvcApp/App_Start/IoCConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ public static void Register()

IContainer container = builder.Build();

Bus.Configure(context => context.SetResolver(new AutofacFunnyDependencyResolver(container)));
Bus.Configure(context =>
{
context.SetResolver(new AutofacFunnyDependencyResolver(container));
context.ParallelHandlerExecution = true;
});

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
Expand Down

0 comments on commit cbdd8a7

Please sign in to comment.