This commit is contained in:
Eugene Sadovoi 2019-01-05 18:18:13 -05:00
Родитель e6a55bfaf8
Коммит 71c75f5d02
29 изменённых файлов: 1283 добавлений и 1163 удалений

Просмотреть файл

@ -1,137 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Injection;
using Unity.Policy;
using Unity.Storage;
namespace Unity.Processors
{
public delegate Expression MemberExpressionFactory(Attribute attribute, Expression member, object info, Type type, object resolver);
public abstract partial class BuildMemberProcessor<TMemberInfo, TData> where TMemberInfo : MemberInfo
{
#region Fields
protected (Type type, MemberExpressionFactory factory)[] ExpressionFactories;
#endregion
#region Public Methods
public void Add(Type type, MemberExpressionFactory factory)
{
for (var i = 0; i < ExpressionFactories.Length; i++)
{
if (ExpressionFactories[i].type != type) continue;
ExpressionFactories[i].factory = factory;
return;
}
var factories = new (Type type, MemberExpressionFactory factory)[ExpressionFactories.Length + 1];
Array.Copy(ExpressionFactories, factories, ExpressionFactories.Length);
factories[ExpressionFactories.Length] = (type, factory);
ExpressionFactories = factories;
}
#endregion
#region Overrides
/// <inheritdoc />
public override IEnumerable<Expression> GetBuildSteps(Type type, IPolicySet registration)
{
var selector = GetPolicy<ISelect<TMemberInfo>>(registration);
var members = selector.Select(type, registration);
return ExpressionsFromSelected(type, members);
}
#endregion
#region Build Expression
protected virtual IEnumerable<Expression> ExpressionsFromSelected(Type type, IEnumerable<object> members)
{
foreach (var member in members)
{
switch (member)
{
case TMemberInfo memberInfo:
yield return BuildMemberExpression(memberInfo);
break;
case InjectionMember<TMemberInfo, TData> injectionMember:
var (info, value) = injectionMember.FromType(type);
yield return BuildMemberExpression(info, value);
break;
default:
throw new InvalidOperationException($"Unknown MemberInfo<{typeof(TMemberInfo)}> type");
}
}
}
protected virtual Expression BuildMemberExpression(TMemberInfo info)
{
var member = CreateMemberExpression(info);
foreach (var pair in ExpressionFactories)
{
#if NETSTANDARD1_0 || NETCOREAPP1_0
var attribute = info.GetCustomAttributes()
.Where(a => a.GetType()
.GetTypeInfo()
.IsAssignableFrom(pair.type.GetTypeInfo()))
.FirstOrDefault();
#else
var attribute = info.GetCustomAttribute(pair.type);
#endif
if (null == attribute || null == pair.factory)
continue;
return pair.factory(attribute, member, info, MemberType(info), null);
}
return Expression.Assign(member, GetExpression(info, null, null));
}
protected virtual Expression BuildMemberExpression(TMemberInfo info, TData resolver)
=> Expression.Assign(CreateMemberExpression(info), GetExpression(info, null, resolver));
protected virtual Expression GetExpression(TMemberInfo info, string name, object resolver) => throw new NotImplementedException();
protected virtual MemberExpression CreateMemberExpression(TMemberInfo info) => throw new NotImplementedException();
protected abstract Type MemberType(TMemberInfo info);
#endregion
#region Parameter Expression Factories
protected virtual Expression DependencyExpressionFactory(Attribute attribute, Expression member, object memberInfo, Type type, object resolver)
{
TMemberInfo info = (TMemberInfo)memberInfo;
return Expression.Assign(member, GetExpression(info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? DependencyAttribute.Instance));
}
protected virtual Expression OptionalDependencyExpressionFactory(Attribute attribute, Expression member, object memberInfo, Type type, object resolver)
{
TMemberInfo info = (TMemberInfo)memberInfo;
return Expression.TryCatch(
Expression.Assign(member, GetExpression(info, ((OptionalDependencyAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance)),
Expression.Catch(typeof(Exception),
Expression.Assign(member, Expression.Constant(null, type))));
}
#endregion
}
}

Просмотреть файл

@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
using Unity.Exceptions;
using Unity.Policy;
namespace Unity.Processors
{
public abstract class BuildMemberProcessor
{
#region Fields
protected static readonly MethodInfo StringFormat =
typeof(string).GetTypeInfo()
.DeclaredMethods
.First(m =>
{
var parameters = m.GetParameters();
return m.Name == nameof(string.Format) &&
m.GetParameters().Length == 2 &&
typeof(object) == parameters[1].ParameterType;
});
protected static readonly Expression InvalidRegistrationExpression = Expression.New(typeof(InvalidRegistrationException));
#endregion
#region Public Methods
public abstract IEnumerable<Expression> GetBuildSteps(Type type, IPolicySet registration);
public abstract ResolveDelegate<BuilderContext> GetResolver(Type type, IPolicySet registration, ResolveDelegate<BuilderContext> seed);
#endregion
}
public abstract partial class BuildMemberProcessor<TMemberInfo, TData> : BuildMemberProcessor
where TMemberInfo : MemberInfo
{
#region Fields
private readonly IPolicySet _policySet;
#endregion
#region Constructors
protected BuildMemberProcessor(IPolicySet policySet)
{
// Add Unity attribute factories
ExpressionFactories = new (Type type, MemberExpressionFactory factory)[]
{
(typeof(DependencyAttribute), DependencyExpressionFactory),
(typeof(OptionalDependencyAttribute), OptionalDependencyExpressionFactory),
};
// Add Unity attribute factories
ResolverFactories = new (Type type, MemberResolverFactory factory)[]
{
(typeof(DependencyAttribute), DependencyResolverFactory),
(typeof(OptionalDependencyAttribute), OptionalDependencyResolverFactory),
};
_policySet = policySet;
}
#endregion
#region Policy Retrieval
public TPolicyInterface GetPolicy<TPolicyInterface>(IPolicySet registration)
{
return (TPolicyInterface)(registration.Get(typeof(TPolicyInterface)) ??
_policySet.Get(typeof(TPolicyInterface)));
}
#endregion
}
}

Просмотреть файл

@ -1,127 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Unity.Builder;
using Unity.Injection;
using Unity.Policy;
using Unity.Storage;
namespace Unity.Processors
{
public delegate ResolveDelegate<BuilderContext> MemberResolverFactory(Attribute attribute, object info, object resolver, object defaultValue);
public abstract partial class BuildMemberProcessor<TMemberInfo, TData> where TMemberInfo : MemberInfo
{
#region Fields
protected (Type type, MemberResolverFactory factory)[] ResolverFactories;
#endregion
#region Public Methods
public void Add(Type type, MemberResolverFactory factory)
{
for (var i = 0; i < ResolverFactories.Length; i++)
{
if (ResolverFactories[i].type != type) continue;
ResolverFactories[i].factory = factory;
return;
}
var factories = new (Type type, MemberResolverFactory factory)[ResolverFactories.Length + 1];
Array.Copy(ResolverFactories, factories, ResolverFactories.Length);
factories[ResolverFactories.Length] = (type, factory);
ResolverFactories = factories;
}
#endregion
#region Overrides
public override ResolveDelegate<BuilderContext> GetResolver(Type type, IPolicySet registration, ResolveDelegate<BuilderContext> seed)
{
var selector = GetPolicy<ISelect<TMemberInfo>>(registration);
var members = selector.Select(type, registration);
var resolvers = ResolversFromSelected(type, members).ToArray();
return (ref BuilderContext c) =>
{
if (null == (c.Existing = seed(ref c))) return null;
foreach (var resolver in resolvers) resolver(ref c);
return c.Existing;
};
}
#endregion
#region Build Resolver
protected virtual IEnumerable<ResolveDelegate<BuilderContext>> ResolversFromSelected(Type type, IEnumerable<object> members)
{
foreach (var member in members)
{
switch (member)
{
case TMemberInfo memberInfo:
yield return BuildMemberResolver(memberInfo);
break;
case InjectionMember<TMemberInfo, TData> injectionMember:
var (info, value) = injectionMember.FromType(type);
yield return BuildMemberResolver(info, value);
break;
default:
throw new InvalidOperationException($"Unknown MemberInfo<{typeof(TMemberInfo)}> type");
}
}
}
protected virtual ResolveDelegate<BuilderContext> BuildMemberResolver(TMemberInfo info)
{
foreach (var pair in ResolverFactories)
{
#if NETSTANDARD1_0 || NETCOREAPP1_0
var attribute = info.GetCustomAttributes()
.Where(a => a.GetType()
.GetTypeInfo()
.IsAssignableFrom(pair.type.GetTypeInfo()))
.FirstOrDefault();
#else
var attribute = info.GetCustomAttribute(pair.type);
#endif
if (null == attribute || null == pair.factory)
continue;
return pair.factory(attribute, info, null, null);
}
return GetResolver(info, null);
}
protected virtual ResolveDelegate<BuilderContext> BuildMemberResolver(TMemberInfo info, TData resolver) => GetResolver(info, resolver);
protected virtual ResolveDelegate<BuilderContext> GetResolver(TMemberInfo info, object resolver) => throw new NotImplementedException();
#endregion
#region Parameter Resolver Factories
// Default expression factory for [Dependency] attribute
protected abstract ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null);
// Default expression factory for [OptionalDependency] attribute
protected abstract ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null);
#endregion
}
}

Просмотреть файл

@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Injection;
namespace Unity.Processors
{
public delegate Expression ExpressionAttributeFactory(Attribute attribute, Expression member, object info, Type type, object resolver);
public abstract partial class MemberProcessor<TMemberInfo, TData> where TMemberInfo : MemberInfo
{
#region Members Processing
protected virtual IEnumerable<Expression> ExpressionsFromSelection(Type type, IEnumerable<object> members)
{
foreach (var member in members)
{
switch (member)
{
case TMemberInfo memberInfo:
yield return ExpressionFromMemberInfo(memberInfo);
break;
case InjectionMember<TMemberInfo, TData> injectionMember:
var (info, value) = injectionMember.FromType(type);
yield return ExpressionFromMemberInfo(info, value);
break;
default:
throw new InvalidOperationException($"Unknown MemberInfo<{typeof(TMemberInfo)}> type");
}
}
}
protected virtual Expression ExpressionFromMemberInfo(TMemberInfo info)
{
var member = CreateMemberExpression(info);
foreach (var node in AttributeFactories)
{
var attribute = GetCustomAttribute(info, node.Type);
if (null == attribute || null == node.ExpressionFactory)
continue;
return node.ExpressionFactory(attribute, member, info, MemberType(info), null);
}
return Expression.Assign(member, GetResolverExpression(info, null, null));
}
protected virtual Expression ExpressionFromMemberInfo(TMemberInfo info, TData resolver)
{
return Expression.Assign(CreateMemberExpression(info), GetResolverExpression(info, null, resolver));
}
#endregion
#region Implementation
private Expression ExpressionFromAttribute(TMemberInfo info, object resolver)
{
var member = CreateMemberExpression(info);
foreach (var node in AttributeFactories)
{
var attribute = GetCustomAttribute(info, node.Type);
if (null == attribute || null == node.ExpressionFactory)
continue;
return node.ExpressionFactory(attribute, member, info, MemberType(info), null);
}
return null;
}
protected virtual Expression GetResolverExpression(TMemberInfo info, string name, object resolver) => throw new NotImplementedException();
protected virtual MemberExpression CreateMemberExpression(TMemberInfo info) => throw new NotImplementedException();
#endregion
#region Parameter Expression Factories
protected virtual Expression DependencyExpressionFactory(Attribute attribute, Expression member, object memberInfo, Type type, object resolver)
{
TMemberInfo info = (TMemberInfo)memberInfo;
return Expression.Assign(member, GetResolverExpression(info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? DependencyAttribute.Instance));
}
protected virtual Expression OptionalDependencyExpressionFactory(Attribute attribute, Expression member, object memberInfo, Type type, object resolver)
{
TMemberInfo info = (TMemberInfo)memberInfo;
return Expression.TryCatch(
Expression.Assign(member, GetResolverExpression(info, ((OptionalDependencyAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance)),
Expression.Catch(typeof(Exception),
Expression.Assign(member, Expression.Constant(null, type))));
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,259 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
using Unity.Exceptions;
using Unity.Injection;
using Unity.Policy;
using Unity.Registration;
namespace Unity.Processors
{
public abstract class MemberProcessor
{
#region Fields
protected static readonly MethodInfo StringFormat =
typeof(string).GetTypeInfo()
.DeclaredMethods
.First(m =>
{
var parameters = m.GetParameters();
return m.Name == nameof(string.Format) &&
m.GetParameters().Length == 2 &&
typeof(object) == parameters[1].ParameterType;
});
protected static readonly Expression InvalidRegistrationExpression = Expression.New(typeof(InvalidRegistrationException));
#endregion
#region Public Methods
/// <summary>
///
/// </summary>
/// <remarks>
/// Call hierarchy:
/// <see cref="GetExpressions"/>
/// + <see cref="SelectMembers"/>
/// + <see cref="ExpressionsFromSelected"/>
/// + <see cref="BuildMemberExpression"/>
/// + <see cref="GetResolverExpression"/>
/// </remarks>
/// <param name="type"></param>
/// <param name="registration"></param>
/// <returns></returns>
public abstract IEnumerable<Expression> GetExpressions(Type type, IPolicySet registration);
/// <summary>
///
/// </summary>
/// <remarks>
/// Call hierarchy:
/// <see cref="GetResolver"/>
/// + <see cref="SelectMembers"/>
/// + <see cref="ResolversFromSelected"/>
/// + <see cref="BuildMemberResolver"/>
/// + <see cref="GetResolverDelegate"/>
/// </remarks>
/// <param name="type"></param>
/// <param name="registration"></param>
/// <param name="seed"></param>
/// <returns></returns>
public abstract ResolveDelegate<BuilderContext> GetResolver(Type type, IPolicySet registration, ResolveDelegate<BuilderContext> seed);
#endregion
}
public abstract partial class MemberProcessor<TMemberInfo, TData> : MemberProcessor,
ISelect<TMemberInfo>
where TMemberInfo : MemberInfo
{
#region Fields
private readonly IPolicySet _policySet;
protected AttributeFactoryNode[] AttributeFactories;
#endregion
#region Constructors
protected MemberProcessor(IPolicySet policySet)
{
// Add Unity attribute factories
AttributeFactories = new[]
{
new AttributeFactoryNode(typeof(DependencyAttribute),
DependencyExpressionFactory,
DependencyResolverFactory),
new AttributeFactoryNode(typeof(OptionalDependencyAttribute),
OptionalDependencyExpressionFactory,
OptionalDependencyResolverFactory),
};
_policySet = policySet;
}
#endregion
#region Public Methods
public void Add(Type type, ExpressionAttributeFactory expressionFactory,
ResolutionAttributeFactory resolutionFactory)
{
for (var i = 0; i < AttributeFactories.Length; i++)
{
if (AttributeFactories[i].Type != type) continue;
AttributeFactories[i].ExpressionFactory = expressionFactory;
AttributeFactories[i].ResolutionFactory = resolutionFactory;
return;
}
var factories = new AttributeFactoryNode[AttributeFactories.Length + 1];
Array.Copy(AttributeFactories, factories, AttributeFactories.Length);
factories[AttributeFactories.Length] = new AttributeFactoryNode(type, expressionFactory, resolutionFactory);
AttributeFactories = factories;
}
#endregion
#region MemberProcessor
/// <inheritdoc />
public override IEnumerable<Expression> GetExpressions(Type type, IPolicySet registration)
{
var selector = GetPolicy<ISelect<TMemberInfo>>(registration);
var members = selector.Select(type, registration);
return ExpressionsFromSelection(type, members);
}
/// <inheritdoc />
public override ResolveDelegate<BuilderContext> GetResolver(Type type, IPolicySet registration, ResolveDelegate<BuilderContext> seed)
{
var selector = GetPolicy<ISelect<TMemberInfo>>(registration);
var members = selector.Select(type, registration);
var resolvers = ResolversFromSelection(type, members).ToArray();
return (ref BuilderContext c) =>
{
if (null == (c.Existing = seed(ref c))) return null;
foreach (var resolver in resolvers) resolver(ref c);
return c.Existing;
};
}
#endregion
#region ISelect
public virtual IEnumerable<object> Select(Type type, IPolicySet registration)
{
HashSet<object> memberSet = new HashSet<object>();
// Select Injected Members
if (null != ((InternalRegistration)registration).InjectionMembers)
{
foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers)
{
if (injectionMember is InjectionMember<TMemberInfo, TData> && memberSet.Add(injectionMember))
yield return injectionMember;
}
}
// Select Attributed members
IEnumerable<TMemberInfo> members = DeclaredMembers(type);
if (null == members) yield break;
foreach (var member in members)
{
for (var i = 0; i < AttributeFactories.Length; i++)
{
if (!member.IsDefined(AttributeFactories[i].Type) ||
!memberSet.Add(member)) continue;
yield return member;
break;
}
}
}
#endregion
#region Implementation
protected abstract Type MemberType(TMemberInfo info);
protected abstract IEnumerable<TMemberInfo> DeclaredMembers(Type type);
protected virtual object PreProcessResolver(TMemberInfo info, object resolver)
{
switch (resolver)
{
case IResolve policy:
return (ResolveDelegate<BuilderContext>)policy.Resolve;
case IResolverFactory factory:
return factory.GetResolver<BuilderContext>(MemberType(info));
case Type type:
return typeof(Type) == MemberType(info)
? type : (object)info;
}
return resolver;
}
protected Attribute GetCustomAttribute(TMemberInfo info, Type type)
{
#if NETSTANDARD1_0 || NETCOREAPP1_0
return info.GetCustomAttributes()
.Where(a => a.GetType()
.GetTypeInfo()
.IsAssignableFrom(type.GetTypeInfo()))
.FirstOrDefault();
#else
return info.GetCustomAttribute(type);
#endif
}
public TPolicyInterface GetPolicy<TPolicyInterface>(IPolicySet registration)
{
return (TPolicyInterface)(registration.Get(typeof(TPolicyInterface)) ??
_policySet.Get(typeof(TPolicyInterface)));
}
#endregion
#region Nested Types
public struct AttributeFactoryNode
{
public readonly Type Type;
public ExpressionAttributeFactory ExpressionFactory;
public ResolutionAttributeFactory ResolutionFactory;
public AttributeFactoryNode(Type type, ExpressionAttributeFactory expressionFactory, ResolutionAttributeFactory resolutionFactory)
{
Type = type;
ExpressionFactory = expressionFactory;
ResolutionFactory = resolutionFactory;
}
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Unity.Builder;
using Unity.Injection;
using Unity.Policy;
namespace Unity.Processors
{
public delegate ResolveDelegate<BuilderContext> ResolutionAttributeFactory(Attribute attribute, object info, object resolver, object defaultValue);
public abstract partial class MemberProcessor<TMemberInfo, TData> where TMemberInfo : MemberInfo
{
#region Member Processing
protected virtual IEnumerable<ResolveDelegate<BuilderContext>> ResolversFromSelection(Type type, IEnumerable<object> members)
{
foreach (var member in members)
{
switch (member)
{
case TMemberInfo memberInfo:
yield return ResolverFromMemberInfo(memberInfo);
break;
case InjectionMember<TMemberInfo, TData> injectionMember:
var (info, value) = injectionMember.FromType(type);
yield return ResolverFromMemberInfo(info, value);
break;
default:
throw new InvalidOperationException($"Unknown MemberInfo<{typeof(TMemberInfo)}> type");
}
}
}
protected virtual ResolveDelegate<BuilderContext> ResolverFromMemberInfo(TMemberInfo info)
{
return GetAttributeResolver(info, DependencyAttribute.Instance) ??
GetResolverDelegate(info, DependencyAttribute.Instance);
}
TData GetParameterResolver(TMemberInfo info, object data)
{
throw new NotImplementedException();
}
protected virtual ResolveDelegate<BuilderContext> ResolverFromMemberInfo(TMemberInfo info, TData resolver)
{
return GetResolverDelegate(info, resolver);
}
#endregion
#region Implementation
protected virtual ResolveDelegate<BuilderContext> GetDataResolver(TMemberInfo info, object resolver)
{
switch (resolver)
{
case DependencyAttribute dependencyAttribute:
return (ref BuilderContext context) => context.Resolve(MemberType(info), dependencyAttribute.Name);
case OptionalDependencyAttribute optionalAttribute:
return (ref BuilderContext context) =>
{
try { return context.Resolve(MemberType(info), optionalAttribute.Name); }
catch { return null; }
};
case IResolve policy:
return policy.Resolve;
case IResolverFactory<TMemberInfo> memberFactory:
return memberFactory.GetResolver<BuilderContext>(info);
case IResolverFactory typeFactory:
return typeFactory.GetResolver<BuilderContext>(MemberType(info));
case Type type:
return (ref BuilderContext context) => typeof(Type) == MemberType(info)
? type : context.Resolve(type, null);
}
return (ref BuilderContext context) => resolver;
}
private ResolveDelegate<BuilderContext> GetAttributeResolver(TMemberInfo info, object resolver)
{
foreach (var node in AttributeFactories)
{
var attribute = GetCustomAttribute(info, node.Type);
if (null == attribute || null == node.ResolutionFactory)
continue;
return node.ResolutionFactory(attribute, info, resolver, null);
}
return null;
}
protected virtual ResolveDelegate<BuilderContext> GetResolverDelegate(TMemberInfo info, object resolver)
{
switch(resolver)
{
case DependencyAttribute dependencyAttribute
when ReferenceEquals(dependencyAttribute, DependencyAttribute.Instance):
break;
case OptionalDependencyAttribute optionalAttribute
when ReferenceEquals(optionalAttribute, OptionalDependencyAttribute.Instance):
break;
}
throw new NotImplementedException();
}
#endregion
#region Parameter Resolver Factories
// Default expression factory for [Dependency] attribute
protected abstract ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null);
// Default expression factory for [OptionalDependency] attribute
protected abstract ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null);
#endregion
}
}

Просмотреть файл

@ -1,322 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
using Unity.Injection;
using Unity.Policy;
using Unity.Storage;
namespace Unity.Processors
{
public abstract class MethodBaseInfoProcessor<TMemberInfo> : BuildMemberProcessor<TMemberInfo, object[]>
where TMemberInfo : MethodBase
{
#region Fields
private readonly MethodInfo ResolveParameter =
typeof(BuilderContext).GetTypeInfo()
.GetDeclaredMethods(nameof(BuilderContext.Resolve))
.First(m =>
{
var parameters = m.GetParameters();
return 2 <= parameters.Length &&
typeof(ParameterInfo) == parameters[0].ParameterType;
});
#endregion
#region Constructors
protected MethodBaseInfoProcessor(IPolicySet policySet, Type attribute)
: base(policySet)
{
Add(attribute, (MemberResolverFactory)null);
Add(attribute, (MemberExpressionFactory)null);
}
#endregion
#region Overrides
protected override Type MemberType(TMemberInfo info) => info.DeclaringType;
protected override IEnumerable<object> SelectMembers(Type type, IEnumerable<TMemberInfo> members, InjectionMember[] injectors)
{
// Select Injected Members
if (null != injectors)
{
foreach (var injectionMember in injectors)
{
if (injectionMember is InjectionMember<TMemberInfo, object[]>)
yield return injectionMember;
}
}
if (null == members) yield break;
// Select Attributed members
foreach (var member in members)
{
if (ResolverFactories.Any(pair => member.IsDefined(pair.type)))
{
yield return member;
}
}
}
#endregion
#region Parameter Resolution Factories
protected virtual IEnumerable<ResolveDelegate<BuilderContext>> CreateParameterResolvers(ParameterInfo[] parameters, object[] injectors = null)
{
object[] resolvers = null != injectors && 0 == injectors.Length ? null : injectors;
for (var i = 0; i < parameters.Length; i++)
{
var parameter = parameters[i];
var resolver = null == resolvers ? parameter : PreProcessResolver(parameter, resolvers[i]);
// Check if has default value
var defaultValue = parameter.HasDefaultValue
? parameter.DefaultValue
: null;
// Check for registered attributes first
var expression = FromAttribute(parameter, defaultValue, resolver);
if (null == expression)
{
// Check if has default value
if (!parameter.HasDefaultValue)
{
// Plain vanilla case
expression = (ref BuilderContext context) => context.Resolve(parameter, null, resolver);
}
else
{
expression = (ref BuilderContext context) =>
{
try
{
return context.Resolve(parameter, null, resolver);
}
catch
{
return defaultValue;
}
};
}
}
yield return expression;
}
ResolveDelegate<BuilderContext> FromAttribute(ParameterInfo param, object defaultValue, object data)
{
foreach (var pair in ResolverFactories)
{
if (null == pair.factory) continue;
var attribute = param.GetCustomAttribute(pair.type);
if (null == attribute) continue;
// If found match, use provided factory to create expression
return pair.factory(attribute, param, data, defaultValue);
}
return null;
}
}
protected override ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
var parameter = (ParameterInfo)info;
if (!parameter.HasDefaultValue)
return (ref BuilderContext context) => context.Resolve((ParameterInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver);
else
{
return (ref BuilderContext context) =>
{
try
{
return context.Resolve((ParameterInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver);
}
catch
{
return defaultValue;
}
};
}
}
protected override ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
var parameter = (ParameterInfo)info;
return (ref BuilderContext context) =>
{
try
{
return context.Resolve((ParameterInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance);
}
catch
{
return defaultValue;
}
};
}
#endregion
#region Parameter Expression Factories
protected virtual IEnumerable<Expression> CreateParameterExpressions(ParameterInfo[] parameters, object[] injectors = null)
{
object[] resolvers = null != injectors && 0 == injectors.Length ? null : injectors;
for (var i = 0; i < parameters.Length; i++)
{
var parameter = parameters[i];
var resolver = null == resolvers ? parameter : PreProcessResolver(parameter, resolvers[i]);
// Check if has default value
var defaultValueExpr = parameter.HasDefaultValue
? Expression.Constant(parameter.DefaultValue, parameter.ParameterType)
: null;
// Check for registered attributes first
var expression = FromAttribute(parameter, defaultValueExpr, resolver);
if (null == expression)
{
// Check if has default value
if (!parameter.HasDefaultValue)
{
// Plain vanilla case
expression = ResolveExpression(parameter, null, resolver);
}
else
{
var variable = Expression.Variable(parameter.ParameterType);
var resolve = ResolveExpression(parameter, null, resolver);
expression = Expression.Block(new[] { variable }, new Expression[]
{
Expression.TryCatch(
Expression.Assign(variable, resolve),
Expression.Catch(typeof(Exception),
Expression.Assign(variable, defaultValueExpr))),
variable
});
}
}
yield return expression;
}
Expression FromAttribute(ParameterInfo param, Expression member, object data)
{
foreach (var pair in ExpressionFactories)
{
if (null == pair.factory) continue;
var attribute = param.GetCustomAttribute(pair.type);
if (null == attribute) continue;
// If found match, use provided factory to create expression
return pair.factory(attribute, member, param, param.ParameterType, data);
}
return null;
}
}
protected override Expression DependencyExpressionFactory(Attribute attribute, Expression member, object info, Type type, object resolver)
{
var parameter = (ParameterInfo)info;
if (null == member)
{
// Plain vanilla case
return ResolveExpression(parameter, ((DependencyResolutionAttribute)attribute).Name, resolver);
}
else
{
// Has default value
var variable = Expression.Variable(parameter.ParameterType);
return Expression.Block(new[] { variable }, new Expression[]
{
Expression.TryCatch(
Expression.Assign(
variable,
ResolveExpression(parameter, ((DependencyResolutionAttribute)attribute).Name, resolver)),
Expression.Catch(typeof(Exception),
Expression.Assign(variable, member))),
variable
});
}
}
protected override Expression OptionalDependencyExpressionFactory(Attribute attribute, Expression member, object info, Type type, object resolver)
{
var parameter = (ParameterInfo)info;
var variable = Expression.Variable(parameter.ParameterType);
return Expression.Block(new[] { variable }, new Expression[]
{
Expression.TryCatch(
Expression.Assign(
variable,
ResolveExpression(parameter, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance)),
Expression.Catch(typeof(Exception),
Expression.Assign(variable, member ?? Expression.Constant(null, parameter.ParameterType)))),
variable
});
}
#endregion
#region Expression Implementation
private Expression ResolveExpression(ParameterInfo parameter, string name, object resolver = null)
{
return Expression.Convert(
Expression.Call(BuilderContextExpression.Context, ResolveParameter,
Expression.Constant(parameter, typeof(ParameterInfo)),
Expression.Constant(name, typeof(string)),
Expression.Constant(resolver, typeof(object))),
parameter.ParameterType);
}
#endregion
#region Implementation
private object PreProcessResolver(ParameterInfo parameter, object resolver)
{
switch (resolver)
{
case IResolve policy:
return (ResolveDelegate<BuilderContext>)policy.Resolve;
case IResolverFactory<ParameterInfo> factory:
return factory.GetResolver<BuilderContext>(parameter);
case Type type:
return typeof(Type) == parameter.ParameterType
? type : (object)parameter;
}
return resolver;
}
#endregion
}
}

Просмотреть файл

@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Unity.Injection;
using Unity.Policy;
using Unity.Registration;
using Unity.Storage;
namespace Unity.Processors
{
public abstract partial class BuildMemberProcessor<TMemberInfo, TData> : ISelect<TMemberInfo>
{
#region ISelect
public IEnumerable<object> Select(Type type, IPolicySet registration)
{
return SelectMembers(type, DeclaredMembers(type),
((InternalRegistration) registration).InjectionMembers)
.Distinct();
}
#endregion
#region Implementation
protected virtual IEnumerable<object> SelectMembers(Type type, IEnumerable<TMemberInfo> members, InjectionMember[] injectors)
{
// Select Injected Members
if (null != injectors)
{
foreach (var injectionMember in injectors)
{
if (injectionMember is InjectionMember<TMemberInfo, TData>)
yield return injectionMember;
}
}
if (null == members) yield break;
// Select Attributed members
foreach (var member in members)
{
foreach (var pair in ExpressionFactories)
{
if (!member.IsDefined(pair.type)) continue;
yield return member;
break;
}
}
}
protected virtual IEnumerable<TMemberInfo> DeclaredMembers(Type type) => new TMemberInfo[0];
#endregion
}
}

Просмотреть файл

@ -75,7 +75,7 @@ namespace Unity.Processors
#region Expression Overrides
public override IEnumerable<Expression> GetBuildSteps(Type type, IPolicySet registration)
public override IEnumerable<Expression> GetExpressions(Type type, IPolicySet registration)
{
// Validate if Type could be created
var exceptionExpr = ValidateConstructedTypeExpression(type);
@ -132,7 +132,7 @@ namespace Unity.Processors
// Create 'new' expression
var ifThenExpr = Expression.IfThen(
Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing),
BuildMemberExpression(info, resolvers));
ExpressionFromMemberInfo(info, resolvers));
// Check if PerResolveLifetimeManager is required
return lifetimeManager is PerResolveLifetimeManager
@ -140,7 +140,7 @@ namespace Unity.Processors
: new Expression[] { ifThenExpr };
}
protected override Expression BuildMemberExpression(ConstructorInfo info, object[] resolvers)
protected override Expression ExpressionFromMemberInfo(ConstructorInfo info, object[] resolvers)
{
// Check if had ByRef parameters
var parameters = info.GetParameters();

Просмотреть файл

@ -53,7 +53,7 @@ namespace Unity.Processors
#region Overrides
public override IEnumerable<Expression> GetBuildSteps(Type type, IPolicySet registration)
public override IEnumerable<Expression> GetExpressions(Type type, IPolicySet registration)
{
// Select ConstructorInfo
var selector = GetPolicy<ISelect<ConstructorInfo>>(registration);

Просмотреть файл

@ -5,10 +5,11 @@ using System.Linq;
using System.Reflection;
using Unity.Injection;
using Unity.Policy;
using Unity.Registration;
namespace Unity.Processors
{
public partial class ConstructorProcessor : MethodBaseInfoProcessor<ConstructorInfo>
public partial class ConstructorProcessor : MethodBaseProcessor<ConstructorInfo>
{
#region Fields
@ -39,6 +40,41 @@ namespace Unity.Processors
#region Overrides
public override IEnumerable<object> Select(Type type, IPolicySet registration)
{
// Select Injected Members
if (null != ((InternalRegistration)registration).InjectionMembers)
{
foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers)
{
if (injectionMember is InjectionMember<ConstructorInfo, object[]>)
{
return new[] { injectionMember };
}
}
}
// Enumerate to array
var constructors = DeclaredMembers(type).ToArray();
if (1 >= constructors.Length)
return constructors;
// Select Attributed constructors
foreach (var constructor in constructors)
{
for (var i = 0; i < AttributeFactories.Length; i++)
{
if (!constructor.IsDefined(AttributeFactories[i].Type))
continue;
return new[] { constructor };
}
}
// Select default
return new[] { SelectMethod(type, constructors) };
}
protected override IEnumerable<ConstructorInfo> DeclaredMembers(Type type)
{
#if NETSTANDARD1_0
@ -50,51 +86,6 @@ namespace Unity.Processors
#endif
}
protected override IEnumerable<object> SelectMembers(Type type, IEnumerable<ConstructorInfo> members, InjectionMember[] injectors)
{
// Select Injected Members
if (null != injectors)
{
foreach (var injectionMember in injectors)
{
if (injectionMember is InjectionMember<ConstructorInfo, object[]>)
{
yield return injectionMember;
yield break;
}
}
}
if (null == members) yield break;
// Enumerate to array
var constructors = members.ToArray();
switch (constructors.Length)
{
case 0:
yield break;
case 1:
yield return constructors[0];
yield break;
}
// Select Attributed members
foreach (var constructor in constructors)
{
foreach (var pair in ResolverFactories)
{
if (!constructor.IsDefined(pair.type)) continue;
yield return constructor;
yield break;
}
}
// Select default
yield return SelectMethod(type, constructors);
}
#endregion

Просмотреть файл

@ -0,0 +1,28 @@
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
namespace Unity.Processors
{
public partial class FieldsProcessor
{
#region Overrides
protected override Expression GetResolverExpression(FieldInfo field, string name, object resolver)
{
return Expression.Convert(
Expression.Call(BuilderContextExpression.Context, ResolveField,
Expression.Constant(field, typeof(FieldInfo)),
Expression.Constant(name, typeof(string)),
Expression.Constant(PreProcessResolver(field, resolver), typeof(object))),
field.FieldType);
}
protected override MemberExpression CreateMemberExpression(FieldInfo info)
=> Expression.Field(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info);
#endregion
}
}

Просмотреть файл

@ -0,0 +1,59 @@
using System;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
namespace Unity.Processors
{
public partial class FieldsProcessor
{
#region Overrides
protected override ResolveDelegate<BuilderContext> GetResolverDelegate(FieldInfo info, object resolver)
{
var value = PreProcessResolver(info, resolver);
return (ref BuilderContext context) =>
{
info.SetValue(context.Existing, context.Resolve(info, context.Name, value));
return context.Existing;
};
}
#endregion
#region Parameter Resolver Factories
protected override ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
return (ref BuilderContext context) =>
{
((FieldInfo)info).SetValue(context.Existing,
context.Resolve((FieldInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? DependencyAttribute.Instance));
return context.Existing;
};
}
protected override ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
return (ref BuilderContext context) =>
{
try
{
((FieldInfo)info).SetValue(context.Existing,
context.Resolve((FieldInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance));
return context.Existing;
}
catch
{
((FieldInfo)info).SetValue(context.Existing, defaultValue);
return context.Existing;
}
};
}
#endregion
}
}

Просмотреть файл

@ -1,15 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
using Unity.Storage;
namespace Unity.Processors
{
public class FieldsProcessor : BuildMemberProcessor<FieldInfo, object>
public partial class FieldsProcessor : MemberProcessor<FieldInfo, object>
{
#region Fields
@ -32,7 +30,7 @@ namespace Unity.Processors
: base(policySet)
{
}
#endregion
@ -50,67 +48,11 @@ namespace Unity.Processors
protected override Type MemberType(FieldInfo info) => info.FieldType;
protected override ResolveDelegate<BuilderContext> GetResolver(FieldInfo info, object resolver)
{
var value = PreProcessResolver(info, resolver);
return (ref BuilderContext context) =>
{
info.SetValue(context.Existing, context.Resolve(info, context.Name, value));
return context.Existing;
};
}
protected override Expression GetExpression(FieldInfo field, string name, object resolver)
{
return Expression.Convert(
Expression.Call(BuilderContextExpression.Context, ResolveField,
Expression.Constant(field, typeof(FieldInfo)),
Expression.Constant(name, typeof(string)),
Expression.Constant(PreProcessResolver(field, resolver), typeof(object))),
field.FieldType);
}
protected override MemberExpression CreateMemberExpression(FieldInfo info)
=> Expression.Field(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info);
#endregion
#region Parameter Resolver Factories
protected override ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
return (ref BuilderContext context) =>
{
((FieldInfo)info).SetValue(context.Existing,
context.Resolve((FieldInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? DependencyAttribute.Instance));
return context.Existing;
};
}
protected override ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
return (ref BuilderContext context) =>
{
try
{
((FieldInfo)info).SetValue(context.Existing,
context.Resolve((FieldInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance));
return context.Existing;
}
catch
{
((FieldInfo)info).SetValue(context.Existing, defaultValue);
return context.Existing;
}
};
}
#endregion
#region Implementation
#if NETSTANDARD1_0
public static IEnumerable<FieldInfo> GetFieldsHierarchical(Type type)
{
@ -128,25 +70,7 @@ namespace Unity.Processors
.DeclaredFields
.Concat(GetFieldsHierarchical(type.GetTypeInfo().BaseType));
}
private object PreProcessResolver(FieldInfo field, object resolver)
{
switch (resolver)
{
case IResolve policy:
return (ResolveDelegate<BuilderContext>)policy.Resolve;
case IResolverFactory factory:
return factory.GetResolver<BuilderContext>(field.FieldType);
case Type type:
return typeof(Type) == field.FieldType
? type : (object)field;
}
return resolver;
}
#endif
#endregion
}
}

Просмотреть файл

@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
namespace Unity.Processors
{
public abstract partial class MethodBaseProcessor<TMemberInfo>
{
#region Parameter Factory
protected virtual IEnumerable<Expression> CreateParameterExpressions(ParameterInfo[] parameters, object[] injectors = null)
{
object[] resolvers = null != injectors && 0 == injectors.Length ? null : injectors;
for (var i = 0; i < parameters.Length; i++)
{
var parameter = parameters[i];
var resolver = null == resolvers ? parameter : PreProcessResolver(parameter, resolvers[i]);
// Check if has default value
var defaultValueExpr = parameter.HasDefaultValue
? Expression.Constant(parameter.DefaultValue, parameter.ParameterType)
: null;
// Check for registered attributes first
var expression = FromAttribute(parameter, defaultValueExpr, resolver);
if (null == expression)
{
// Check if has default value
if (!parameter.HasDefaultValue)
{
// Plain vanilla case
expression = CallResolveExpression(parameter, null, resolver);
}
else
{
var variable = Expression.Variable(parameter.ParameterType);
var resolve = CallResolveExpression(parameter, null, resolver);
expression = Expression.Block(new[] { variable }, new Expression[]
{
Expression.TryCatch(
Expression.Assign(variable, resolve),
Expression.Catch(typeof(Exception),
Expression.Assign(variable, defaultValueExpr))),
variable
});
}
}
yield return expression;
}
Expression FromAttribute(ParameterInfo param, Expression member, object data)
{
foreach (var node in AttributeFactories)
{
if (null == node.ExpressionFactory) continue;
var attribute = param.GetCustomAttribute(node.Type);
if (null == attribute) continue;
// If found match, use provided factory to create expression
return node.ExpressionFactory(attribute, member, param, param.ParameterType, data);
}
return null;
}
}
#endregion
#region Attribute Factory
protected override Expression DependencyExpressionFactory(Attribute attribute, Expression member, object info, Type type, object resolver)
{
var parameter = (ParameterInfo)info;
if (null == member)
{
// Plain vanilla case
return CallResolveExpression(parameter, ((DependencyResolutionAttribute)attribute).Name, resolver);
}
else
{
// Has default value
var variable = Expression.Variable(parameter.ParameterType);
return Expression.Block(new[] { variable }, new Expression[]
{
Expression.TryCatch(
Expression.Assign(
variable,
CallResolveExpression(parameter, ((DependencyResolutionAttribute)attribute).Name, resolver)),
Expression.Catch(typeof(Exception),
Expression.Assign(variable, member))),
variable
});
}
}
protected override Expression OptionalDependencyExpressionFactory(Attribute attribute, Expression member, object info, Type type, object resolver)
{
var parameter = (ParameterInfo)info;
var variable = Expression.Variable(parameter.ParameterType);
return Expression.Block(new[] { variable }, new Expression[]
{
Expression.TryCatch(
Expression.Assign(
variable,
CallResolveExpression(parameter, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance)),
Expression.Catch(typeof(Exception),
Expression.Assign(variable, member ?? Expression.Constant(null, parameter.ParameterType)))),
variable
});
}
#endregion
#region Implementation
private Expression CallResolveExpression(ParameterInfo parameter, string name, object resolver = null)
{
return Expression.Convert(
Expression.Call(BuilderContextExpression.Context, ResolveParameter,
Expression.Constant(parameter, typeof(ParameterInfo)),
Expression.Constant(name, typeof(string)),
Expression.Constant(resolver, typeof(object))),
parameter.ParameterType);
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,67 @@
using System;
using System.Linq;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
namespace Unity.Processors
{
public abstract partial class MethodBaseProcessor<TMemberInfo> : MemberProcessor<TMemberInfo, object[]>
where TMemberInfo : MethodBase
{
#region Fields
private readonly MethodInfo ResolveParameter =
typeof(BuilderContext).GetTypeInfo()
.GetDeclaredMethods(nameof(BuilderContext.Resolve))
.First(m =>
{
var parameters = m.GetParameters();
return 2 <= parameters.Length &&
typeof(ParameterInfo) == parameters[0].ParameterType;
});
#endregion
#region Constructors
protected MethodBaseProcessor(IPolicySet policySet, Type attribute)
: base(policySet)
{
Add(attribute, (ExpressionAttributeFactory)null, (ResolutionAttributeFactory)null);
}
#endregion
#region Overrides
protected override Type MemberType(TMemberInfo info) => info.DeclaringType;
#endregion
#region Implementation
private object PreProcessResolver(ParameterInfo parameter, object resolver)
{
switch (resolver)
{
case IResolve policy:
return (ResolveDelegate<BuilderContext>)policy.Resolve;
case IResolverFactory<ParameterInfo> factory:
return factory.GetResolver<BuilderContext>(parameter);
case Type type:
return typeof(Type) == parameter.ParameterType
? type : (object)parameter;
}
return resolver;
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
namespace Unity.Processors
{
public abstract partial class MethodBaseProcessor<TMemberInfo>
{
#region Parameter Factory
protected virtual IEnumerable<ResolveDelegate<BuilderContext>> CreateParameterResolvers(ParameterInfo[] parameters, object[] injectors = null)
{
object[] resolvers = null != injectors && 0 == injectors.Length ? null : injectors;
for (var i = 0; i < parameters.Length; i++)
{
var parameter = parameters[i];
var resolver = null == resolvers ? parameter : PreProcessResolver(parameter, resolvers[i]);
// Check if has default value
var defaultValue = parameter.HasDefaultValue
? parameter.DefaultValue
: null;
// Check for registered attributes first
var expression = FromAttribute(parameter, defaultValue, resolver);
if (null == expression)
{
// Check if has default value
if (!parameter.HasDefaultValue)
{
// Plain vanilla case
expression = (ref BuilderContext context) => context.Resolve(parameter, null, resolver);
}
else
{
expression = (ref BuilderContext context) =>
{
try
{
return context.Resolve(parameter, null, resolver);
}
catch
{
return defaultValue;
}
};
}
}
yield return expression;
}
ResolveDelegate<BuilderContext> FromAttribute(ParameterInfo param, object defaultValue, object data)
{
foreach (var node in AttributeFactories)
{
if (null == node.ResolutionFactory) continue;
var attribute = param.GetCustomAttribute(node.Type);
if (null == attribute) continue;
// If found match, use provided factory to create expression
return node.ResolutionFactory(attribute, param, data, defaultValue);
}
return null;
}
}
#endregion
#region Attribute Factory
protected override ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
var parameter = (ParameterInfo)info;
if (!parameter.HasDefaultValue)
return (ref BuilderContext context) => context.Resolve((ParameterInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver);
else
{
return (ref BuilderContext context) =>
{
try
{
return context.Resolve((ParameterInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver);
}
catch
{
return defaultValue;
}
};
}
}
protected override ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue = null)
{
var parameter = (ParameterInfo)info;
return (ref BuilderContext context) =>
{
try
{
return context.Resolve((ParameterInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance);
}
catch
{
return defaultValue;
}
};
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,29 @@
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
namespace Unity.Processors
{
public partial class MethodProcessor
{
#region Building Expression
protected override Expression ExpressionFromMemberInfo(MethodInfo info)
{
ValidateMethod(info);
return Expression.Call(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType),
info, CreateParameterExpressions(info.GetParameters()));
}
protected override Expression ExpressionFromMemberInfo(MethodInfo info, object[] resolvers)
{
ValidateMethod(info);
return Expression.Call(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType),
info, CreateParameterExpressions(info.GetParameters(), resolvers));
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Unity.Exceptions;
using Unity.Policy;
using Unity.Utility;
namespace Unity.Processors
{
public partial class MethodProcessor : MethodBaseProcessor<MethodInfo>
{
#region Constructors
public MethodProcessor(IPolicySet policySet)
: base(policySet, typeof(InjectionMethodAttribute))
{
}
#endregion
#region Selection
protected override IEnumerable<MethodInfo> DeclaredMembers(Type type)
{
#if NETSTANDARD1_0
return type.GetMethodsHierarchical()
.Where(c => c.IsStatic == false && c.IsPublic);
#else
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public);
#endif
}
#endregion
#region Implementation
private void ValidateMethod(MethodInfo info)
{
var parameters = info.GetParameters();
if (info.IsGenericMethodDefinition || parameters.Any(param => param.IsOut || param.ParameterType.IsByRef))
{
var format = info.IsGenericMethodDefinition
? "The method {1} on type {0} is marked for injection, but it is an open generic method. Injection cannot be performed."
: "The method {1} on type {0} has an out parameter. Injection cannot be performed.";
throw new IllegalInjectionMethodException(string.Format(CultureInfo.CurrentCulture,
format, info.DeclaringType.GetTypeInfo().Name, info.Name));
}
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,52 @@
using System.Linq;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
namespace Unity.Processors
{
public partial class MethodProcessor
{
#region Building Resolver
protected override ResolveDelegate<BuilderContext> ResolverFromMemberInfo(MethodInfo info)
{
ValidateMethod(info);
var parameterResolvers = CreateParameterResolvers(info.GetParameters()).ToArray();
return (ref BuilderContext c) =>
{
if (null == c.Existing) return c.Existing;
var parameters = new object[parameterResolvers.Length];
for (var i = 0; i < parameters.Length; i++)
parameters[i] = parameterResolvers[i](ref c);
info.Invoke(c.Existing, parameters);
return c.Existing;
};
}
protected override ResolveDelegate<BuilderContext> ResolverFromMemberInfo(MethodInfo info, object[] resolvers)
{
ValidateMethod(info);
var parameterResolvers = CreateParameterResolvers(info.GetParameters(), resolvers).ToArray();
return (ref BuilderContext c) =>
{
if (null == c.Existing) return c.Existing;
var parameters = new object[parameterResolvers.Length];
for (var i = 0; i < parameters.Length; i++)
parameters[i] = parameterResolvers[i](ref c);
info.Invoke(c.Existing, parameters);
return c.Existing;
};
}
#endregion
}
}

Просмотреть файл

@ -1,125 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
using Unity.Exceptions;
using Unity.Policy;
using Unity.Storage;
using Unity.Utility;
namespace Unity.Processors
{
public class MethodsProcessor : MethodBaseInfoProcessor<MethodInfo>
{
#region Constructors
public MethodsProcessor(IPolicySet policySet)
: base(policySet, typeof(InjectionMethodAttribute))
{
}
#endregion
#region Selection
protected override IEnumerable<MethodInfo> DeclaredMembers(Type type)
{
#if NETSTANDARD1_0
return type.GetMethodsHierarchical()
.Where(c => c.IsStatic == false && c.IsPublic);
#else
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public);
#endif
}
#endregion
#region Building Expression
protected override Expression BuildMemberExpression(MethodInfo info)
{
ValidateMethod(info);
return Expression.Call(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType),
info, CreateParameterExpressions(info.GetParameters()));
}
protected override Expression BuildMemberExpression(MethodInfo info, object[] resolvers)
{
ValidateMethod(info);
return Expression.Call(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType),
info, CreateParameterExpressions(info.GetParameters(), resolvers));
}
#endregion
#region Building Resolver
protected override ResolveDelegate<BuilderContext> BuildMemberResolver(MethodInfo info)
{
ValidateMethod(info);
var parameterResolvers = CreateParameterResolvers(info.GetParameters()).ToArray();
return (ref BuilderContext c) =>
{
if (null == c.Existing) return c.Existing;
var parameters = new object[parameterResolvers.Length];
for (var i = 0; i < parameters.Length; i++)
parameters[i] = parameterResolvers[i](ref c);
info.Invoke(c.Existing, parameters);
return c.Existing;
};
}
protected override ResolveDelegate<BuilderContext> BuildMemberResolver(MethodInfo info, object[] resolvers)
{
ValidateMethod(info);
var parameterResolvers = CreateParameterResolvers(info.GetParameters(), resolvers).ToArray();
return (ref BuilderContext c) =>
{
if (null == c.Existing) return c.Existing;
var parameters = new object[parameterResolvers.Length];
for (var i = 0; i < parameters.Length; i++)
parameters[i] = parameterResolvers[i](ref c);
info.Invoke(c.Existing, parameters);
return c.Existing;
};
}
#endregion
#region Implementation
private void ValidateMethod(MethodInfo info)
{
var parameters = info.GetParameters();
if (info.IsGenericMethodDefinition || parameters.Any(param => param.IsOut || param.ParameterType.IsByRef))
{
var format = info.IsGenericMethodDefinition
? "The method {1} on type {0} is marked for injection, but it is an open generic method. Injection cannot be performed."
: "The method {1} on type {0} has an out parameter. Injection cannot be performed.";
throw new IllegalInjectionMethodException(string.Format(CultureInfo.CurrentCulture,
format, info.DeclaringType.GetTypeInfo().Name, info.Name));
}
}
#endregion
}
}

Просмотреть файл

@ -1,167 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
using Unity.Storage;
using Unity.Utility;
namespace Unity.Processors
{
public class PropertiesProcessor : BuildMemberProcessor<PropertyInfo, object>
{
#region Fields
public static readonly MethodInfo ResolveProperty =
typeof(BuilderContext).GetTypeInfo()
.GetDeclaredMethods(nameof(BuilderContext.Resolve))
.First(m =>
{
var parameters = m.GetParameters();
return 2 <= parameters.Length &&
typeof(PropertyInfo) == parameters[0].ParameterType;
});
#endregion
#region Constructors
public PropertiesProcessor(IPolicySet policySet)
: base(policySet)
{
}
#endregion
#region Overrides
protected override IEnumerable<PropertyInfo> DeclaredMembers(Type type)
{
#if NETSTANDARD1_0
return GetPropertiesHierarchical(type)
.Where(p =>
{
if (!p.CanWrite) return false;
var propertyMethod = p.GetSetMethod(true) ??
p.GetGetMethod(true);
// Skip static properties and indexers.
if (propertyMethod.IsStatic || p.GetIndexParameters().Length != 0)
return false;
return true;
});
#else
return type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanWrite && p.GetIndexParameters().Length == 0);
#endif
}
protected override Type MemberType(PropertyInfo info)
=> info.PropertyType;
protected override ResolveDelegate<BuilderContext> GetResolver(PropertyInfo info, object resolver)
{
var value = PreProcessResolver(info, resolver);
return (ref BuilderContext context) =>
{
info.SetValue(context.Existing, context.Resolve(info, context.Name, value));
return context.Existing;
};
}
protected override Expression GetExpression(PropertyInfo property, string name, object resolver)
{
return Expression.Convert(
Expression.Call(BuilderContextExpression.Context, ResolveProperty,
Expression.Constant(property, typeof(PropertyInfo)),
Expression.Constant(name, typeof(string)),
Expression.Constant(PreProcessResolver(property, resolver), typeof(object))),
property.PropertyType);
}
protected override MemberExpression CreateMemberExpression(PropertyInfo info)
=> Expression.Property(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info);
#endregion
#region Parameter Resolver Factories
protected override ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue)
{
return (ref BuilderContext context) =>
{
((PropertyInfo)info).SetValue(context.Existing,
context.Resolve((PropertyInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? DependencyAttribute.Instance));
return context.Existing;
};
}
protected override ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue)
{
return (ref BuilderContext context) =>
{
try
{
((PropertyInfo)info).SetValue(context.Existing,
context.Resolve((PropertyInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance));
return context.Existing;
}
catch
{
((PropertyInfo)info).SetValue(context.Existing, defaultValue);
return context.Existing;
}
};
}
#endregion
#region Implementation
public static IEnumerable<PropertyInfo> GetPropertiesHierarchical(Type type)
{
if (type == null)
{
return Enumerable.Empty<PropertyInfo>();
}
if (type == typeof(object))
{
return type.GetTypeInfo().DeclaredProperties;
}
return type.GetTypeInfo()
.DeclaredProperties
.Concat(GetPropertiesHierarchical(type.GetTypeInfo().BaseType));
}
private object PreProcessResolver(PropertyInfo property, object resolver)
{
switch (resolver)
{
case IResolve policy:
return (ResolveDelegate<BuilderContext>)policy.Resolve;
case IResolverFactory factory:
return factory.GetResolver<BuilderContext>(property.PropertyType);
case Type type:
return typeof(Type) == property.PropertyType
? type : (object)property;
}
return resolver;
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,28 @@
using System.Linq.Expressions;
using System.Reflection;
using Unity.Builder;
namespace Unity.Processors
{
public partial class PropertyProcessor
{
#region Overrides
protected override Expression GetResolverExpression(PropertyInfo property, string name, object resolver)
{
return Expression.Convert(
Expression.Call(BuilderContextExpression.Context, ResolveProperty,
Expression.Constant(property, typeof(PropertyInfo)),
Expression.Constant(name, typeof(string)),
Expression.Constant(PreProcessResolver(property, resolver), typeof(object))),
property.PropertyType);
}
protected override MemberExpression CreateMemberExpression(PropertyInfo info)
=> Expression.Property(Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType), info);
#endregion
}
}

Просмотреть файл

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
namespace Unity.Processors
{
public partial class PropertyProcessor : MemberProcessor<PropertyInfo, object>
{
#region Fields
public static readonly MethodInfo ResolveProperty =
typeof(BuilderContext).GetTypeInfo()
.GetDeclaredMethods(nameof(BuilderContext.Resolve))
.First(m =>
{
var parameters = m.GetParameters();
return 2 <= parameters.Length &&
typeof(PropertyInfo) == parameters[0].ParameterType;
});
#endregion
#region Constructors
public PropertyProcessor(IPolicySet policySet)
: base(policySet)
{
}
#endregion
#region Overrides
protected override Type MemberType(PropertyInfo info) => info.PropertyType;
protected override IEnumerable<PropertyInfo> DeclaredMembers(Type type)
{
#if NETSTANDARD1_0
return GetPropertiesHierarchical(type)
.Where(p =>
{
if (!p.CanWrite) return false;
var propertyMethod = p.GetSetMethod(true) ??
p.GetGetMethod(true);
// Skip static properties and indexers.
if (propertyMethod.IsStatic || p.GetIndexParameters().Length != 0)
return false;
return true;
});
#else
return type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanWrite && p.GetIndexParameters().Length == 0);
#endif
}
#endregion
#region Implementation
#if NETSTANDARD1_0
public static IEnumerable<PropertyInfo> GetPropertiesHierarchical(Type type)
{
if (type == null)
{
return Enumerable.Empty<PropertyInfo>();
}
if (type == typeof(object))
{
return type.GetTypeInfo().DeclaredProperties;
}
return type.GetTypeInfo()
.DeclaredProperties
.Concat(GetPropertiesHierarchical(type.GetTypeInfo().BaseType));
}
#endif
#endregion
}
}

Просмотреть файл

@ -0,0 +1,60 @@
using System;
using System.Reflection;
using Unity.Builder;
using Unity.Policy;
namespace Unity.Processors
{
public partial class PropertyProcessor
{
#region Overrides
protected override ResolveDelegate<BuilderContext> GetResolverDelegate(PropertyInfo info, object resolver)
{
var value = PreProcessResolver(info, resolver);
return (ref BuilderContext context) =>
{
info.SetValue(context.Existing, context.Resolve(info, context.Name, value));
return context.Existing;
};
}
#endregion
#region Parameter Resolver Factories
protected override ResolveDelegate<BuilderContext> DependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue)
{
return (ref BuilderContext context) =>
{
((PropertyInfo)info).SetValue(context.Existing,
context.Resolve((PropertyInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? DependencyAttribute.Instance));
return context.Existing;
};
}
protected override ResolveDelegate<BuilderContext> OptionalDependencyResolverFactory(Attribute attribute, object info, object resolver, object defaultValue)
{
return (ref BuilderContext context) =>
{
try
{
((PropertyInfo)info).SetValue(context.Existing,
context.Resolve((PropertyInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver ?? OptionalDependencyAttribute.Instance));
return context.Existing;
}
catch
{
((PropertyInfo)info).SetValue(context.Existing, defaultValue);
return context.Existing;
}
};
}
#endregion
}
}

Просмотреть файл

@ -64,12 +64,12 @@ namespace Unity
// Processors
var fieldsProcessor = new FieldsProcessor(Defaults);
var methodsProcessor = new MethodsProcessor(Defaults);
var propertiesProcessor = new PropertiesProcessor(Defaults);
var methodsProcessor = new MethodProcessor(Defaults);
var propertiesProcessor = new PropertyProcessor(Defaults);
var constructorProcessor = new ConstructorDiagnostic(Defaults, IsTypeExplicitlyRegistered);
// Processors chain
_processors = new StagedStrategyChain<BuildMemberProcessor, BuilderStage>
_processors = new StagedStrategyChain<MemberProcessor, BuilderStage>
{
{ constructorProcessor, BuilderStage.Creation },
{ fieldsProcessor, BuilderStage.Fields },

Просмотреть файл

@ -43,11 +43,11 @@ namespace Unity
// Strategies
private StagedStrategyChain<BuilderStrategy, UnityBuildStage> _strategies;
private StagedStrategyChain<BuildMemberProcessor, BuilderStage> _processors;
private StagedStrategyChain<MemberProcessor, BuilderStage> _processors;
// Caches
private BuilderStrategy[] _strategiesChain;
private BuildMemberProcessor[] _processorsChain;
private MemberProcessor[] _processorsChain;
// Events
private event EventHandler<RegisterEventArgs> Registering;

Просмотреть файл

@ -39,12 +39,12 @@ namespace Unity
(ResolveDelegate<BuilderContext>)ExecuteDefaultPlan);
// Processors
var fieldsProcessor = new FieldsProcessor(Defaults);
var methodsProcessor = new MethodsProcessor(Defaults);
var propertiesProcessor = new PropertiesProcessor(Defaults);
var methodsProcessor = new MethodProcessor(Defaults);
var propertiesProcessor = new PropertyProcessor(Defaults);
var constructorProcessor = new ConstructorProcessor(Defaults, IsTypeExplicitlyRegistered);
// Processors chain
_processors = new StagedStrategyChain<BuildMemberProcessor, BuilderStage>
_processors = new StagedStrategyChain<MemberProcessor, BuilderStage>
{
{ constructorProcessor, BuilderStage.Creation },
{ fieldsProcessor, BuilderStage.Fields },

Просмотреть файл

@ -226,7 +226,7 @@ namespace Unity
var expressions = new List<Expression>();
foreach (var processor in chain)
{
foreach (var step in processor.GetBuildSteps(type, registration))
foreach (var step in processor.GetExpressions(type, registration))
expressions.Add(step);
}
@ -252,7 +252,7 @@ namespace Unity
foreach (var processor in _processorsChain)
{
foreach (var step in processor.GetBuildSteps(type, registration))
foreach (var step in processor.GetExpressions(type, registration))
expressions.Add(step);
}