IContentAccessor
IAccessor └── IContentAccessor └── IContentAccessor<Container> └── IContentAccessor<Container, Content>
IContentAccessor describes writers to access a specific content in a container, e.g. a field.
/// <summary>Access to specific content of a container.</summary>
public interface IContentAccessor : IAccessor, IContainerAccessor
{
/// <summary></summary>
Type ContentType { 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; }
}
IContentAccessor<Container, Content> describes accessor for container type Content and field type Content.
/// <summary>Indicates content and container types.</summary>
public interface IContentAccessor<Container, Content> : IContentAccessor<Container>, IContentAccessorOf<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; }
}
IContentVisitor and IContentVisitorT are visitor interfaces for IAccessorBase.Accept(IAccessorVisitor).
/// <summary>Base interface for content visitor</summary>
public interface IContentVisitor : IAccessorVisitor
{
/// <summary>Try visit <paramref name="contentAccessor"/>.</summary>
/// <returns>true to continue visitation</returns>
bool VisitContentAccessor(IContentAccessor contentAccessor);
}
/// <summary>Base interface for content visitor</summary>
public interface IContentVisitorT : IAccessorVisitor
{
/// <summary>Try visit <paramref name="contentAccessor"/>.</summary>
/// <returns>true to continue visitation</returns>
bool VisitContentAccessor<Container, Content>(IContentAccessor<Container, Content> contentAccessor);
}
ContentAccessor
AccessorBase └── ContentAccessor └── ContentAccessor<Container> └── ContentAccessor<Container, Content>
ContentAccessor<Content, Field> is the default implementation.
IContentAccessor<MyRecord, int> accessor = new ContentAccessor<MyRecord, int>()
{
Reader = null!,
Writer = null!,
Referer = null!,
}.SetReadOnly();
ContentAccessor.Create(Type, Type) constructs IContentAccessor<Container, Content>. There is a setter method for each field.
IContentAccessor<MyRecord, int> accessor =
(IContentAccessor<MyRecord, int>)
ContentAccessor.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.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IAccessor> request = new AccessorRequest(target);
// Issue request
IContentAccessor<MyRecord> accessor = service.GetRequired<IRequest, IContentAccessor<MyRecord>>(request);
ContentAccessorRequest(target) requests for IContentAccessor<Container>.
// Create service
IService service = Services.Create(Avalanche.Accessor.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyRecord, int> accessor = service.GetRequired<IRequest, IContentAccessor<MyRecord, int>>(request);
ContentAccessorRequest(target) can also request for IContentAccessor<Container, Content>.
// Create service
IService service = Services.Create(Avalanche.Accessor.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!, typeof(object));
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyRecord, object> accessor = service.GetRequired<IRequest, IContentAccessor<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);
ContentAccessorRequest is specifically a request for specific writers. Each can be assigned with explicit customization.
// Create service
IService service = Services.Create(Avalanche.Accessor.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest
{
Reader = new ReaderRequest(target),
Writer = new WriterRequest(target),
Referer = new RefererRequest(target),
IsAssigned = new IsAssignedRequest(target),
Unassign = new UnassignRequest(target),
ContainerType = new ContainerTypeRequest(target),
ContentType = new ContentTypeRequest(target),
};
// Issue request
IContentAccessor<MyRecord> accessor = service.GetRequired<IRequest, IContentAccessor<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.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IContentAccessor<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.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IContentAccessor<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 contentaccessor
{
public static void Run()
{
{
// <00>
IContentAccessor accessor = new ContentAccessor()
{
Reader = null!,
Writer = null!,
Referer = null!,
}.SetReadOnly();
// </00>
}
{
// <01>
IContentAccessor<MyRecord, int> accessor = new ContentAccessor<MyRecord, int>()
{
Reader = null!,
Writer = null!,
Referer = null!,
}.SetReadOnly();
// </01>
}
{
// <02>
IContentAccessor<MyRecord, int> accessor =
(IContentAccessor<MyRecord, int>)
ContentAccessor.Create(typeof(MyRecord), typeof(int))
.SetReader(null!)
.SetWriter(null!)
.SetReferer(null!)
.SetReadOnly();
// </02>
}
{
// <03>
IContentAccessor accessor =
ContentAccessor.Create(typeof(MyRecord))
.SetReader(null!)
.SetWriter(null!)
.SetReferer(null!)
.SetReadOnly();
// </03>
}
{
// <04>
IContentAccessor accessor =
ContentAccessor.Create(typeof(MyRecord), typeof(object))
.SetReader(null!)
.SetWriter(null!)
.SetReferer(null!)
.SetReadOnly();
// </04>
}
{
// <10>
// Create service
IService service = Services.Create(Avalanche.Accessor.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IAccessor> request = new AccessorRequest(target);
// Issue request
IContentAccessor<MyRecord> accessor = service.GetRequired<IRequest, IContentAccessor<MyRecord>>(request);
// </10>
}
{
// <11>
// Create service
IService service = Services.Create(Avalanche.Accessor.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyRecord, int> accessor = service.GetRequired<IRequest, IContentAccessor<MyRecord, int>>(request);
// </11>
}
{
// <11B>
// Create service
IService service = Services.Create(Avalanche.Accessor.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!, typeof(object));
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyRecord, object> accessor = service.GetRequired<IRequest, IContentAccessor<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.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest
{
Reader = new ReaderRequest(target),
Writer = new WriterRequest(target),
Referer = new RefererRequest(target),
IsAssigned = new IsAssignedRequest(target),
Unassign = new UnassignRequest(target),
ContainerType = new ContainerTypeRequest(target),
ContentType = new ContentTypeRequest(target),
};
// Issue request
IContentAccessor<MyRecord> accessor = service.GetRequired<IRequest, IContentAccessor<MyRecord>>(request);
// </12>
}
{
// Create service
IService service = Services.Create(Avalanche.Accessor.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyRecord).GetField("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyRecord, int> accessor = service.GetRequired<IRequest, IContentAccessor<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.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IContentAccessor<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.Net.Module.Instance);
// Create container target
IContainerTarget target = new NetField(typeof(MyStruct).GetProperty("Id")!);
// Create request
IRequestFor<IContentAccessor> request = new ContentAccessorRequest(target);
// Issue request
IContentAccessor<MyStruct, int> accessor = service.GetRequired<IRequest, IContentAccessor<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>
}