public UserSpec(EntityTypeBuilder <User> entityBuilder) { EntitySpec <User> .SetEntitySpecs(entityBuilder); entityBuilder .HasIndex(o => o.Login) .IsUnique(); entityBuilder .Property(o => o.Login) .IsRequired() .HasMaxLength(250); entityBuilder .Property(o => o.FirstName) .HasMaxLength(250); entityBuilder .Property(o => o.LastName) .HasMaxLength(250); entityBuilder .Property(o => o.Email) .HasMaxLength(250); entityBuilder .Ignore(o => o.FullName); }
public PageSpec(EntityTypeBuilder <Page> entityBuilder) { EntitySpec <Page> .SetEntitySpecs(entityBuilder); entityBuilder .HasIndex(o => o.Title); entityBuilder .Property(o => o.Title) .IsRequired() .HasMaxLength(250); entityBuilder .HasIndex(o => o.Slug); entityBuilder .Property(o => o.Slug) .IsRequired() .HasMaxLength(100); entityBuilder .HasOne(o => o.Owner) .WithMany(o => o.Pages) .IsRequired(); }
/// <summary> /// Converts the <see cref="sourceValue" /> parameter to the <see cref="destinationType" /> parameter using <see cref="formatProvider" /// /> and <see cref="ignoreCase" /> /// </summary> /// <param name="sourceValue">the value to convert into an instance of <see cref="EntitySpec" />.</param> /// <returns> /// an instance of <see cref="EntitySpec" />, or <c>null</c> if there is no suitable conversion. /// </returns> public static object ConvertFrom(dynamic sourceValue) { if (null == sourceValue) { return(null); } try { EntitySpec.FromJsonString(typeof(string) == sourceValue.GetType() ? sourceValue : sourceValue.ToJsonString()); } catch { // Unable to use JSON pattern } try { return(new EntitySpec { CategoryList = sourceValue.CategoryList, VmReference = VmReferenceTypeConverter.ConvertFrom(sourceValue.VmReference), VmSpec = VmTypeConverter.ConvertFrom(sourceValue.VmSpec), }); } catch { } return(null); }
public BookSpec(EntityTypeBuilder <Book> entityBuilder) { EntitySpec <Book> .SetEntitySpecs(entityBuilder); entityBuilder .HasIndex(o => o.Title); entityBuilder .Property(o => o.Title) .IsRequired() .HasMaxLength(250); entityBuilder .HasIndex(o => o.Slug); entityBuilder .Property(o => o.Slug) .IsRequired() .HasMaxLength(100); entityBuilder .HasOne(o => o.Owner) .WithMany(o => o.Books) .IsRequired(); entityBuilder .Ignore(o => o.PageCount); }
/// <summary> /// Initializes a new instance of the <see cref="EntityArrayScanTarget"/> class. /// </summary> /// <param name="entityType"> /// The entity type. /// </param> /// <param name="entitySpec"> /// The entity spec. /// </param> /// <param name="array"> /// The array. /// </param> /// <param name="indexes"> /// The indexes. /// </param> internal EntityArrayScanTarget(Type entityType, EntitySpec entitySpec, Array array, int[] indexes) : base(entityType, entitySpec) { this.array = array; this.indexes = new int[indexes.Length]; Array.Copy(indexes, this.indexes, indexes.Length); this.setter = this.Set; }
/// <summary> /// Initializes a new instance of the <see cref="EntityCollectionScanTarget"/> class. /// </summary> /// <param name="entityType"> /// The entity type. /// </param> /// <param name="entitySpec"> /// The entity specification. /// </param> /// <param name="inspectedEnumerable"> /// The inspected enumerable. /// </param> /// <param name="collection"> /// The target collection. /// </param> /// <exception cref="PersistenceException"> /// If the <paramref name="inspectedEnumerable"/> does not have an add method. /// </exception> internal EntityCollectionScanTarget(Type entityType, EntitySpec entitySpec, InspectedEnumerable inspectedEnumerable, object collection) : base(entityType, entitySpec) { if (!inspectedEnumerable.HasAdd) { throw new PersistenceException( string.Format(CultureInfo.InvariantCulture, @"Enumerable {0} has no void Add({1}) method.", inspectedEnumerable.InspectedType, inspectedEnumerable.ElementType)); } this.setter = this.Add; this.add = inspectedEnumerable.Add; this.collection = collection; }
public void GetQuerySql(Entity query, StringBuilder sql, DBParameterList parms) { var builder = new EntitySpec <Entity>(query).Sql; if (!string.IsNullOrEmpty(builder.Sql)) { sql.Append(" and (" + this.searchBO.resolveTableName(builder.Sql) + ")"); } if (builder.Parameters.ParameterNames.Count() > 0) { parms.AddExpandoParams(builder.Parameters); } }
/// <summary> /// Initializes a new instance of the <see cref="EntityIndexerScanTarget"/> class. /// </summary> /// <param name="entityType"> /// The entity type. /// </param> /// <param name="entitySpec"> /// The entity spec. /// </param> /// <param name="inspectedEnumerable"> /// The inspected enumerable. /// </param> /// <param name="collection"> /// The collection. /// </param> /// <param name="pos"> /// The position in the indexed collection. /// </param> /// <exception cref="PersistenceException"> /// If the <paramref name="inspectedEnumerable"/> does not have an indexer. /// </exception> internal EntityIndexerScanTarget(Type entityType, EntitySpec entitySpec, InspectedEnumerable inspectedEnumerable, object collection, int pos) : base(entityType, entitySpec) { if (!inspectedEnumerable.HasIndexer) { throw new PersistenceException( string.Format(CultureInfo.InvariantCulture, @"Enumerable {0} has no index for type {1}.", inspectedEnumerable.InspectedType, inspectedEnumerable.ElementType)); } this.setter = this.Set; this.inspectedEnumerable = inspectedEnumerable; this.collection = collection; this.pos = pos; }
/// <summary> /// Adds an entity specification to the scan. /// </summary> /// <param name="entitySpec"> /// The entity specification to add. /// </param> public void Add(EntitySpec entitySpec) { var esr = entitySpec as EntityScanResult; if (esr == null) { throw new ArgumentException(@"EntitySpec of type EntityScanResult expected", nameof(entitySpec)); } lock (this.syncRoot) { this.entityScanResult = esr; } }
/// <summary> /// Adds an entity specification to the scan. /// </summary> /// <param name="entitySpec"> /// The entity specification to add. /// </param> public void Add(EntitySpec entitySpec) { var entityScanTarget = entitySpec as EntityScanTarget; if (entityScanTarget == null) { throw new ArgumentException(@"EntitySpec of type EntityScanTarget expected", nameof(entitySpec)); } EntityScanTarget entityScanTargetExisting; if (!this.GetOrAdd(entityScanTarget, out entityScanTargetExisting)) { entityScanTargetExisting.AddScanTargetRef(entityScanTarget); } }
/// <summary> /// The serializing entity callback. /// </summary> /// <param name="isRoot"> /// Indicating whether the entity is the root entity. /// </param> /// <param name="er"> /// The entity reference. /// </param> /// <param name="serializeType"> /// The serialize type. /// </param> /// <param name="e"> /// The entity. /// </param> /// <returns> /// The entity key. /// </returns> private Key SerializingEntity(bool isRoot, EntityReference er, Type serializeType, object e) { if (isRoot) { this.entityReference = er; switch (this.behaviors & Behaviors.CreateBehaviors) { case Behaviors.CreateAlways: this.key = er.GenerateKey(e); this.newEntity = true; break; case Behaviors.CreateLazy: this.key = er.GetKeyFromEntity(e, out this.newEntity); if (!this.newEntity) { var entitySpec = new EntitySpec(this.entityReference, new Key(this.key)); ////TODO needs to check if the entity has been modified (write,write again) if (!this.entitySpecsWritten.Contains(entitySpec)) { ////TODO needs to check if the entity has been modified (read, write) if (this.behaviors.BypassReadCache() || !this.entitySpecsFetched.Contains(entitySpec)) { this.key = er.GenerateKey(e); } } else { return(null); // cancel further serialization } } break; case Behaviors.CreateNew: this.key = er.GetKeyFromEntity(e, out this.newEntity); break; } return(this.key); } return(Persist(this.entityContext, serializeType, e, this.behaviors, this.entitiesWritten)); }
/// <summary> /// Stores an entity instance to the database. /// </summary> /// <param name="entity"> /// The entity to store. /// </param> /// <param name="behaviors"> /// The behaviors. /// </param> /// <typeparam name="T"> /// The entity type. /// </typeparam> public void Persist <T>(T entity, Behaviors behaviors) where T : class { if (behaviors.IsCreateNew() && !behaviors.DoNotCache() && !behaviors.BypassWriteCache()) { var entityReference = this.EntityReferenceForType(entity.GetType()); if (entityReference != null) { bool newEntity; var key = entityReference.GetKeyFromEntity(entity, out newEntity); if (!newEntity) { var entitySpec = new EntitySpec(entityReference, key); this.entitySpecsWritten.Remove(entitySpec); } } } EntityWriter.Persist(this, entity, behaviors); }
protected EntityView(Type type) { _type = type; IsValid = _components.TryAddComponent(type); _fields = _type.GetFields().Where(x => x.FieldType.IsPointer).ToArray(); _entityFields = new EntityField[_fields.Length]; if (IsValid) { FindIgnoreComponents(); _ignoreSpec = new EntitySpec(_ignoreComponents.ToArray()); } if (IsValid) { FindAnyComponents(); _anySpec = new EntitySpec(_anyComponents.ToArray()); } if (IsValid) { FindHasComponents(); } if (IsValid) { var components = FindPointerComponents(); foreach (var it in _hasComponents) { components.Add(it); } if (components != null) { _spec = new EntitySpec(components.ToArray()); } } }
private void entitySpecToolStripMenuItem_Click(object sender, EventArgs e) { if (this.OpenImage.ShowDialog() == DialogResult.OK) { string filePath = Path.GetDirectoryName(this.OpenImage.FileName); string filename = Path.GetFileNameWithoutExtension(this.OpenImage.FileName); this.folderMap.Add(filename, filePath); EntitySpec entitySpec = new EntitySpec( filename, new CharSetSpec(filename), new TextureSpec(filename), new BGMapSpriteSpec(), new EntityRomSpec()); entitySpec.Name = filename; entitySpec.Dock = DockStyle.Fill; TabPage tabPage = new TabPage(filename); tabPage.Controls.Add(entitySpec); this.Tabs.TabPages.Add(tabPage); } }
/// <summary> /// Initializes a new instance of the <see cref="EntityQueryScanTarget"/> class. /// </summary> /// <param name="entityType"> /// The entity type. /// </param> /// <param name="entitySpec"> /// The entity spec. /// </param> /// <param name="key"> /// The entity key. /// </param> /// <param name="valueSink"> /// The value sink. /// </param> internal EntityQueryScanTarget(Type entityType, EntitySpec entitySpec, Key key, Action<object> valueSink) : base(entityType, entitySpec, key) { this.setter = this.Add; this.valueSink = valueSink; }
/// <summary> /// Adds an entity specification to the scan. /// </summary> /// <param name="entitySpec"> /// The entity specification to add. /// </param> public void Add(EntitySpec entitySpec) { var esr = entitySpec as EntityScanResult; if (esr == null) { throw new ArgumentException(@"EntitySpec of type EntityScanResult expected", "entitySpec"); } lock (this.syncRoot) { this.entityScanResult = esr; } }
public void Init() { var componentList = new ComponentList(); var parms = _method.GetParameters(); var method = new DynamicMethod("Execute", null, new Type[] { typeof(object), typeof(int), typeof(void **) }); var gen = method.GetILGenerator(); var i = gen.DeclareLocal(typeof(int)); var b = gen.DeclareLocal(typeof(bool)); var arrays = new LocalBuilder[parms.Length]; for (var k = 0; k < parms.Length; k++) { arrays[k] = gen.DeclareLocal(parms[k].ParameterType); } var end = gen.DefineLabel(); var top = gen.DefineLabel(); //init component type pointers for (var k = 0; k < parms.Length; k++) { gen.Emit(OpCodes.Ldarg_2); if (k > 0) { gen.Emit(OpCodes.Sizeof, typeof(void *)); gen.Emit(OpCodes.Add); } gen.Emit(OpCodes.Ldind_I); gen.Emit(OpCodes.Stloc, arrays[k].LocalIndex); } //i = 0 gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Stloc, i.LocalIndex); gen.Emit(OpCodes.Br_S, end); // //for loop gen.MarkLabel(top); gen.Emit(OpCodes.Ldarg_0); //systemtest for (var k = 0; k < parms.Length; k++) { var pType = parms[k].ParameterType; var dataType = pType.GetElementType(); //load component ptr gen.Emit(OpCodes.Ldloc, arrays[k].LocalIndex); // gen.Emit(OpCodes.Ldarg_2); // if (k > 0) // { // gen.Emit(OpCodes.Ldc_I4, k); // gen.Emit(OpCodes.Sizeof, typeof(void*)); // gen.Emit(OpCodes.Mul); // gen.Emit(OpCodes.Add); // } // gen.Emit(OpCodes.Ldind_I); //load i gen.Emit(OpCodes.Ldloc, i.LocalIndex); gen.Emit(OpCodes.Conv_I); //increment pointer by index of i gen.Emit(OpCodes.Sizeof, dataType); gen.Emit(OpCodes.Mul); gen.Emit(OpCodes.Add); if (!componentList.TryAddComponent(dataType, out var componentType)) { return; //invalid type } if (!_componentTypes.Add(componentType)) { return; //duplicate type } //check if we are read only (finally a decent way to enforce read only pointers!) if (parms[k].GetCustomAttribute <System.Runtime.InteropServices.InAttribute>() != null) { _readComponents.Add(componentType); } else { _writeComponents.Add(componentType); } } //call method gen.Emit(OpCodes.Call, _method); //i++ gen.Emit(OpCodes.Ldloc, i.LocalIndex); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Add); gen.Emit(OpCodes.Stloc, i.LocalIndex); //i < length gen.MarkLabel(end); gen.Emit(OpCodes.Ldloc, i.LocalIndex); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Clt); gen.Emit(OpCodes.Stloc, b.LocalIndex); gen.Emit(OpCodes.Ldloc, b.LocalIndex); gen.Emit(OpCodes.Brtrue_S, top); gen.Emit(OpCodes.Ret); _execute = (Executor)method.CreateDelegate(typeof(Executor)); var extraComponents = _method.GetCustomAttribute <HasAttribute>()?.Types.Where(x => componentList.TryAddComponent(x)).Select(x => componentList.Get(x)).ToArray(); if (extraComponents != null) { foreach (var it in extraComponents) { _componentTypes.Add(it); } } _anyComponent = _method.GetCustomAttribute <AnyAttribute>()?.Types.Where(x => componentList.TryAddComponent(x)).Select(x => componentList.Get(x)).ToArray(); _ignoreComponent = _method.GetCustomAttribute <IgnoreAttribute>()?.Types.Where(x => componentList.TryAddComponent(x)).Select(x => componentList.Get(x)).ToArray(); _spec = new EntitySpec(_componentTypes.ToArray()); _dependencies = new DependencyList(Name, Priority, config => { foreach (var it in _readComponents) { config.Read(it); } foreach (var it in _writeComponents) { config.Write(it); } var before = _method.GetCustomAttribute <BeforeAttribute>(); if (before != null) { foreach (var it in before.Names) { config.Before(it); } } var after = _method.GetCustomAttribute <AfterAttribute>(); if (after != null) { foreach (var it in after.Names) { config.After(it); } } }); }
private ConcreteEntity _getRealConcreteEntity(Entity e, EntitySpec es) { if (e is Building) { return new ConcreteBuilding((Building)e, (BuildingSpec)es); } if (e is Unit) { return new ConcreteUnit((Unit)e, (UnitSpec)es); } if (e is Resource) { return new ConcreteResource((Resource)e, (ResourceSpec)es); } //if (e is ) return new ConcreteEntity(e, es); }
/// <summary> /// Reads an object. /// </summary> /// <param name="destinationType"> /// The destination type. /// </param> /// <param name="tag"> /// The tag. /// </param> /// <returns> /// The object read. /// </returns> protected override object Read(Type destinationType, Tags tag) { EntitySpec entitySpec = null; switch (tag) { case Tags.EntityRef: entitySpec = new EntitySpec( this.ReadType(), this.ReadString(), this.ReadString(), new Key(this.BinaryReader.ReadString(), this.ReadString(), this.ReadString())); break; case Tags.EntityKey: { var type = this.ReadType(); var entityReference = this.entityBindingContext.EntityReferenceForType(type); if (entityReference == null) { throw new PersistenceException(string.Format(CultureInfo.InvariantCulture, @"{0} is not a valid entity", type)); } var tableBinding = entityReference.TableBinding; if (tableBinding == null) { throw new PersistenceException(string.Format(CultureInfo.InvariantCulture, @"Undefined table binding for type {0}", type)); } entitySpec = new EntitySpec( type, tableBinding.Namespace, tableBinding.TableName, new Key(this.BinaryReader.ReadString(), this.ReadString(), this.ReadString())); break; } case Tags.EntityRow: { var type = this.ReadType(); var entityReference = this.entityBindingContext.EntityReferenceForType(type); if (entityReference == null) { throw new PersistenceException(string.Format(CultureInfo.InvariantCulture, @"{0} is not a valid entity", type)); } var tableBinding = entityReference.TableBinding; if (tableBinding == null) { throw new PersistenceException(string.Format(CultureInfo.InvariantCulture, @"Undefined table binding for type {0}", type)); } var columnBinding = entityReference.ColumnBinding; if (columnBinding == null) { throw new PersistenceException(string.Format(CultureInfo.InvariantCulture, @"Undefined column binding for type {0}", type)); } entitySpec = new EntitySpec( type, tableBinding.Namespace, tableBinding.TableName, new Key(this.BinaryReader.ReadString(), columnBinding.ColumnFamily, columnBinding.ColumnQualifier)); break; } } if (entitySpec != null) { object entity; if (this.entityReader.TryGetFetchedEntity(entitySpec, out entity)) { this.ObjectRefs.Add(entity); return(destinationType.Convert(entity)); } return(entitySpec); } return(base.Read(destinationType, tag)); }
/// <summary> /// Attempts to get an already fetched entity from the cache. /// </summary> /// <param name="entitySpec"> /// The entity spec. /// </param> /// <param name="entity"> /// The entity. /// </param> /// <returns> /// <c>true</c> if the cache contains an element with the specified entity spec, otherwise <c>false</c>. /// </returns> internal bool TryGetFetchedEntity(EntitySpec entitySpec, out object entity) { return this.entitiesFetched.TryGetValue(entitySpec, out entity); }
/// <summary> /// Crée une entité concrète /// </summary> /// <param name="shared">Attributs partagés</param> /// <param name="unshared">Attributs variables</param> public ConcreteEntity(Entity shared, EntitySpec unshared) { this._shared = shared; this._unshared = unshared; }
/// <summary> /// Adds an entity specification to the scan. /// </summary> /// <param name="entitySpec"> /// The entity specification to add. /// </param> /// <param name="scanSpec"> /// The scan specification. /// </param> internal void Add(EntitySpec entitySpec, ScanSpec scanSpec) { lock (this.syncRoot) { if (this.tables == null) { this.tables = new Map<Pair<string>, ITableScan>(); } this.tables = new Map<Pair<string>, ITableScan>(); var tableScanSpec = this.tables.GetOrAdd(new Pair<string>(entitySpec.Namespace, entitySpec.TableName), kvp => this.CreateTableScan(scanSpec)); tableScanSpec.Add(entitySpec); } }
/// <summary> /// Initializes a new instance of the <see cref="EntityScanTarget"/> class. /// </summary> /// <param name="entityType"> /// The entity type. /// </param> /// <param name="entitySpec"> /// The entity spec. /// </param> /// <param name="setter"> /// The scan target setter action. /// </param> internal EntityScanTarget(Type entityType, EntitySpec entitySpec, Action<object, object> setter) : base(entityType, entitySpec) { this.setter = setter; }
/// <summary> /// Attempts to get an already fetched entity from the cache. /// </summary> /// <param name="entitySpec"> /// The entity spec. /// </param> /// <param name="entity"> /// The entity. /// </param> /// <returns> /// <c>true</c> if the cache contains an element with the specified entity spec, otherwise <c>false</c>. /// </returns> internal bool TryGetFetchedEntity(EntitySpec entitySpec, out object entity) { return(this.entitiesFetched.TryGetValue(entitySpec, out entity)); }
/// <summary> /// Initializes a new instance of the <see cref="EntityScanTarget"/> class. /// </summary> /// <param name="entityType"> /// The entity type. /// </param> /// <param name="entitySpec"> /// The entity specification. /// </param> protected EntityScanTarget(Type entityType, EntitySpec entitySpec) : base(entityType, entitySpec) { }
public SystemMethodExecutor(Type type, MethodInfo m) { _type = type; var componentList = new ComponentList(); var parms = m.GetParameters(); var method = new DynamicMethod("Execute", null, new Type[] { typeof(object), typeof(int), typeof(void **) }); var gen = method.GetILGenerator(); var i = gen.DeclareLocal(typeof(int)); var b = gen.DeclareLocal(typeof(bool)); var arrays = new LocalBuilder[parms.Length]; for (var k = 0; k < parms.Length; k++) { arrays[k] = gen.DeclareLocal(parms[k].ParameterType); } var end = gen.DefineLabel(); var top = gen.DefineLabel(); //init component type pointers for (var k = 0; k < parms.Length; k++) { gen.Emit(OpCodes.Ldarg_2); if (k > 0) { gen.Emit(OpCodes.Sizeof, typeof(void *)); gen.Emit(OpCodes.Add); } gen.Emit(OpCodes.Ldind_I); gen.Emit(OpCodes.Stloc, arrays[k].LocalIndex); } //i = 0 gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Stloc, i.LocalIndex); gen.Emit(OpCodes.Br_S, end); // //for loop gen.MarkLabel(top); gen.Emit(OpCodes.Ldarg_0); //systemtest for (var k = 0; k < parms.Length; k++) { var pType = parms[k].ParameterType; var dataType = pType.GetElementType(); //load component ptr gen.Emit(OpCodes.Ldloc, arrays[k].LocalIndex); // gen.Emit(OpCodes.Ldarg_2); // if (k > 0) // { // gen.Emit(OpCodes.Ldc_I4, k); // gen.Emit(OpCodes.Sizeof, typeof(void*)); // gen.Emit(OpCodes.Mul); // gen.Emit(OpCodes.Add); // } // gen.Emit(OpCodes.Ldind_I); //load i gen.Emit(OpCodes.Ldloc, i.LocalIndex); gen.Emit(OpCodes.Conv_I); //increment pointer by index of i gen.Emit(OpCodes.Sizeof, dataType); gen.Emit(OpCodes.Mul); gen.Emit(OpCodes.Add); if (!componentList.TryAddComponent(dataType, out var componentType)) { return; //invalid type } if (!_componentTypes.Add(componentType)) { return; //duplicate type } //check if we are read only (finally a decent way to enforce read only pointers!) if (pType.GetCustomAttribute <System.Runtime.InteropServices.InAttribute>() != null) { _readComponents.Add(componentType); } else { _writeComponents.Add(componentType); } } //call method gen.Emit(OpCodes.Call, m); //i++ gen.Emit(OpCodes.Ldloc, i.LocalIndex); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Add); gen.Emit(OpCodes.Stloc, i.LocalIndex); //i < length gen.MarkLabel(end); gen.Emit(OpCodes.Ldloc, i.LocalIndex); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Clt); gen.Emit(OpCodes.Stloc, b.LocalIndex); gen.Emit(OpCodes.Ldloc, b.LocalIndex); gen.Emit(OpCodes.Brtrue_S, top); gen.Emit(OpCodes.Ret); Execute = (Executor)method.CreateDelegate(typeof(Executor)); Spec = new EntitySpec(_componentTypes.ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="EntityScanTarget"/> class. /// </summary> /// <param name="entityType"> /// The entity type. /// </param> /// <param name="entitySpec"> /// The entity specification. /// </param> /// <param name="key"> /// The entity key. /// </param> protected EntityScanTarget(Type entityType, EntitySpec entitySpec, Key key) : base(entityType, entitySpec, key) { }
/// <summary> /// Initializes a new instance of the <see cref="EntityScanTarget"/> class. /// </summary> /// <param name="property"> /// The inspected property. /// </param> /// <param name="entitySpec"> /// The entity specification. /// </param> /// <param name="target"> /// The scan target. /// </param> internal EntityScanTarget(InspectedProperty property, EntitySpec entitySpec, object target) : base(property.PropertyType, entitySpec) { this.target = target; this.setter = property.Setter; }
/// <summary> /// Service discovery endpoint called by the CloudState operator in order to determine /// the list of <see cref="IStatefulService" />'s running within the current local process. /// </summary> /// <param name="request">ProxyInfo request</param> /// <param name="context">ServerCallContext</param> /// <returns></returns> public override async Task <EntitySpec> discover(ProxyInfo request, ServerCallContext context) { Logger.LogInformation( $"Received discovery call from sidecar [{request.ProxyName} {request.ProxyVersion}] supporting CloudState {request.ProtocolMajorVersion}.{request.ProtocolMinorVersion}" ); Logger.LogDebug($"Supported sidecar entity types: {string.Join(", ", request.SupportedEntityTypes)}"); var unsupportedServices = Services.Values.Where(service => !request.SupportedEntityTypes.Contains(service.StatefulServiceTypeName) ); if (unsupportedServices.Any()) { Logger.LogError( "Proxy doesn't support the entity types for the following services: " + string.Join(", ", unsupportedServices .Select(s => s.ServiceDescriptor.FullName + ": " + s.StatefulServiceTypeName) ) ); } if (false) { // TODO: verify compatibility with in.protocolMajorVersion & in.protocolMinorVersion // await Task.FromException(new CloudStateException("Proxy version not compatible with library protocol support version")); } else { var allDescriptors = new AnySupport(Services.Values.Select(x => x.ServiceDescriptor.File)).FlattenDescriptors( Services.Values.Select(x => x.ServiceDescriptor.File) ); var set = new FileDescriptorSet(); set.File.AddRange(allDescriptors.Select(x => FileDescriptorProto.Parser.ParseFrom(x.Value.SerializedData))); var fileDescriptorSet = set.ToByteString(); var entities = Services.Select(x => new Entity { EntityType = x.Value.StatefulServiceTypeName, ServiceName = x.Key, PersistenceId = x.Value.PersistenceId } ); var spec = new EntitySpec { ServiceInfo = ServiceInfo, Proto = fileDescriptorSet }; try { spec.Entities.AddRange(entities); } catch (Exception ex) { Logger.LogError($"Exception: {ex.StackTrace}", ex.InnerException ?? ex); } return(await Task.FromResult(spec)); } }