IFieldAccessor
IAccessor └── IFieldAccessor └── IFieldAccessor<Container> └── IFieldAccessor<Container, Content>
IFieldAccessor describes writers to access a specific content in a container, e.g. a field.
/// <summary>Access to specific field of a container.</summary>
public interface IFieldAccessor : IAccessor, IContainerAccessor
{
/// <summary></summary>
Type ContentType { get; set; }
/// <summary></summary>
IAccessor ContentAccessor { get; set; }
/// <summary>Reads <typeparamref name="Content"/> from <typeparamref name="Container"/>.</summary>
IWriter Reader { get; set; }
/// <summary>Writes <typeparamref name="Content"/> to <typeparamref name="Container"/>.</summary>
IWriter Writer { get; set; }
/// <summary>Refers <typeparamref name="Content"/> in <typeparamref name="Container"/>.</summary>
IWriter Referer { get; set; }
}
IFieldAccessor<Container, Content> describes accessor for container type Content and field type Content.
/// <summary>Indicates field and container types.</summary>
public interface IFieldAccessor<Container, Content> : IFieldAccessor<Container>, IFieldAccessorOf<Content>
{
/// <summary>Reads <typeparamref name="Content"/> from <typeparamref name="Container"/>.</summary>
new IWriterBase<Container, Content> Reader { get; set; }
/// <summary>Writes <typeparamref name="Content"/> to <typeparamref name="Container"/>.</summary>
new IWriterBase<Content, Container> Writer { get; set; }
/// <summary>Refers <typeparamref name="Content"/> in <typeparamref name="Container"/>.</summary>
new IWriter Referer { get; set; }
}
IFieldVisitor and IFieldVisitorT are visitor interfaces for IAccessorBase.Accept(IAccessorVisitor).
/// <summary>Base interface for field visitor</summary>
public interface IFieldVisitor : IAccessorVisitor
{
/// <summary>Try visit <paramref name="fieldAccessor"/>.</summary>
/// <returns>true to continue visitation</returns>
bool VisitFieldAccessor(IFieldAccessor fieldAccessor);
}
/// <summary>Base interface for field visitor</summary>
public interface IFieldVisitorT : IAccessorVisitor
{
/// <summary>Try visit <paramref name="fieldAccessor"/>.</summary>
/// <returns>true to continue visitation</returns>
bool VisitFieldAccessor<Container, Content>(IFieldAccessor<Container, Content> fieldAccessor);
}
FieldAccessor
AccessorBase └── FieldAccessor └── FieldAccessor<Container> └── FieldAccessor<Container, Content>
FieldAccessor<Content, Field> is the default implementation.
IFieldAccessor<MyRecord, int> accessor = new FieldAccessor<MyRecord, int>()
{
Reader = null!,
Writer = null!,
Referer = null!,
}.SetReadOnly();
FieldAccessor.Create(Type, Type) constructs IFieldAccessor<Container, Content>. There is a setter method for each field.
IFieldAccessor<MyRecord, int> accessor =
(IFieldAccessor<MyRecord, int>)
FieldAccessor.Create(typeof(MyRecord), typeof(int))
.SetReader(null!)
.SetWriter(null!)
.SetReferer(null!)
.SetReadOnly();
Query
AccessorRequest(target) requests for IAccessor depending on type target.
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IAccessor> request = new AccessorRequest(target);
// Issue request
IFieldAccessor<MyRecord> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord>>(request);
FieldAccessorRequest(target) requests for IFieldAccessor<Container>.
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyRecord, int> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord, int>>(request);
FieldAccessorRequest(target) can also request for IFieldAccessor<Container, Content>.
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!, typeof(object));
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyRecord, object> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord, object>>(request);
// Create record
var record = new MyRecord(11, "A");
// Write as boxed object
accessor.Writer.Write(12, record);
// Read as object
object label = accessor.Reader.Read(record);
FieldAccessorRequest is specifically a request for specific writers. Each can be assigned with explicit customization.
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest
{
Reader = new ReaderRequest(target),
Writer = new WriterRequest(target),
Referer = new RefererRequest(target),
IsAssigned = new IsAssignedRequest(target),
Unassign = new UnassignRequest(target),
ContainerType = new TypeRequest(target),
ContentType = new TypeRequest(new ContentTargetRequest(target)),
};
// Issue request
IFieldAccessor<MyRecord> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord>>(request);
Usage
.Reader reads value from container.
MyRecord record = new MyRecord(10, "Hello");
int id = accessor.Reader.ReadAs<MyRecord, int>(record);
.Writer writes value to container.
MyRecord record = new MyRecord(10, "Hello");
accessor.Writer.WriteAs<int, MyRecord>(11, record);
.Referer gets pointer to the value in the container.
MyRecord record = new MyRecord(10, "Hello");
ref int pointer = ref ((IReferer<MyRecord, int>)accessor.Referer).GetReference(record);
Notes
A ref must be used when accessing value-typed container.
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IFieldAccessor<MyStruct, int>>(request);
// Create value-typed record on stack
MyStruct record = new MyStruct(10, "Hello");
// Write id
accessor.Writer.WriteAs<int, MyStruct>(11, ref record);
Boxed value-types can be accessed as object.
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IFieldAccessor<MyStruct, int>>(request);
// Create value-typed record into heap
object record = new MyStruct(10, "Hello");
// Write id
accessor.Writer.TypeCast<int, object>().Write(11, record);
Full Example
Full example
using System.Runtime.Serialization;
using Avalanche.Accessor;
using Avalanche.DataType;
using Avalanche.Service;
using Avalanche.Utilities;
using Avalanche.Utilities.Record;
using Avalanche.Writer;
public class fieldaccessor
{
public static void Run()
{
{
// <00>
IFieldAccessor accessor = new FieldAccessor()
{
Reader = null!,
Writer = null!,
Referer = null!,
}.SetReadOnly();
// </00>
}
{
// <01>
IFieldAccessor<MyRecord, int> accessor = new FieldAccessor<MyRecord, int>()
{
Reader = null!,
Writer = null!,
Referer = null!,
}.SetReadOnly();
// </01>
}
{
// <02>
IFieldAccessor<MyRecord, int> accessor =
(IFieldAccessor<MyRecord, int>)
FieldAccessor.Create(typeof(MyRecord), typeof(int))
.SetReader(null!)
.SetWriter(null!)
.SetReferer(null!)
.SetReadOnly();
// </02>
}
{
// <03>
IFieldAccessor accessor =
FieldAccessor.Create(typeof(MyRecord))
.SetReader(null!)
.SetWriter(null!)
.SetReferer(null!)
.SetReadOnly();
// </03>
}
{
// <04>
IFieldAccessor accessor =
FieldAccessor.Create(typeof(MyRecord), typeof(object))
.SetReader(null!)
.SetWriter(null!)
.SetReferer(null!)
.SetReadOnly();
// </04>
}
{
// <10>
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IAccessor> request = new AccessorRequest(target);
// Issue request
IFieldAccessor<MyRecord> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord>>(request);
// </10>
}
{
// <11>
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyRecord, int> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord, int>>(request);
// </11>
}
{
// <11B>
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!, typeof(object));
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyRecord, object> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord, object>>(request);
// Create record
var record = new MyRecord(11, "A");
// Write as boxed object
accessor.Writer.Write(12, record);
// Read as object
object label = accessor.Reader.Read(record);
// </11B>
}
{
// <12>
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest
{
Reader = new ReaderRequest(target),
Writer = new WriterRequest(target),
Referer = new RefererRequest(target),
IsAssigned = new IsAssignedRequest(target),
Unassign = new UnassignRequest(target),
ContainerType = new TypeRequest(target),
ContentType = new TypeRequest(new ContentTargetRequest(target)),
};
// Issue request
IFieldAccessor<MyRecord> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord>>(request);
// </12>
}
{
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyRecord, int> accessor = service.GetRequired<IRequest, IFieldAccessor<MyRecord, int>>(request);
{
// <51>
MyRecord record = new MyRecord(10, "Hello");
int id = accessor.Reader.ReadAs<MyRecord, int>(record);
// </51>
}
{
// <52>
MyRecord record = new MyRecord(10, "Hello");
accessor.Writer.WriteAs<int, MyRecord>(11, record);
// </52>
}
{
// <53>
MyRecord record = new MyRecord(10, "Hello");
ref int pointer = ref ((IReferer<MyRecord, int>)accessor.Referer).GetReference(record);
// </53>
}
}
{
// <71>
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IFieldAccessor<MyStruct, int>>(request);
// Create value-typed record on stack
MyStruct record = new MyStruct(10, "Hello");
// Write id
accessor.Writer.WriteAs<int, MyStruct>(11, ref record);
// </71>
}
{
// <72>
// Create service
IService service = Services.Create(Avalanche.Accessor.Dto.Module.Instance);
// Create container target
IContainerTarget target = DtoTarget.Field(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IFieldAccessor> request = new FieldAccessorRequest(target);
// Issue request
IFieldAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IFieldAccessor<MyStruct, int>>(request);
// Create value-typed record into heap
object record = new MyStruct(10, "Hello");
// Write id
accessor.Writer.TypeCast<int, object>().Write(11, record);
// </72>
}
}
// <100>
public record MyRecord
{
public int Id;
public string Label;
public MyRecord(int id, string label)
{
this.Id = id;
this.Label = label;
}
}
// </100>
// <101>
public record struct MyStruct(int Id, string Label);
// </101>
}