/// <summary> /// Returns an instance of a resource repository accessor for a Belongs To relationship. /// </summary> /// <typeparam name="TEntity">The type of entity to return.</typeparam> /// <param name="relationship">The relationship that defines the accessor to return.</param> /// <returns>The resource repository accessor instance.</returns> public Func <IDatabase, IRepositoryAccessor <TEntity> > GetOrCreateBelongsToAccessor <TEntity>(IBelongsToRelationship relationship) { return((Func <IDatabase, IRepositoryAccessor <TEntity> >)_cache.GetOrAdd(relationship, r => CreateBelongsToAccessor <TEntity>())); }
/// <summary> /// Create the belongs to getter expression. /// </summary> /// <typeparam name="TSource">The type of the source resource to enrich.</typeparam> /// <param name="relationship">The relationship to create the accessor for.</param> /// <param name="sourceParameter">The source parameter for the expression.</param> /// <returns>The expression that returns the getter for the relationship.</returns> static Expression <Func <TSource, int?> > CreateBelongsToAccessorExpression <TSource>(IBelongsToRelationship relationship, ParameterExpression sourceParameter) { if (relationship.BackingField.Accessor.ValueType == typeof(int?)) { return(Expression .Lambda <Func <TSource, int?> >( Expression.PropertyOrField( sourceParameter, relationship.BackingField.Name), sourceParameter)); } return(Expression .Lambda <Func <TSource, int?> >( Expression.Convert( Expression.PropertyOrField( sourceParameter, relationship.BackingField.Name), typeof(int?)), sourceParameter)); }
/// <summary> /// Get or create an instance of a belongs to resource accessor. /// </summary> /// <typeparam name="TSource">The type of the source resource to enrich.</typeparam> /// <typeparam name="TDestination">The type of the destination resource that is enriched on the source.</typeparam> /// <param name="relationship">The relationship to create the accessor for.</param> /// <returns>The belongs to resource accessor.</returns> IBelongsToResourceAccessor <TSource, TDestination> CreateBelongsToAccessor <TSource, TDestination>(IBelongsToRelationship relationship) { var sourceParameter = Expression.Parameter(typeof(TSource)); var destinationParameter = Expression.Parameter(typeof(TDestination)); return(new DelegatingBelongsToResourceAccessor <TSource, TDestination>( CreateBelongsToAccessorExpression <TSource>(relationship, sourceParameter).Compile(), Expression .Lambda <Action <TSource, TDestination> >( Expression.Assign( Expression.PropertyOrField( sourceParameter, relationship.Name), destinationParameter), sourceParameter, destinationParameter) .Compile())); }
/// <summary> /// Get or create an instance of a belongs to resource accessor. /// </summary> /// <typeparam name="TSource">The type of the source resource to enrich.</typeparam> /// <typeparam name="TDestination">The type of the destination resource that is enriched on the source.</typeparam> /// <param name="relationship">The relationship to create the accessor for.</param> /// <returns>The belongs to resource accessor.</returns> public IBelongsToResourceAccessor <TSource, TDestination> GetOrCreateBelongsToAccessor <TSource, TDestination>(IBelongsToRelationship relationship) { return((IBelongsToResourceAccessor <TSource, TDestination>)_cache.GetOrAdd(relationship, r => CreateBelongsToAccessor <TSource, TDestination>((IBelongsToRelationship)r))); }
/// <summary> /// Create a belongs to enricher for the given relationship. /// </summary> /// <param name="relationship">The relationship to create the enricher from.</param> /// <param name="database">The database to perform the enrichment within.</param> /// <returns>The enricher for the given resource and relationship.</returns> IResourceEnricher <TSource, TDestination> CreateBelongsToEnricher <TSource, TDestinationEntity, TDestination>(IBelongsToRelationship relationship, IDatabase database) where TDestinationEntity : IEntityWithId where TDestination : IEntityWithId { var foreignKeyAccessor = _resourceAccessorFactory.GetOrCreateBelongsToAccessor <TSource, TDestination>(relationship); var repositoryAccessorFactory = _repositoryAccessorFactory.GetOrCreateBelongsToAccessor <TDestinationEntity>(relationship); return(new DelegatingBelongsToResourceEnricher <TSource, TDestinationEntity, TDestination>( foreignKeyAccessor, repositoryAccessorFactory(database))); }
/// <summary> /// Create a belongs to enricher for the given relationship. /// </summary> /// <typeparam name="TSource">The resource type to create the enricher for.</typeparam> /// <typeparam name="TDestination">The resource type on the other end of the relationship that is being enriched from.</typeparam> /// <param name="relationship">The relationship to create the enricher from.</param> /// <param name="database">The database to perform the enrichment within.</param> /// <returns>The enricher for the given resource and relationship.</returns> IResourceEnricher <TSource, TDestination> CreateBelongsToEnricher <TSource, TDestination>(IBelongsToRelationship relationship, IDatabase database) { var parameters = new[] { Expression.Parameter(typeof(IBelongsToRelationship)), Expression.Parameter(typeof(IDatabase)) }; var methodCallExpression = Expression.Call( Expression.Constant(this), nameof(CreateBelongsToEnricher), new[] { typeof(TSource), relationship.RelatedTo.BaseType, relationship.RelatedTo }, // ReSharper disable once CoVariantArrayConversion parameters); var @delegate = Expression .Lambda <Func <IBelongsToRelationship, IDatabase, IResourceEnricher <TSource, TDestination> > >( methodCallExpression, parameters) .Compile(); return(@delegate(relationship, database)); }