Skip to content

Commit

Permalink
Created DNX project targeting DNXCore50, modified shared source to ge…
Browse files Browse the repository at this point in the history
…t it to compile.
  • Loading branch information
Noah Potash authored and micdenny committed Aug 13, 2016
1 parent a12d373 commit a5ec600
Show file tree
Hide file tree
Showing 32 changed files with 459 additions and 15 deletions.
20 changes: 20 additions & 0 deletions Source/EasyNetQ DNX/EasyNetQ DNX.xproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>

<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>ed270a39-d32c-438a-bf4f-aa0e66c7879c</ProjectGuid>
<RootNamespace>EasyNetQ_DNX</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>

<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
38 changes: 38 additions & 0 deletions Source/EasyNetQ DNX/Internals/AsyncSemaphore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Threading;
using System.Threading.Tasks;

namespace EasyNetQ.Internals
{
/// <summary>
/// AsyncSemaphore should be used with a lot of care.
/// </summary>
public class AsyncSemaphore
{
private readonly SemaphoreSlim semaphore;

public AsyncSemaphore(int initial)
{
semaphore = new SemaphoreSlim(initial);
}

public int Available
{
get { return semaphore.CurrentCount; }
}

public void Wait()
{
semaphore.Wait();
}

public Task WaitAsync()
{
return semaphore.WaitAsync();
}

public void Release()
{
semaphore.Release();
}
}
}
152 changes: 152 additions & 0 deletions Source/EasyNetQ DNX/Internals/TaskHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.Threading.Tasks;

namespace EasyNetQ.Internals
{
public static class TaskHelpers
{
/// <summary>
/// We want to prevent callers hijacking the reader thread; this is a bit nasty, but works;
/// see http://stackoverflow.com/a/22588431/23354 for more information; a huge
/// thanks to Eli Arbel for spotting this (even though it is pure evil; it is *my kind of evil*)
/// </summary>
private static readonly Func<Task, bool> IsSyncSafe;

static TaskHelpers()
{
try
{
var taskType = typeof(Task);
var continuationField = taskType.GetField("m_continuationObject", BindingFlags.Instance | BindingFlags.NonPublic);
var safeScenario = taskType.GetNestedType("SetOnInvokeMres", BindingFlags.NonPublic);
if (continuationField != null && continuationField.FieldType == typeof(object) && safeScenario != null)
{
var method = new DynamicMethod("IsSyncSafe", typeof(bool), new[] { typeof(Task) }, typeof(Task), true);
var il = method.GetILGenerator();
//var hasContinuation = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, continuationField);
Label nonNull = il.DefineLabel(), goodReturn = il.DefineLabel();
// check if null
il.Emit(OpCodes.Brtrue_S, nonNull);
il.MarkLabel(goodReturn);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ret);

// check if is a SetOnInvokeMres - if so, we're OK
il.MarkLabel(nonNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, continuationField);
il.Emit(OpCodes.Isinst, safeScenario);
il.Emit(OpCodes.Brtrue_S, goodReturn);

il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Ret);

IsSyncSafe = (Func<Task, bool>)method.CreateDelegate(typeof(Func<Task, bool>));

// and test them (check for an exception etc)
var tcs = new TaskCompletionSource<int>();
var expectTrue = IsSyncSafe(tcs.Task);
tcs.Task.ContinueWith(delegate { });
var expectFalse = IsSyncSafe(tcs.Task);
tcs.SetResult(0);
if (!expectTrue || expectFalse)
{
Debug.WriteLine("IsSyncSafe reported incorrectly!");
Trace.WriteLine("IsSyncSafe reported incorrectly!");
// revert to not trusting /them
IsSyncSafe = null;
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Trace.WriteLine(ex.Message);
IsSyncSafe = null;
}
if (IsSyncSafe == null)
IsSyncSafe = t => false; // assume: not
}

public static readonly Task Completed = FromResult<object>(null);

public static Task ExecuteSynchronously(Action action)
{
var tcs = new TaskCompletionSource<object>();
try
{
action();
tcs.SetResult(null);
}
catch (Exception e)
{
tcs.SetException(e);
}
return tcs.Task;
}

public static Task<T> FromResult<T>(T result)
{
return Task.FromResult(result);
}

public static Task FromException(Exception ex)
{
var tcs = new TaskCompletionSource<object>();
tcs.SetException(ex);
return tcs.Task;
}

public static Task Delay(TimeSpan delay, CancellationToken cancellation)
{
return Task.Delay(delay, cancellation);
}

public static Task<Task> WhenAny(params Task[] tasks)
{
return Task.WhenAny(tasks);
}

public static void TrySetResultSafe<T>(this TaskCompletionSource<T> source, T result)
{
if (IsSyncSafe(source.Task))
{
source.TrySetResult(result);
}
else
{
Task.Run(() => source.TrySetResult(result));
}
}

public static void TrySetCanceledSafe<T>(this TaskCompletionSource<T> source)
{
if (IsSyncSafe(source.Task))
{
source.TrySetCanceled();
}
else
{
Task.Run(() => source.TrySetCanceled());
}
}

public static void TrySetExceptionSafe<T>(this TaskCompletionSource<T> source, Exception exception)
{
if (IsSyncSafe(source.Task))
{
source.TrySetException(exception);
}
else
{
Task.Run(() => source.TrySetException(exception));
}
}
}
}
23 changes: 23 additions & 0 deletions Source/EasyNetQ DNX/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EasyNetQ_DNX")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EasyNetQ_DNX")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("ed270a39-d32c-438a-bf4f-aa0e66c7879c")]
49 changes: 49 additions & 0 deletions Source/EasyNetQ DNX/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"version": "1.0.0-*",
"description": "EasyNetQ DNX Class Library",
"authors": [ "SapientGuardian" ],
"tags": [ "" ],
"projectUrl": "",
"licenseUrl": "",
"compile": [ "../EasyNetQ/*.cs", "../EasyNetQ/**/*.cs" ],
"frameworks": {
"dotnet5.4": {
"dependencies": {
"Microsoft.CSharp": "4.0.1-beta-23516",
"System.Collections": "4.0.11-beta-23516",
"System.Linq": "4.0.1-beta-23516",
"System.Threading": "4.0.11-beta-23516",
"System.Reflection.TypeExtensions": "4.1.0-beta-23516",
"System.Runtime.Handles": "4.0.1-beta-23516",
"System.Reflection": "4.1.0-beta-23516",
"System.Threading.Tasks": "4.0.11-beta-23516",
"System.Reflection.Primitives": "4.0.1-beta-23516",
"System.Reflection.Extensions": "4.0.1-beta-23516",
"System.Runtime.InteropServices": "4.0.21-beta-23516",
"System.Linq.Expressions": "4.0.11-beta-23516",
"System.Runtime.Extensions": "4.0.11-beta-23516",
"System.Resources.ResourceManager": "4.0.1-beta-23516",
"System.Globalization": "4.0.11-beta-23516",
"System.Diagnostics.Debug": "4.0.11-beta-23516",
"System.Dynamic.Runtime": "4.0.11-beta-23516",
"System.Reflection.Emit": "4.0.1-beta-23516",
"System.Reflection.Emit.ILGeneration": "4.0.1-beta-23516",
"System.Reflection.Emit.Lightweight": "4.0.1-beta-23516",
"System.ObjectModel": "4.0.11-beta-23516",
"System.Text.Encoding.Extensions": "4.0.11-beta-23516",
"System.IO.FileSystem.Primitives": "4.0.1-beta-23516",
"System.IO.FileSystem": "4.0.1-beta-23516",
"System.IO": "4.0.11-beta-23516",
"System.Diagnostics.Tools": "4.0.1-beta-23516",
"System.Text.Encoding": "4.0.11-beta-23516",
"System.IO.Compression": "4.1.0-beta-23516",
"System.Threading.Timer": "4.0.1-beta-23516",
"System.Net.NameResolution": "4.0.0-beta-23516"
}
}
},
"dependencies": {
"Newtonsoft.Json": "8.0.1",
"RabbitMQ.Client.CoreClrUnofficial": "3.5.6.1"
}
}
5 changes: 5 additions & 0 deletions Source/EasyNetQ.sln
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyNetQ.Tests.Tasks", "EasyNetQ.Tests.Tasks\EasyNetQ.Tests.Tasks.csproj", "{A5CF1B2C-E390-4BFF-BB1A-0F171DB0D6BD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyNetQ.DI.LightInject", "EasyNetQ.DI.LightInject\EasyNetQ.DI.LightInject.csproj", "{3AD2CD4A-8969-4C2D-8EAA-9FC800585678}"
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "EasyNetQ DNX", "EasyNetQ DNX\EasyNetQ DNX.xproj", "{ED270A39-D32C-438A-BF4F-AA0E66C7879C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyNetQ.DI.SimpleInjector", "EasyNetQ.DI.SimpleInjector\EasyNetQ.DI.SimpleInjector.csproj", "{519185ED-B7BE-426E-8F2F-9410F8621AC4}"
EndProject
Expand Down Expand Up @@ -193,6 +194,10 @@ Global
{519185ED-B7BE-426E-8F2F-9410F8621AC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{519185ED-B7BE-426E-8F2F-9410F8621AC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{519185ED-B7BE-426E-8F2F-9410F8621AC4}.Release|Any CPU.Build.0 = Release|Any CPU
{ED270A39-D32C-438A-BF4F-AA0E66C7879C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED270A39-D32C-438A-BF4F-AA0E66C7879C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED270A39-D32C-438A-BF4F-AA0E66C7879C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED270A39-D32C-438A-BF4F-AA0E66C7879C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
31 changes: 29 additions & 2 deletions Source/EasyNetQ/AutoSubscribe/AutoSubscriber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,14 @@ protected virtual void InvokeMethods(IEnumerable<KeyValuePair<Type, AutoSubscrib
.GetMethod(dispatchName, BindingFlags.Instance | BindingFlags.Public)
.MakeGenericMethod(subscriptionInfo.MessageType, subscriptionInfo.ConcreteType);

#if DOTNET5_4
var dispatchDelegate = dispatchMethod.CreateDelegate(
subscriberTypeFromMessageTypeDelegate(subscriptionInfo.MessageType),
AutoSubscriberMessageDispatcher);
#else
var dispatchDelegate = Delegate.CreateDelegate(subscriberTypeFromMessageTypeDelegate(subscriptionInfo.MessageType), AutoSubscriberMessageDispatcher, dispatchMethod);
#endif

var subscriptionAttribute = GetSubscriptionAttribute(subscriptionInfo);
var subscriptionId = subscriptionAttribute != null ? subscriptionAttribute.SubscriptionId : GenerateSubscriptionId(subscriptionInfo);
var busSubscribeMethod = genericBusSubscribeMethod.MakeGenericMethod(subscriptionInfo.MessageType);
Expand Down Expand Up @@ -191,7 +198,7 @@ private Action<ISubscriptionConfiguration> GenerateConfigurationFromTopics(IEnum
private IEnumerable<string> GetTopAttributeValues(AutoSubscriberConsumerInfo subscriptionInfo)
{
var consumeMethod = ConsumeMethod(subscriptionInfo);
object[] customAttributes = consumeMethod.GetCustomAttributes(typeof(ForTopicAttribute), true);
object[] customAttributes = consumeMethod.GetCustomAttributes(typeof(ForTopicAttribute), true).Cast<object>().ToArray();
return customAttributes
.OfType<ForTopicAttribute>()
.Select(a => a.Topic);
Expand Down Expand Up @@ -224,15 +231,20 @@ private Action<ISubscriptionConfiguration> AutoSubscriberConsumerInfo(AutoSubscr
private SubscriptionConfigurationAttribute GetSubscriptionConfigurationAttributeValue(AutoSubscriberConsumerInfo subscriptionInfo)
{
var consumeMethod = ConsumeMethod(subscriptionInfo);
object[] customAttributes = consumeMethod.GetCustomAttributes(typeof(SubscriptionConfigurationAttribute), true);
object[] customAttributes = consumeMethod.GetCustomAttributes(typeof(SubscriptionConfigurationAttribute), true).Cast<object>().ToArray();
return customAttributes
.OfType<SubscriptionConfigurationAttribute>()
.FirstOrDefault();
}

protected virtual bool IsValidMarkerType(Type markerType)
{
#if DOTNET5_4
return markerType.GetTypeInfo().IsInterface && markerType.GetMethods().Any(m => m.Name == ConsumeMethodName);
#else
return markerType.IsInterface && markerType.GetMethods().Any(m => m.Name == ConsumeMethodName);
#endif

}

protected virtual MethodInfo GetSubscribeMethodOfBus(string methodName, Type parmType)
Expand Down Expand Up @@ -268,6 +280,18 @@ private MethodInfo GetExplicitlyDeclaredInterfaceMethod(Type messageType)

protected virtual IEnumerable<KeyValuePair<Type, AutoSubscriberConsumerInfo[]>> GetSubscriptionInfos(IEnumerable<Type> types,Type interfaceType)
{
#if DOTNET5_4
foreach (var concreteType in types.Where(t => t.GetTypeInfo().IsClass && !t.GetTypeInfo().IsAbstract))
{
var subscriptionInfos = concreteType.GetInterfaces()
.Where(i => i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == interfaceType && !i.GetGenericArguments()[0].IsGenericParameter)
.Select(i => new AutoSubscriberConsumerInfo(concreteType, i, i.GetGenericArguments()[0]))
.ToArray();

if (subscriptionInfos.Any())
yield return new KeyValuePair<Type, AutoSubscriberConsumerInfo[]>(concreteType, subscriptionInfos);
}
#else
foreach (var concreteType in types.Where(t => t.IsClass && !t.IsAbstract))
{
var subscriptionInfos = concreteType.GetInterfaces()
Expand All @@ -278,6 +302,9 @@ protected virtual IEnumerable<KeyValuePair<Type, AutoSubscriberConsumerInfo[]>>
if (subscriptionInfos.Any())
yield return new KeyValuePair<Type, AutoSubscriberConsumerInfo[]>(concreteType, subscriptionInfos);
}
#endif


}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace EasyNetQ.AutoSubscribe
{
#if !DOTNET5_4
#endif
[AttributeUsage(AttributeTargets.Method)]
public class AutoSubscriberConsumerAttribute : Attribute
{
Expand Down
Loading

0 comments on commit a5ec600

Please sign in to comment.