parent
2d2dac9cb3
commit
537c909dfc
52 changed files with 466 additions and 2919 deletions
@ -0,0 +1,74 @@ |
||||
--------------------------------------------------------------- |
||||
------------ 0x43---------------- |
||||
ReadClassDefinition |
||||
Hessian.ClassDef={"Name":"com.xxl.rpc.remoting.net.params.XxlRpcRequest","Fields":["requestId","createMillisTime","accessToken","className","methodName","version","parameterTypes","parameters"]} |
||||
------------------------------------------------------------ |
||||
------------ 0x60---------------- |
||||
ReadObjectCompact |
||||
------------ 0x30---------------- |
||||
ReadMediumString |
||||
------------ 0x4c---------------- |
||||
ReadLongFull |
||||
------------ 0x00---------------- |
||||
ReadShortString |
||||
------------ 0x1d---------------- |
||||
ReadShortString |
||||
------------ 0x08---------------- |
||||
ReadShortString |
||||
------------ 0x4e---------------- |
||||
ReadNull |
||||
------------ 0x71---------------- |
||||
ReadCompactFixList |
||||
------------ 0x43---------------- |
||||
ReadClassDefinition |
||||
------------ 0x61---------------- |
||||
ReadObjectCompact |
||||
------------ 0x0e---------------- |
||||
ReadShortString |
||||
Hessian.HessianObject=[{"Item1":"requestId","Item2":"e24123be4a76417ca6f41f227532b235"},{"Item1":"createMillisTime","Item2":1547819469003},{"Item1":"accessToken","Item2":""},{"Item1":"className","Item2":"com.xxl.job.core.biz.AdminBiz"},{"I |
||||
tem1":"methodName","Item2":"callback"},{"Item1":"version","Item2":null},{"Item1":"parameterTypes","Item2":[{"Name":"java.lang.Class","Fields":["name"]}]},{"Item1":"parameters","Item2":[{"Item1":"name","Item2":"java.util.List"}]}] |
||||
------------------------------------------------------------ |
||||
------------ 0x71---------------- |
||||
ReadCompactFixList |
||||
------------ 0x72---------------- |
||||
ReadCompactFixList |
||||
------------ 0x43---------------- |
||||
ReadClassDefinition |
||||
------------ 0x62---------------- |
||||
ReadObjectCompact |
||||
------------ 0x9b---------------- |
||||
ReadIntegerSingleByte |
||||
------------ 0x4c---------------- |
||||
ReadLongFull |
||||
------------ 0x43---------------- |
||||
ReadClassDefinition |
||||
System.Collections.Generic.List`1[System.Object]=[[{"Name":"com.xxl.job.core.biz.model.HandleCallbackParam","Fields":["logId","logDateTim","executeResult"]},[{"Item1":"logId","Item2":11},{"Item1":"logDateTim","Item2":1547819469000},{"Item1 |
||||
":"executeResult","Item2":{"Name":"com.xxl.job.core.biz.model.ReturnT","Fields":["code","msg","content"]}}]]] |
||||
------------------------------------------------------------ |
||||
------------ 0x63---------------- |
||||
ReadObjectCompact |
||||
------------ 0xc8---------------- |
||||
ReadIntegerTwoBytes |
||||
------------ 0x03---------------- |
||||
ReadShortString |
||||
------------ 0x07---------------- |
||||
ReadShortString |
||||
Hessian.HessianObject=[{"Item1":"code","Item2":200},{"Item1":"msg","Item2":"1bc"},{"Item1":"content","Item2":"acd3323"}] |
||||
------------------------------------------------------------ |
||||
------------ 0x62---------------- |
||||
ReadObjectCompact |
||||
------------ 0xa6---------------- |
||||
ReadIntegerSingleByte |
||||
------------ 0x4c---------------- |
||||
ReadLongFull |
||||
------------ 0x63---------------- |
||||
ReadObjectCompact |
||||
------------ 0xc9---------------- |
||||
ReadIntegerTwoBytes |
||||
------------ 0x03---------------- |
||||
ReadShortString |
||||
------------ 0x03---------------- |
||||
ReadShortString |
||||
Hessian.HessianObject=[{"Item1":"logId","Item2":22},{"Item1":"logDateTim","Item2":1547819469000},{"Item1":"executeResult","Item2":[{"Item1":"code","Item2":500},{"Item1":"msg","Item2":"aad"},{"Item1":"content","Item2":"cac"}]}] |
||||
------------------------------------------------------------ |
||||
------------------------------------------------------------ |
||||
Binary file not shown.
@ -1,12 +1,49 @@ |
||||
using DotXxlJob.Core.DefaultHandlers; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using Microsoft.Extensions.DependencyInjection; |
||||
|
||||
namespace DotXxlJob.Core |
||||
{ |
||||
public class DefaultJobHandlerFactory:IJobHandlerFactory |
||||
{ |
||||
private readonly IServiceProvider _provider; |
||||
private readonly Dictionary<string, IJobHandler> handlersCache = new Dictionary<string, IJobHandler>(); |
||||
public DefaultJobHandlerFactory(IServiceProvider provider) |
||||
{ |
||||
this._provider = provider; |
||||
Initialize(); |
||||
} |
||||
|
||||
private void Initialize() |
||||
{ |
||||
var list = this._provider.GetServices<IJobHandler>(); |
||||
if (list == null || !list.Any()) |
||||
{ |
||||
throw new TypeLoadException("IJobHandlers are not found in IServiceCollection"); |
||||
} |
||||
|
||||
foreach (var handler in list) |
||||
{ |
||||
var jobHandlerAttr = handler.GetType().GetCustomAttribute<JobHandlerAttribute>(); |
||||
var handlerName = jobHandlerAttr == null ? handler.GetType().Name : jobHandlerAttr.Name; |
||||
if (handlersCache.ContainsKey(handlerName)) |
||||
{ |
||||
throw new Exception($"same IJobHandler' name: [{handlerName}]"); |
||||
} |
||||
handlersCache.Add(handlerName,handler); |
||||
} |
||||
|
||||
} |
||||
|
||||
public IJobHandler GetJobHandler(string handlerName) |
||||
{ |
||||
return new HttpJobHandler(); |
||||
if (handlersCache.ContainsKey(handlerName)) |
||||
{ |
||||
return handlersCache[handlerName]; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,126 @@ |
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Reflection; |
||||
using System.Runtime.Serialization; |
||||
using DotXxlJob.Core.Model; |
||||
using Hessian; |
||||
|
||||
namespace DotXxlJob.Core |
||||
{ |
||||
public class HessianObjectHelper |
||||
{ |
||||
|
||||
private static readonly Dictionary<string,Dictionary<string,PropertyInfo>> TransferObjCache |
||||
= new Dictionary<string, Dictionary<string, PropertyInfo>>(); |
||||
private static readonly Dictionary<string,Type> TransferTypeCache |
||||
= new Dictionary<string, Type>(); |
||||
static HessianObjectHelper() |
||||
{ |
||||
|
||||
InitProperties(typeof(RpcRequest)); |
||||
|
||||
InitProperties(typeof(TriggerParam)); |
||||
|
||||
InitProperties(typeof(RpcResponse)); |
||||
|
||||
InitProperties(typeof(ReturnT)); |
||||
|
||||
InitProperties(typeof(HandleCallbackParam)); |
||||
|
||||
InitProperties(typeof(JavaClass)); |
||||
|
||||
InitProperties(typeof(RegistryParam)); |
||||
|
||||
InitProperties(typeof(LogResult)); |
||||
} |
||||
private static void InitProperties(Type type) |
||||
{ |
||||
var propertyInfos = new Dictionary<string, PropertyInfo>(); |
||||
var typeInfo = type.GetTypeInfo(); |
||||
var classAttr = type.GetCustomAttribute<DataContractAttribute>(); |
||||
if (classAttr == null) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
foreach (var property in typeInfo.DeclaredProperties) |
||||
{ |
||||
var attribute = property.GetCustomAttribute<DataMemberAttribute>(); |
||||
|
||||
if (null == attribute) |
||||
{ |
||||
continue; |
||||
} |
||||
|
||||
if (!property.CanRead || !property.CanWrite) |
||||
{ |
||||
continue; |
||||
} |
||||
|
||||
propertyInfos.Add(attribute.Name,property); |
||||
} |
||||
TransferTypeCache.Add(classAttr.Name,type); |
||||
TransferObjCache.Add(classAttr.Name,propertyInfos); |
||||
} |
||||
|
||||
public static object GetRealObjectValue(object value) |
||||
{ |
||||
if (value == null || IsSimpleType(value.GetType())) |
||||
{ |
||||
return value; |
||||
} |
||||
|
||||
if (value is HessianObject hessianObject) |
||||
{ |
||||
if(TransferObjCache.TryGetValue(hessianObject.TypeName,out var properties)) |
||||
{ |
||||
var instance = Activator.CreateInstance(TransferTypeCache[hessianObject.TypeName]); |
||||
foreach (var (k, v) in hessianObject) |
||||
{ |
||||
if (properties.TryGetValue(k, out var p)) |
||||
{ |
||||
p.SetValue(instance,GetRealObjectValue(v)); |
||||
} |
||||
} |
||||
|
||||
return instance; |
||||
} |
||||
} |
||||
|
||||
if (IsListType(value.GetType())) |
||||
{ |
||||
var listData = new List<object>(); |
||||
|
||||
var cList = value as List<object>; |
||||
foreach (var cItem in cList) |
||||
{ |
||||
listData.Add(GetRealObjectValue(cItem)); |
||||
} |
||||
|
||||
return listData; |
||||
} |
||||
throw new HessianException($"unknown item:{value.GetType()}"); |
||||
} |
||||
|
||||
private static bool IsListType(Type type) |
||||
{ |
||||
return typeof(ICollection).IsAssignableFrom(type); |
||||
} |
||||
private static bool IsSimpleType(Type typeInfo) |
||||
{ |
||||
if (typeInfo.IsValueType || typeInfo.IsEnum || typeInfo.IsPrimitive) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
if (typeof (string) == typeInfo) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -1,162 +0,0 @@ |
||||
using Hessian.Net.Specification; |
||||
|
||||
namespace Hessian.Net |
||||
{ |
||||
public class LeadingByte |
||||
{ |
||||
public byte Data |
||||
{ |
||||
get; |
||||
private set; |
||||
} |
||||
|
||||
public bool IsNull => Check(If.Marker.Equals(Marker.Null)); |
||||
|
||||
public bool IsTrue => Check(If.Marker.Equals(Marker.True)); |
||||
|
||||
public bool IsFalse => Check(If.Marker.Equals(Marker.False)); |
||||
|
||||
public bool IsTinyInt32 => Check(If.Marker.Between(0x80).And(0xBF)); |
||||
|
||||
public bool IsShortInt32 => Check(If.Marker.Between(0xC0).And(0xCF)); |
||||
|
||||
public bool IsCompactInt32 => Check(If.Marker.Between(0xD0).And(0xD7)); |
||||
|
||||
public bool IsUnpackedInt32 => Check(If.Marker.Equals(Marker.UnpackedInteger)); |
||||
|
||||
public bool IsTinyInt64 => Check(If.Marker.Between(0xD8).And(0xEF)); |
||||
|
||||
public bool IsShortInt64 => Check(If.Marker.Between(0xF0).And(0xFF)); |
||||
|
||||
public bool IsCompactInt64 => Check(If.Marker.Between(0x38).And(0x3F)); |
||||
|
||||
public bool IsPackedInt64 => Check(If.Marker.Equals(Marker.PackedLong)); |
||||
|
||||
public bool IsUnpackedInt64 => Check(If.Marker.Equals(Marker.UnpackedLong)); |
||||
|
||||
public bool IsCompactBinary => Check(If.Marker.Between(0x20).And(0x2f)); |
||||
|
||||
public bool IsNonfinalChunkBinary => Check(If.Marker.Equals(Marker.BinaryNonfinalChunk)); |
||||
|
||||
public bool IsFinalChunkBinary => Check(If.Marker.Equals(Marker.BinaryFinalChunk)); |
||||
|
||||
public bool IsZeroDouble => Check(If.Marker.Equals(Marker.DoubleZero)); |
||||
|
||||
public bool IsOneDouble => Check(If.Marker.Equals(Marker.DoubleOne)); |
||||
|
||||
public bool IsTinyDouble => Check(If.Marker.Equals(Marker.DoubleOctet)); |
||||
|
||||
public bool IsShortDouble => Check(If.Marker.Equals(Marker.DoubleShort)); |
||||
|
||||
public bool IsCompactDouble => Check(If.Marker.Equals(Marker.DoubleFloat)); |
||||
|
||||
public bool IsUnpackedDouble => Check(If.Marker.Equals(Marker.Double)); |
||||
|
||||
public bool IsTinyString => Check(If.Marker.Between(0x00).And(0x1F)); |
||||
|
||||
public bool IsCompactString => Check(If.Marker.Between(0x30).And(0x33)); |
||||
|
||||
public bool IsNonfinalChunkString => Check(If.Marker.Equals(Marker.StringNonfinalChunk)); |
||||
|
||||
public bool IsFinalChunkString => Check(If.Marker.Equals(Marker.StringFinalChunk)); |
||||
|
||||
public bool IsCompactDateTime => Check(If.Marker.Equals(Marker.DateTimeCompact)); |
||||
|
||||
public bool IsUnpackedDateTime => Check(If.Marker.Equals(Marker.DateTimeLong)); |
||||
|
||||
public bool IsClassDefinition => Check(If.Marker.Equals(Marker.ClassDefinition)); |
||||
|
||||
public bool IsShortObjectReference => Check(If.Marker.Between(0x60).And(0x6F)); |
||||
|
||||
public bool IsLongObjectReference => Check(If.Marker.Equals(Marker.ClassReference)); |
||||
|
||||
public bool IsInstanceReference => Check(If.Marker.Equals(Marker.InstanceReference)); |
||||
|
||||
public bool IsVarList => Check(If.Marker.Equals(Marker.VarList)); |
||||
|
||||
public bool IsFixedList => Check(If.Marker.Equals(Marker.FixedList)); |
||||
public bool IsVarListUntyped => Check(If.Marker.Equals(Marker.VarListUntyped)); |
||||
public bool IsFixListUntyped => Check(If.Marker.Equals(Marker.FixListUntyped)); |
||||
public bool IsCompactFixList => Check(If.Marker.Between(Marker.CompactFixListStart).And(Marker.CompactFixListEnd)); |
||||
public bool IsCompactFixListUntyped => Check(If.Marker.Between(Marker.CompactFixListUntypedStart).And(Marker.CompactFixListUntypedEnd)); |
||||
|
||||
|
||||
|
||||
public void SetData(byte value) |
||||
{ |
||||
Data = value; |
||||
} |
||||
|
||||
private bool Check(ISpecification<byte> specification) |
||||
{ |
||||
return specification.IsSatisfied(Data); |
||||
} |
||||
|
||||
private static class If |
||||
{ |
||||
internal static class Marker |
||||
{ |
||||
public static MarkerValue Equals(byte value) |
||||
{ |
||||
return new MarkerValue(value); |
||||
} |
||||
|
||||
public static MarkerMinValue Between(byte value) |
||||
{ |
||||
return new MarkerMinValue(value); |
||||
} |
||||
|
||||
internal abstract class MarkerSpecification : ISpecification<byte> |
||||
{ |
||||
public abstract bool IsSatisfied(byte arg); |
||||
} |
||||
|
||||
internal class MarkerValue : MarkerSpecification |
||||
{ |
||||
protected readonly byte value; |
||||
|
||||
public MarkerValue(byte value) |
||||
{ |
||||
this.value = value; |
||||
} |
||||
|
||||
public override bool IsSatisfied(byte arg) |
||||
{ |
||||
return value == arg; |
||||
} |
||||
} |
||||
|
||||
internal class MarkerMinValue : MarkerValue |
||||
{ |
||||
public MarkerMinValue(byte value) |
||||
: base(value) |
||||
{ |
||||
} |
||||
|
||||
public override bool IsSatisfied(byte arg) |
||||
{ |
||||
return value <= arg; |
||||
} |
||||
|
||||
public ISpecification<byte> And(byte max) |
||||
{ |
||||
return this.And(new MarkerMaxValue(max)); |
||||
} |
||||
} |
||||
|
||||
private class MarkerMaxValue : MarkerValue |
||||
{ |
||||
public MarkerMaxValue(byte value) |
||||
: base(value) |
||||
{ |
||||
} |
||||
|
||||
public override bool IsSatisfied(byte arg) |
||||
{ |
||||
return value >= arg; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -1,179 +0,0 @@ |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
|
||||
|
||||
namespace Hessian.Net |
||||
{ |
||||
public class ListElement: ISerializationElement |
||||
{ |
||||
private readonly IDictionary<Type, ISerializationElement> _catalog; |
||||
private readonly IObjectSerializerFactory _factory; |
||||
public ListElement(Type listType, IDictionary<Type, ISerializationElement> catalog, IObjectSerializerFactory factory) |
||||
{ |
||||
this.ObjectType = listType; |
||||
this._catalog = catalog; |
||||
this._factory = factory; |
||||
} |
||||
private readonly Lazy<ListTypeResolver> listTypeResolver = new Lazy<ListTypeResolver>(); |
||||
|
||||
public Type ObjectType { get; } |
||||
public ISerializationElement ChildSerializationElement { get; } |
||||
|
||||
public void Serialize(HessianOutputWriter writer, object graph, HessianSerializationContext context) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public object Deserialize(HessianInputReader reader, HessianSerializationContext context) |
||||
{ |
||||
object ret=null; |
||||
var preamble = reader.BeginList(); |
||||
switch (preamble) |
||||
{ |
||||
case ObjectPreamble.FixList: |
||||
ret =ReadFixList(reader, context); |
||||
break; |
||||
case ObjectPreamble.VarList: |
||||
ret = ReadVarList(reader, context); |
||||
break; |
||||
case ObjectPreamble.FixListUntyped: |
||||
ret = ReadFixListUntyped(reader, context); |
||||
break; |
||||
case ObjectPreamble.VarListUntyped: |
||||
ret = ReadVarListUntyped(reader, context); |
||||
break; |
||||
case ObjectPreamble.CompactFixList: |
||||
ret = ReadCompactFixList(reader, context); |
||||
break; |
||||
case ObjectPreamble.CompactFixListUntyped: |
||||
ret = ReadCompactFixListUntyped(reader, context); |
||||
break; |
||||
} |
||||
|
||||
reader.EndList(); |
||||
return ret; |
||||
} |
||||
|
||||
|
||||
private string ReadTypeName(HessianInputReader reader) |
||||
{ |
||||
|
||||
var tag = reader.Peek(); |
||||
|
||||
// A type name is either a string, or an integer reference to a |
||||
// string already read and stored in the type-name ref map. |
||||
if ((tag >= 0x00 && tag < 0x20) |
||||
|| (tag >= 0x30 && tag < 0x34) |
||||
|| tag == 0x52 |
||||
|| tag == 0x53) { |
||||
|
||||
var typeName = reader.ReadString(); |
||||
return typeName; |
||||
} |
||||
|
||||
reader.ReadInt32(); |
||||
return ""; |
||||
|
||||
} |
||||
|
||||
#region List |
||||
|
||||
private IList<object> ReadVarList(HessianInputReader reader, HessianSerializationContext context) |
||||
{ |
||||
var type = ReadTypeName(reader); |
||||
return ReadListCore(reader, context, type: type); |
||||
} |
||||
|
||||
private IList<object> ReadFixList(HessianInputReader reader, HessianSerializationContext context) |
||||
{ |
||||
var type = ReadTypeName(reader); |
||||
var length = reader.ReadInt32(); |
||||
return ReadListCore(reader, context, length, type); |
||||
} |
||||
|
||||
private IList<object> ReadVarListUntyped(HessianInputReader reader, HessianSerializationContext context) |
||||
{ |
||||
return ReadListCore(reader, context); |
||||
} |
||||
|
||||
private IList<object> ReadFixListUntyped(HessianInputReader reader, HessianSerializationContext context) |
||||
{ |
||||
var length = reader.ReadInt32(); |
||||
return ReadListCore(reader, context, length); |
||||
} |
||||
|
||||
private IList<object> ReadCompactFixList(HessianInputReader reader, HessianSerializationContext context) |
||||
{ |
||||
var tag = reader.LeadingByte.Data; |
||||
var length = tag - 0x70; |
||||
var type = ReadTypeName(reader); |
||||
return ReadListCore(reader, context, length, type); |
||||
} |
||||
|
||||
private IList<object> ReadCompactFixListUntyped(HessianInputReader reader, HessianSerializationContext context) |
||||
{ |
||||
var tag = reader.LeadingByte.Data; |
||||
var length = tag - 0x70; |
||||
return ReadListCore(reader, context, length); |
||||
} |
||||
|
||||
private IList<object> ReadListCore(HessianInputReader reader, HessianSerializationContext context, int? length = null, string type = null) |
||||
{ |
||||
var list = GetListInstance(type, length); |
||||
|
||||
//objectRefs.Add(list); |
||||
|
||||
if (length.HasValue) { |
||||
PopulateFixLengthList(reader, context, list, length.Value); |
||||
} else { |
||||
PopulateVarList(reader, context, list); |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
private IList<object> GetListInstance(string type, int? length = null) |
||||
{ |
||||
IList<object> list; |
||||
|
||||
if (length.HasValue) { |
||||
if (!listTypeResolver.Value.TryGetListInstance(type, length.Value, out list)) { |
||||
list = new List<object>(length.Value); |
||||
} |
||||
} else { |
||||
if (!listTypeResolver.Value.TryGetListInstance(type, out list)) { |
||||
list = new List<object>(); |
||||
} |
||||
} |
||||
|
||||
return list; |
||||
} |
||||
|
||||
private void PopulateFixLengthList(HessianInputReader reader, HessianSerializationContext context, IList<object> list, int length) |
||||
{ |
||||
var tag = reader.ReadByte(); //0x16 |
||||
|
||||
for (var i = 0; i < length; ++i) |
||||
{ |
||||
ObjectElement objectElement = new ObjectElement(); |
||||
var scheme = HessianSerializationScheme.CreateFromType(this.GetType(), this._factory); |
||||
var obj = scheme.Deserialize(reader, context); |
||||
list.Add(obj); |
||||
} |
||||
} |
||||
|
||||
private void PopulateVarList(HessianInputReader reader, HessianSerializationContext context, IList<object> list) |
||||
{ |
||||
while (true) { |
||||
var tag = reader.ReadByte(); |
||||
if (tag == 'Z') { |
||||
reader.ReadByte(); |
||||
break; |
||||
} |
||||
list.Add(this.ChildSerializationElement.Deserialize(reader, context)); |
||||
} |
||||
} |
||||
|
||||
#endregion |
||||
} |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
namespace Hessian.Net.Specification |
||||
{ |
||||
internal class AndSpecification<TParam> : BinarySpecification<TParam> |
||||
{ |
||||
public AndSpecification(ISpecification<TParam> left, ISpecification<TParam> right) |
||||
: base(left, right) |
||||
{ |
||||
} |
||||
|
||||
public override bool IsSatisfied(TParam arg) |
||||
{ |
||||
return Left.IsSatisfied(arg) && Right.IsSatisfied(arg); |
||||
} |
||||
} |
||||
} |
||||
@ -1,25 +0,0 @@ |
||||
namespace Hessian.Net.Specification |
||||
{ |
||||
public abstract class BinarySpecification<TParam> : ISpecification<TParam> |
||||
{ |
||||
public ISpecification<TParam> Left |
||||
{ |
||||
get; |
||||
protected set; |
||||
} |
||||
|
||||
public ISpecification<TParam> Right |
||||
{ |
||||
get; |
||||
protected set; |
||||
} |
||||
|
||||
protected BinarySpecification(ISpecification<TParam> left, ISpecification<TParam> right) |
||||
{ |
||||
Left = left; |
||||
Right = right; |
||||
} |
||||
|
||||
public abstract bool IsSatisfied(TParam arg); |
||||
} |
||||
} |
||||
@ -1,16 +0,0 @@ |
||||
namespace Hessian.Net.Specification |
||||
{ |
||||
/// <summary> |
||||
/// |
||||
/// </summary> |
||||
/// <typeparam name="TParam"></typeparam> |
||||
public interface ISpecification<in TParam> |
||||
{ |
||||
/// <summary> |
||||
/// Checks if current specification can be satisfied by given <paramref name="arg" /> |
||||
/// </summary> |
||||
/// <param name="arg">The value to check specification</param> |
||||
/// <returns>Flags if specification is satisfied successfuly</returns> |
||||
bool IsSatisfied(TParam arg); |
||||
} |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
namespace Hessian.Net.Specification |
||||
{ |
||||
/// <summary> |
||||
/// |
||||
/// </summary> |
||||
public static class Specification |
||||
{ |
||||
/// <summary> |
||||
/// |
||||
/// </summary> |
||||
/// <typeparam name="TParam"></typeparam> |
||||
/// <param name="specification"></param> |
||||
/// <returns></returns> |
||||
public static ISpecification<TParam> Not<TParam>(ISpecification<TParam> specification) |
||||
{ |
||||
return new NotSpecification<TParam>(specification); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue