/// <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>()));
 }
Esempio n. 2
0
        /// <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));
        }
Esempio n. 3
0
        /// <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()));
        }
Esempio n. 4
0
 /// <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));
        }