diff --git a/ServiceAnt.sln b/ServiceAnt.sln
index 47ea89b..2a66828 100644
--- a/ServiceAnt.sln
+++ b/ServiceAnt.sln
@@ -26,6 +26,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4FE1FF00-52E
src\Directory.Build.props = src\Directory.Build.props
EndProjectSection
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceAnt.IocInstaller.DotNetCore", "src\ServiceAnt.IocInstaller.DotNetCore\ServiceAnt.IocInstaller.DotNetCore.csproj", "{47B742B7-62A5-45EC-99F2-1700F60D138E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceAnt.IocInstaller.DotNetCore.Test", "test\ServiceAnt.IocInstaller.DotNetCore.Test\ServiceAnt.IocInstaller.DotNetCore.Test.csproj", "{2A67FC30-B4C3-4945-BFF7-E25A5C496ADE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -56,6 +60,14 @@ Global
{ABC9A287-31CC-422B-84A2-6EAEF0BD448E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABC9A287-31CC-422B-84A2-6EAEF0BD448E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABC9A287-31CC-422B-84A2-6EAEF0BD448E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47B742B7-62A5-45EC-99F2-1700F60D138E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47B742B7-62A5-45EC-99F2-1700F60D138E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47B742B7-62A5-45EC-99F2-1700F60D138E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47B742B7-62A5-45EC-99F2-1700F60D138E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2A67FC30-B4C3-4945-BFF7-E25A5C496ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2A67FC30-B4C3-4945-BFF7-E25A5C496ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2A67FC30-B4C3-4945-BFF7-E25A5C496ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2A67FC30-B4C3-4945-BFF7-E25A5C496ADE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -68,6 +80,8 @@ Global
{1FA5221C-9A54-4132-B7CF-CF7CC7A30E59} = {0E041832-D5A5-4220-BD7D-95B03E66FF98}
{ABC9A287-31CC-422B-84A2-6EAEF0BD448E} = {BDFDFA2C-DA6F-4405-B7B0-31D1B0997150}
{4FE1FF00-52E7-4311-A21F-7C34831E62F1} = {5220EBDE-1FFD-4155-85A9-9A87DF0C073C}
+ {47B742B7-62A5-45EC-99F2-1700F60D138E} = {0E041832-D5A5-4220-BD7D-95B03E66FF98}
+ {2A67FC30-B4C3-4945-BFF7-E25A5C496ADE} = {BDFDFA2C-DA6F-4405-B7B0-31D1B0997150}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {52E5EADF-2B54-4C50-BF32-93550974966D}
diff --git a/src/ServiceAnt.IocInstaller.Autofac/ServiceAntModule.cs b/src/ServiceAnt.IocInstaller.Autofac/ServiceAntModule.cs
index 810e58a..57a9673 100644
--- a/src/ServiceAnt.IocInstaller.Autofac/ServiceAntModule.cs
+++ b/src/ServiceAnt.IocInstaller.Autofac/ServiceAntModule.cs
@@ -28,42 +28,44 @@ public ServiceAntModule(params System.Reflection.Assembly[] handlerAssemblies)
_handlerAssemblies = handlerAssemblies;
}
- ///
- /// Excute this method ater you builded container
- ///
- ///
- public static void RegisterHandlers(IComponentContext container)
- {
- foreach (var aHandlerAssembly in _handlerAssemblies)
- {
- var handlerTypes = aHandlerAssembly.GetTypes().Where(p => typeof(IHandler).IsAssignableFrom(p) && !p.IsInterface);
-
- foreach (var aHandler in handlerTypes)
- {
- RegisterHandlerType(container, aHandler);
- }
- }
- }
-
///
/// Intall dependenies and register handler function
///
///
protected override void Load(ContainerBuilder builder)
{
- var serviceBus = InProcessServiceBus.Default;
- builder.RegisterInstance(serviceBus).As();
- builder.RegisterType().AsSelf().As().SingleInstance();
- builder.RegisterType().AsSelf().As().SingleInstance();
+ var subcriptionsManager = new InMemorySubscriptionsManager();
+ var requestManager = new InMemoryRequestHandlerManager();
+
+ RegisterHandlers(subcriptionsManager, requestManager);
+ builder.RegisterInstance(subcriptionsManager).As().SingleInstance();
+ builder.RegisterInstance(requestManager).As().SingleInstance();
- builder.Register(ctx =>
+ builder.Register(ctx =>
{
return new IocResolver(ctx.Resolve());
});
+ builder.RegisterType().AsSelf().As().SingleInstance();
+
builder.RegisterAssemblyTypes(_handlerAssemblies).AsSelf();
+
+ }
+
+ private void RegisterHandlers(ISubscriptionManager subcriptionsManager, IRequestHandlerManager requestManager )
+ {
+ foreach (var aHandlerAssembly in _handlerAssemblies)
+ {
+ var handlerTypes = aHandlerAssembly.GetTypes().Where(p => typeof(IHandler).IsAssignableFrom(p) && !p.IsInterface);
+
+ foreach (var aHandler in handlerTypes)
+ {
+ RegisterHandlerType(subcriptionsManager, requestManager, aHandler);
+ }
+ }
}
- private static void RegisterHandlerType(IComponentContext container, Type aHandlerType)
+
+ private void RegisterHandlerType(ISubscriptionManager subcriptionsManager, IRequestHandlerManager requestManager , Type aHandlerType)
{
var interfaces = aHandlerType.GetInterfaces();
foreach (var aInterface in interfaces)
@@ -77,9 +79,9 @@ private static void RegisterHandlerType(IComponentContext container, Type aHandl
if (genericArgs.Length == 1)
{
if (typeof(IRequestHandler).IsAssignableFrom(aInterface))
- container.Resolve().AddRequestHandler(genericArgs[0], new IocHandlerFactory(container.Resolve(), aHandlerType, genericArgs[0]));
+ requestManager.AddRequestHandler(genericArgs[0], new IocHandlerFactory( aHandlerType, genericArgs[0]));
else
- container.Resolve().AddSubscription(genericArgs[0], new IocHandlerFactory(container.Resolve(), aHandlerType, genericArgs[0]));
+ subcriptionsManager.AddSubscription(genericArgs[0], new IocHandlerFactory( aHandlerType, genericArgs[0]));
}
}
}
diff --git a/src/ServiceAnt.IocInstaller.Castle/ServiceAntInstaller.cs b/src/ServiceAnt.IocInstaller.Castle/ServiceAntInstaller.cs
index 4610aa0..01ac12b 100644
--- a/src/ServiceAnt.IocInstaller.Castle/ServiceAntInstaller.cs
+++ b/src/ServiceAnt.IocInstaller.Castle/ServiceAntInstaller.cs
@@ -3,6 +3,7 @@
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using ServiceAnt.Handler.Request;
+using ServiceAnt.Infrastructure.Dependency;
using ServiceAnt.Request.Handler;
using ServiceAnt.Subscription;
using System;
@@ -42,7 +43,8 @@ public void Install(IWindsorContainer container, IConfigurationStore store)
_container = container;
container.Register(
- Component.For().Instance(InProcessServiceBus.Default),
+ Component.For().UsingFactoryMethod(ctx => new IocResolver(container)).LifestyleTransient(),
+ Component.For().ImplementedBy().LifestyleSingleton(),
Component.For().ImplementedBy().LifestyleSingleton(),
Component.For().ImplementedBy().LifestyleSingleton());
@@ -75,15 +77,13 @@ private void Kernel_ComponentRegistered(string key, IHandler handler)
continue;
}
- var resolver = new IocResolver(_container);
-
var genericArgs = aInterface.GetGenericArguments();
if (genericArgs.Length == 1)
{
if (typeof(IRequestHandler).GetTypeInfo().IsAssignableFrom(aInterface))
- _serviceBus.AddRequestHandler(genericArgs[0], new Base.IocHandlerFactory(resolver, handler.ComponentModel.Implementation, genericArgs[0]));
+ _serviceBus.AddRequestHandler(genericArgs[0], new Base.IocHandlerFactory(handler.ComponentModel.Implementation, genericArgs[0]));
else
- _serviceBus.AddSubscription(genericArgs[0], new Base.IocHandlerFactory(resolver, handler.ComponentModel.Implementation, genericArgs[0]));
+ _serviceBus.AddSubscription(genericArgs[0], new Base.IocHandlerFactory(handler.ComponentModel.Implementation, genericArgs[0]));
}
}
}
diff --git a/src/ServiceAnt.IocInstaller.DotNetCore/IocResolver.cs b/src/ServiceAnt.IocInstaller.DotNetCore/IocResolver.cs
new file mode 100644
index 0000000..b5c372f
--- /dev/null
+++ b/src/ServiceAnt.IocInstaller.DotNetCore/IocResolver.cs
@@ -0,0 +1,46 @@
+using ServiceAnt.Infrastructure.Dependency;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ServiceAnt.IocInstaller.DotNetCore
+{
+ ///
+ /// IocResolver
+ ///
+ public class IocResolver : IIocResolver
+ {
+ private readonly IServiceProvider _container;
+
+ ///
+ /// Constructor
+ ///
+ /// the container of castle
+ public IocResolver(IServiceProvider container)
+ {
+ _container = container;
+ }
+
+ ///
+ /// Releases a pre-resolved object. See Resolve methods.
+ ///
+ /// Object to be released
+ public void Release(object obj)
+ {
+ }
+
+ ///
+ /// Gets an object from IOC container.
+ /// Returning object must be Released (see ) after usage.
+ ///
+ /// Type of the object to cast
+ /// Type of the object to resolve
+ /// The object instance
+ public T Resolve(Type type)
+ {
+ return (T)_container.GetService(type);
+ }
+ }
+}
diff --git a/src/ServiceAnt.IocInstaller.DotNetCore/ServiceAnt.IocInstaller.DotNetCore.csproj b/src/ServiceAnt.IocInstaller.DotNetCore/ServiceAnt.IocInstaller.DotNetCore.csproj
new file mode 100644
index 0000000..c1c80cf
--- /dev/null
+++ b/src/ServiceAnt.IocInstaller.DotNetCore/ServiceAnt.IocInstaller.DotNetCore.csproj
@@ -0,0 +1,15 @@
+
+
+ The IOC installer of ServiceAnt for dotnet core
+ $(PackageTags)
+ netcoreapp2.0
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ServiceAnt.IocInstaller.DotNetCore/ServiceCollectionExtensions.cs b/src/ServiceAnt.IocInstaller.DotNetCore/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..cd47dd6
--- /dev/null
+++ b/src/ServiceAnt.IocInstaller.DotNetCore/ServiceCollectionExtensions.cs
@@ -0,0 +1,78 @@
+using Microsoft.Extensions.DependencyInjection;
+using ServiceAnt.Handler.Request;
+using ServiceAnt.Subscription;
+using System;
+using System.Reflection;
+using System.Linq;
+using ServiceAnt.Base;
+using ServiceAnt.Request.Handler;
+using ServiceAnt.Infrastructure.Dependency;
+using ServiceAnt.IocInstaller.DotNetCore;
+using ServiceAnt;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class ServiceCollectionExtensions
+ {
+ private static System.Reflection.Assembly[] _handlerAssemblies;
+
+ public static void AddServiceAnt(this IServiceCollection @this, params Assembly[] handlerAssemblies)
+ {
+ _handlerAssemblies = handlerAssemblies;
+
+ var subcriptionsManager = new InMemorySubscriptionsManager();
+ var requestManager = new InMemoryRequestHandlerManager();
+
+ RegisterHandlers(subcriptionsManager, requestManager);
+ @this.AddSingleton(subcriptionsManager);
+ @this.AddSingleton(requestManager);
+
+ @this.AddTransient(serviceProvider =>
+ {
+ return new IocResolver(serviceProvider);
+ });
+ @this.AddSingleton();
+
+
+ var allHandlerTypes = _handlerAssemblies.SelectMany(p => p.ExportedTypes).Where(p=>typeof(IHandler).IsAssignableFrom(p));
+ foreach (var aHandlerType in allHandlerTypes)
+ {
+ @this.AddTransient(aHandlerType);
+ }
+ }
+
+ private static void RegisterHandlers(ISubscriptionManager subcriptionsManager, IRequestHandlerManager requestManager)
+ {
+ foreach (var aHandlerAssembly in _handlerAssemblies)
+ {
+ var handlerTypes = aHandlerAssembly.GetTypes().Where(p => typeof(IHandler).IsAssignableFrom(p) && !p.IsInterface);
+
+ foreach (var aHandler in handlerTypes)
+ {
+ RegisterHandlerType(subcriptionsManager, requestManager, aHandler);
+ }
+ }
+ }
+
+ private static void RegisterHandlerType(ISubscriptionManager subcriptionsManager, IRequestHandlerManager requestManager, Type aHandlerType)
+ {
+ var interfaces = aHandlerType.GetInterfaces();
+ foreach (var aInterface in interfaces)
+ {
+ if (!typeof(IHandler).IsAssignableFrom(aInterface))
+ {
+ continue;
+ }
+
+ var genericArgs = aInterface.GetGenericArguments();
+ if (genericArgs.Length == 1)
+ {
+ if (typeof(IRequestHandler).IsAssignableFrom(aInterface))
+ requestManager.AddRequestHandler(genericArgs[0], new IocHandlerFactory(aHandlerType, genericArgs[0]));
+ else
+ subcriptionsManager.AddSubscription(genericArgs[0], new IocHandlerFactory(aHandlerType, genericArgs[0]));
+ }
+ }
+ }
+ }
+}
diff --git a/src/ServiceAnt/Base/IocHandlerFactory.cs b/src/ServiceAnt/Base/IocHandlerFactory.cs
index 2988b62..2c6922f 100644
--- a/src/ServiceAnt/Base/IocHandlerFactory.cs
+++ b/src/ServiceAnt/Base/IocHandlerFactory.cs
@@ -16,16 +16,23 @@ public class IocHandlerFactory : IHandlerFactory
///
/// ctor
///
- ///
///
///
- public IocHandlerFactory(IIocResolver iocResolver, Type handlerType, Type localEventType)
+ public IocHandlerFactory(Type handlerType, Type localEventType)
{
- _iocResolver = iocResolver;
_handlerType = handlerType;
_localEventType = localEventType;
}
+ ///
+ /// set the IocResolver to resolve service
+ ///
+ ///
+ public void SetIocResolver(IIocResolver iocResolver)
+ {
+ _iocResolver = iocResolver;
+ }
+
///
/// get handler
///
diff --git a/src/ServiceAnt/InProcessServiceBus.cs b/src/ServiceAnt/InProcessServiceBus.cs
index ce277c8..9cde160 100644
--- a/src/ServiceAnt/InProcessServiceBus.cs
+++ b/src/ServiceAnt/InProcessServiceBus.cs
@@ -3,6 +3,7 @@
using ServiceAnt.Base;
using ServiceAnt.Handler.Request;
using ServiceAnt.Handler.Subscription.Handler;
+using ServiceAnt.Infrastructure.Dependency;
using ServiceAnt.Request;
using ServiceAnt.Request.Handler;
using ServiceAnt.Subscription;
@@ -17,20 +18,37 @@ namespace ServiceAnt
///
public class InProcessServiceBus : IServiceBus
{
- private ISubscriptionManager _subcriptionManager;
- private IRequestHandlerManager _requestHandlerManager;
+ private readonly ISubscriptionManager _subcriptionManager;
+ private readonly IRequestHandlerManager _requestHandlerManager;
+ private readonly IIocResolver _iocResolver;
///
/// Use to log message of bus
///
public event LogBusMessage OnLogBusMessage;
- private static Lazy _defaultInstance = new Lazy();
+ private static InProcessServiceBus _defaultInstance;
+ private static object _lock = new object();
///
/// Default Instance
///
- public static InProcessServiceBus Default => _defaultInstance.Value;
+ public static InProcessServiceBus Default
+ {
+ get
+ {
+ if (_defaultInstance == null)
+ {
+ lock (_lock)
+ {
+ if (_defaultInstance == null)
+ _defaultInstance = new InProcessServiceBus();
+ }
+ }
+
+ return _defaultInstance;
+ }
+ }
///
/// Constructor
@@ -46,10 +64,13 @@ public InProcessServiceBus()
///
///
///
- public InProcessServiceBus(ISubscriptionManager subcriptionManager, IRequestHandlerManager requestHandlerManager)
+ ///
+ public InProcessServiceBus(ISubscriptionManager subcriptionManager, IRequestHandlerManager requestHandlerManager, IIocResolver iocResolver)
{
_subcriptionManager = subcriptionManager;
_requestHandlerManager = requestHandlerManager;
+ _iocResolver = iocResolver;
+ _defaultInstance = this;
}
#region Pub/Sub
@@ -153,6 +174,7 @@ private async Task ProcessEvent(string eventName, string message, TriggerOption
{
try
{
+ SetTheIocResolverIfIocHandlerFactory(aHandlerFactory);
var aHandler = aHandlerFactory.GetHandler();
if (aHandler is IDynamicEventHandler)
{
@@ -307,7 +329,7 @@ private async Task ProcessRequest(string eventName, string message, Trigge
{
if (requestContext.IsEnd)
break;
-
+ SetTheIocResolverIfIocHandlerFactory(aHandlerFactory);
try
{
var aHandler = aHandlerFactory.GetHandler();
@@ -346,5 +368,12 @@ private void LogMessage(LogLevel type, string value, Exception ex)
{
OnLogBusMessage?.Invoke(type, value, ex);
}
+
+ private void SetTheIocResolverIfIocHandlerFactory(IHandlerFactory aHandlerFactory)
+ {
+ var iocHandlerFactory = aHandlerFactory as IocHandlerFactory;
+ if (iocHandlerFactory != null)
+ iocHandlerFactory.SetIocResolver(_iocResolver);
+ }
}
}
diff --git a/test/ServiceAnt.IocInstaller.Autofac.Test/ServiceAntModule_Test.cs b/test/ServiceAnt.IocInstaller.Autofac.Test/ServiceAntModule_Test.cs
index 1c32820..3be9bf5 100644
--- a/test/ServiceAnt.IocInstaller.Autofac.Test/ServiceAntModule_Test.cs
+++ b/test/ServiceAnt.IocInstaller.Autofac.Test/ServiceAntModule_Test.cs
@@ -28,7 +28,6 @@ public async Task CanHandleEventByIocHandler()
var newContainer = new ContainerBuilder();
newContainer.RegisterModule(new ServiceAntModule(System.Reflection.Assembly.GetExecutingAssembly()));
var autofacContainer = newContainer.Build();
- ServiceAntModule.RegisterHandlers(autofacContainer);
await autofacContainer.Resolve().Publish(new TestEventTrigger() { Result = testValue });
@@ -42,7 +41,6 @@ public async Task CanHandleRequestByIocHandler()
var newContainer = new ContainerBuilder();
newContainer.RegisterModule(new ServiceAntModule(System.Reflection.Assembly.GetExecutingAssembly()));
var autofacContainer = newContainer.Build();
- ServiceAntModule.RegisterHandlers(autofacContainer);
var result = await autofacContainer.Resolve().SendAsync(new TestRequestTrigger() { Result = testValue });
diff --git a/test/ServiceAnt.IocInstaller.DotNetCore.Test/ServiceAnt.IocInstaller.DotNetCore.Test.csproj b/test/ServiceAnt.IocInstaller.DotNetCore.Test/ServiceAnt.IocInstaller.DotNetCore.Test.csproj
new file mode 100644
index 0000000..7178aa8
--- /dev/null
+++ b/test/ServiceAnt.IocInstaller.DotNetCore.Test/ServiceAnt.IocInstaller.DotNetCore.Test.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp2.0
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/ServiceAnt.IocInstaller.DotNetCore.Test/ServiceCollectionExtensions_Test.cs b/test/ServiceAnt.IocInstaller.DotNetCore.Test/ServiceCollectionExtensions_Test.cs
new file mode 100644
index 0000000..2c6a7ba
--- /dev/null
+++ b/test/ServiceAnt.IocInstaller.DotNetCore.Test/ServiceCollectionExtensions_Test.cs
@@ -0,0 +1,74 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using ServiceAnt.Request;
+using ServiceAnt.Request.Handler;
+using ServiceAnt.Subscription;
+using ServiceAnt.Subscription.Handler;
+using System;
+using System.Threading.Tasks;
+
+namespace ServiceAnt.IocInstaller.DotNetCore.Test
+{
+ [TestClass]
+ public class ServiceCollectionExtensions_Test
+ {
+ private static string RESULT_CONTAINER = "";
+ private readonly IServiceProvider _provider;
+
+ public ServiceCollectionExtensions_Test()
+ {
+ IServiceCollection services = new ServiceCollection();
+ services.AddServiceAnt(System.Reflection.Assembly.GetExecutingAssembly());
+ _provider = services.BuildServiceProvider();
+ }
+
+ [TestMethod]
+ public async Task CanHandleEventByIocHandler()
+ {
+ var testValue = "HelloWorld";
+
+ await _provider.GetService().Publish(new TestEventTrigger() { Result = testValue });
+
+ Assert.AreEqual(testValue, RESULT_CONTAINER);
+ }
+
+ [TestMethod]
+ public async Task CanHandleRequestByIocHandler()
+ {
+ var testValue = "HelloWorld2";
+
+ var result = await _provider.GetService().SendAsync(new TestRequestTrigger() { Result = testValue });
+
+ Assert.AreEqual(testValue, result);
+ }
+
+ public class TestEventTrigger : IEventTrigger
+ {
+ public string Result { get; set; }
+ }
+
+ public class TestRequestTrigger : IRequestTrigger
+ {
+ public string Result { get; set; }
+ }
+
+ public class IocEventHandler : IEventHandler
+ {
+ public Task HandleAsync(TestEventTrigger param)
+ {
+ RESULT_CONTAINER = param.Result;
+
+ return Task.Delay(1);
+ }
+ }
+
+ public class IocRequestHandler : IRequestHandler
+ {
+ public Task HandleAsync(TestRequestTrigger param, IRequestHandlerContext handlerContext)
+ {
+ handlerContext.Response = param.Result;
+ return Task.Delay(1);
+ }
+ }
+ }
+}