public static GrainStorageOptions <TContext, TGrain, TGrainState> ConfigureIsPersisted <TContext, TGrain, TGrainState>(
     this GrainStorageOptions <TContext, TGrain, TGrainState> options,
     Func <TGrainState, bool> isPersistedFunc)
     where TContext : DbContext
     where TGrainState : class
 {
     options.IsPersistedFunc = isPersistedFunc;
     return(options);
 }
 /// <summary>
 /// Instructs the storage provider to precompile read query.
 /// This will lead to better performance for complex queries.
 /// Default is to precompile.
 /// </summary>
 /// <typeparam name="TContext"></typeparam>
 /// <typeparam name="TGrain"></typeparam>
 /// <typeparam name="TGrainState"></typeparam>
 /// <param name="options"></param>
 /// <param name="value"></param>
 /// <returns></returns>
 public static GrainStorageOptions <TContext, TGrain, TGrainState> PreCompileReadQuery <TContext, TGrain, TGrainState>(
     this GrainStorageOptions <TContext, TGrain, TGrainState> options,
     bool value = true)
     where TContext : DbContext
     where TGrainState : class
 {
     options.PreCompileReadQuery = value;
     return(options);
 }
 public static GrainStorageOptions <TContext, TGrain, TGrainState> UseQuery <TContext, TGrain, TGrainState>(
     this GrainStorageOptions <TContext, TGrain, TGrainState> options,
     Func <TContext, IQueryable <TGrainState> > queryFunc, Func <TContext, IQueryable <TGrainState> > noTrackingQueryFunc)
     where TContext : DbContext
     where TGrainState : class
 {
     options.DbSetAccessor           = queryFunc;
     options.DbSetNoTrackingAccessor = noTrackingQueryFunc;
     return(options);
 }
        /// <summary>
        /// Overrides the default implementation used to query grain state from database.
        /// </summary>
        /// <typeparam name="TContext"></typeparam>
        /// <typeparam name="TGrainState"></typeparam>
        /// <typeparam name="TGrain"></typeparam>
        /// <param name="options"></param>
        /// <param name="readStateAsyncFunc"></param>
        /// <returns></returns>
        public static GrainStorageOptions <TContext, TGrain, TGrainState> ConfigureReadState <TContext, TGrain, TGrainState>(
            this GrainStorageOptions <TContext, TGrain, TGrainState> options,
            Func <TContext, IAddressable, Task <TGrainState> > readStateAsyncFunc)
            where TContext : DbContext
            where TGrainState : class
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            options.ReadStateAsync = readStateAsyncFunc ?? throw new ArgumentNullException(nameof(readStateAsyncFunc));
            return(options);
        }
예제 #5
0
        public GrainStorage(string grainType, IServiceProvider serviceProvider)
        {
            if (grainType == null)
            {
                throw new ArgumentNullException(nameof(grainType));
            }

            _serviceProvider = serviceProvider
                               ?? throw new ArgumentNullException(nameof(serviceProvider));

            var loggerFactory = _serviceProvider.GetService <ILoggerFactory>();

            _logger = loggerFactory?.CreateLogger <GrainStorage <TContext, TGrain, TGrainState, TEntity> >()
                      ?? NullLogger <GrainStorage <TContext, TGrain, TGrainState, TEntity> > .Instance;

            _scopeFactory = serviceProvider.GetRequiredService <IServiceScopeFactory>();
            _options      = GetOrCreateDefaultOptions(grainType);
        }
        public static GrainStorageOptions <TContext, TGrain, TGrainState> CheckPersistenceOn <TContext, TGrain, TGrainState>(
            this GrainStorageOptions <TContext, TGrain, TGrainState> options,
            string propertyName)
            where TContext : DbContext
            where TGrainState : class
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException(nameof(propertyName));
            }

            options.PersistenceCheckPropertyName = propertyName;

            return(options);
        }
        public static GrainStorageOptions <TContext, TGrain, TGrainState> UseETag <TContext, TGrain, TGrainState>(
            this GrainStorageOptions <TContext, TGrain, TGrainState> options,
            string propertyName)
            where TContext : DbContext
            where TGrainState : class
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException(nameof(propertyName));
            }

            options.ETagPropertyName = propertyName;
            options.ShouldUseETag    = true;

            return(options);
        }
        public static GrainStorageOptions <TContext, TGrain, TGrainState> CheckPersistenceOn <TContext, TGrain, TGrainState, TProperty>(
            this GrainStorageOptions <TContext, TGrain, TGrainState> options,
            Expression <Func <TGrainState, TProperty> > expression)
            where TContext : DbContext
            where TGrainState : class
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            var memberExpression = expression.Body as MemberExpression
                                   ?? throw new ArgumentException(
                                             $"{nameof(expression)} must be a MemberExpression.");

            options.PersistenceCheckPropertyName = memberExpression.Member.Name;

            return(options);
        }
        public static GrainStorageOptions <TContext, TGrain, TGrainState> UseKey <TContext, TGrain, TGrainState>(
            this GrainStorageOptions <TContext, TGrain, TGrainState> options,
            Expression <Func <TGrainState, long> > expression)
            where TContext : DbContext
            where TGrainState : class
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            var memberExpression = expression.Body as MemberExpression
                                   ?? throw new GrainStorageConfigurationException(
                                             $"{nameof(expression)} must be a MemberExpression.");

            options.KeyPropertyName = memberExpression.Member.Name;

            return(options);
        }
        public void PostConfigure(string name, GrainStorageOptions <TContext, TGrain, TEntity> options)
        {
            if (!string.Equals(name, typeof(TGrain).FullName))
            {
                throw new Exception("Post configure on wrong grain type.");
            }

            if (options.IsPersistedFunc == null)
            {
                options.IsPersistedFunc =
                    DefaultConvention.CreateIsPersistedFunc <TEntity>(options);
            }

            // Configure ETag
            if (options.ShouldUseETag)
            {
                if (!string.IsNullOrWhiteSpace(options.ETagPropertyName))
                {
                    DefaultConvention.ConfigureETag(options.ETagPropertyName, options);
                }
            }

            if (options.ReadStateAsync == null)
            {
                if (options.DbSetAccessor == null)
                {
                    options.DbSetAccessor = Convention?.CreateDefaultDbSetAccessorFunc()
                                            ?? DefaultConvention.CreateDefaultDbSetAccessorFunc <TContext, TEntity>();
                }

                if (Convention != null)
                {
                    Convention.SetDefaultKeySelector(options);
                }
                else
                {
                    DefaultConvention.SetDefaultKeySelectors(options);
                }

                if (options.PreCompileReadQuery)
                {
                    options.ReadStateAsync
                        = Convention?.CreatePreCompiledDefaultReadStateFunc(options)
                          ?? DefaultConvention
                          .CreatePreCompiledDefaultReadStateFunc(options);
                }
                else
                {
                    options.ReadStateAsync
                        = Convention?.CreateDefaultReadStateFunc()
                          ?? DefaultConvention
                          .CreateDefaultReadStateFunc(options);
                }
            }
            if (options.ReadStateNoTrackingAsync == null)
            {
                if (options.DbSetNoTrackingAccessor == null)
                {
                    options.DbSetNoTrackingAccessor = Convention?.CreateDefaultDbSetNoTrackingAccessorFunc()
                                                      ?? DefaultConvention.CreateDefaultDbSetNoTrackingAccessorFunc <TContext, TEntity>();
                }

                if (Convention != null)
                {
                    Convention.SetDefaultKeySelector(options);
                }
                else
                {
                    DefaultConvention.SetDefaultKeySelectors(options);
                }

                if (options.PreCompileReadQuery)
                {
                    options.ReadStateNoTrackingAsync
                        = Convention?.CreatePreCompiledDefaultReadStateNoTrackingFunc(options)
                          ?? DefaultConvention
                          .CreatePreCompiledDefaultReadStateNoTrackingFunc(options);
                }
                else
                {
                    options.ReadStateNoTrackingAsync
                        = Convention?.CreateDefaultReadStateFunc()
                          ?? DefaultConvention
                          .CreateDefaultReadStateFunc(options);
                }
            }

            if (options.SetEntity == null)
            {
                options.SetEntity =
                    Convention?.GetSetterFunc()
                    ?? DefaultConvention.GetSetterFunc <TGrainState, TEntity>();
            }

            if (options.GetEntity == null)
            {
                options.GetEntity =
                    Convention?.GetGetterFunc()
                    ?? DefaultConvention.GetGetterFunc <TGrainState, TEntity>();
            }

            DefaultConvention.FindAndConfigureETag(options, options.ShouldUseETag);

            // todo: Validate options

            options.IsConfigured = true;
        }