FieldInfo
AccessorRequest<NetField> requests for a field accessor of FieldInfo or PropertyInfo. (Avalanche.Accessor.Net.dll)
// Create description
FieldInfo fi = typeof(MyClass).GetField("Id")!;
// Create request
AccessorRequest request = new AccessorRequest(new NetField(fi));
// Create accessor
IContentAccessor<MyClass, int> idAccessor = Services.Create(NetAccessorHandlers.Instance).GetRequired<IRequest, IContentAccessor<MyClass, int>>(request);
ContentAccessorRequest(IFieldDescription) also request for IContentAccessor<Container, Content>. FieldInfo, PropertyInfo, MethodInfo, ParameterInfo, and IEnumerable<EmitLine> can be used to describe .Reader, .Writer and .Referer.
// Create description
FieldInfo fi = typeof(MyClass).GetField("Id")!;
IFieldDescription fieldDescription =
new FieldDescription()
.SetName("Id")
.SetType(typeof(int))
.SetReader(fi)
.SetWriter(fi)
.SetReferer(fi)
.SetReadOnly();
// Create request
ContentAccessorRequest request = new ContentAccessorRequest(new NetField(fieldDescription));
// Create accessor
IContentAccessor<MyClass, int> idAccessor =
Services.Create(NetAccessorHandlers.Instance).GetRequired<ContentAccessorRequest, IContentAccessor<MyClass, int>>(request);
ContentAccessorRequest(target, contentType) requests for specific ContentType.
// Create container target
IContainerTarget target = new NetField(typeof(MyClass).GetField("Id")!, typeof(object));
// Create request
ContentAccessorRequest request = new ContentAccessorRequest(target);
// Create accessor
IContentAccessor<MyClass, object> idAccessor =
Services.Create(NetAccessorHandlers.Instance).GetRequired<ContentAccessorRequest, IContentAccessor<MyClass, object>>(request);
FieldDescriptionRequest(Target) requests a field description for FieldInfo, PropertyInfo, MethodInfo, ParameterInfo, and IEnumerable<EmitLine>.
// Get target
FieldInfo fi = typeof(MyClass).GetField("Id")!;
// Create description request
IRequestFor<IFieldDescription> fieldDescriptionRequest = new FieldDescriptionRequest(fi);
// Create request
IRequestFor<IContentAccessor> fieldAccessorRequest = new ContentAccessorRequest(new NetField(fieldDescriptionRequest));
// Create accessor
IContentAccessor<MyClass, int> idAccessor = Services.Create(NetAccessorHandlers.Instance).GetRequired<IRequestFor<IContentAccessor>, IContentAccessor<MyClass, int>>(fieldAccessorRequest);
Usage
.Reader reads the value from the field.
MyClass myRecord = new MyClass(50, "ABC");
int id = idAccessor.Reader.Read(myRecord);
.Writer writes value to field.
MyClass myRecord = new MyClass(50, "ABC");
idAccessor.Writer.Write(10, myRecord);
.Referer gets a pointer to field.
IReferer<MyClass, int> referer1 = new MyClassIdReferer();
MyClass myRecord = new MyClass(50, "ABC");
ref int pointer = ref referer1.GetReference(myRecord);
IRefererFromRef<MyStruct, int> referer2 = new MyStructIdReferer();
MyStruct myStruct = new MyStruct(7, "");
ref int id2 = ref referer2.GetReference(ref myStruct);
Implementation
The default implementations work for most cases, however, more specific custom implementations can be crafted.
Reader
public class MyClass
{
public int Id;
public string Label;
public MyClass(int id, string label)
{
Id = id;
Label = label;
}
}
public struct MyStruct
{
public int Id;
public string Label;
public MyStruct(int id, string label)
{
Id = id;
Label = label;
}
}
Reader can be created with delegate.
var myClassIdReader = DelegateWriter.Reader((MyClass record) => record.Id);
var myStructIdReader = DelegateWriter.Reader((MyStruct record) => record.Id);
Reader can be created with base class.
/// <summary></summary>
public class MyClassIdReader : WriterToRef<MyClass, int>
{
/// <summary></summary>
public override bool TryWrite(MyClass from, ref int to, IServiceProvider? context = null)
{
if (from == null) return false;
to = from.Id;
return true;
}
}
/// <summary></summary>
public class MyStructIdReader : WriterToRef<MyStruct, int>
{
/// <summary></summary>
public override bool TryWrite(MyStruct from, ref int to, IServiceProvider? context = null)
{
to = from.Id;
return true;
}
}
Handler processes ReaderRequest.
// Create service
IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassIdReaderBuilder()), CachePolicies.Default);
// Create field description
IFieldDescription fieldDescription = new FieldDescription().Read(typeof(MyClass).GetField("Id")!).SetReadOnly();
// Reader request
ReaderRequest request = new ReaderRequest(new NetField(fieldDescription));
// Get reader
IWriterBase<MyClass, int> myClassIdReader = service.GetRequired<ReaderRequest, IWriterBase<MyClass, int>>(request);
// Create class
MyClass myClass = new MyClass(6, "");
// Read
int id = myClassIdReader.Read(myClass);
public class MyClassIdReaderBuilder : IHandler<ReaderRequest, IWriterBase>
{
[Order(-100)]
public void Handle(IQuery<ReaderRequest, IWriterBase> query)
{
// Already handled
if (query.Handled()) return;
// Place here field description
IFieldDescription fieldDescription;
// Get field description
if (query.Request.Target is INetField netFieldType && netFieldType.ContainerType is IFieldDescription fieldDescription1) fieldDescription = fieldDescription1;
else if (query.Request.Target is INetType netType && netType.ContainerType is IFieldDescription fieldDescription2) fieldDescription = fieldDescription2;
else if (query.Request.Target is IFieldDescription fieldDescription3) fieldDescription = fieldDescription3;
else return;
// Get record type
Type recordType = fieldDescription.Record?.Type ?? (fieldDescription.Reader as MemberInfo)?.DeclaringType!;
// This handler only handles "MyClass"
if (!typeof(MyClass).Equals(recordType)) return;
//
if (!"Id".Equals(fieldDescription.Name?.ToString())) return;
// Create reader
IWriterBase reader = new MyClassIdReader();
// Decorate IWriterBase<object, object> support
reader = WriterAdapter.Create(reader);
// Assign reader
query.Response.SetValue(reader);
}
}
Writer
Writer can be created with delegate.
var myClassIdWriter = DelegateWriter.Writer((int value, MyClass record) => record.Id = value);
var myStructIdWriter = DelegateWriter.Writer((int value, ref MyStruct record) => record.Id = value);
Writer can be created with base class.
/// <summary></summary>
public class MyClassIdWriter : Writer<int, MyClass>
{
/// <summary></summary>
public override bool TryWrite(int value, MyClass to, IServiceProvider? context = null)
{
if (to == null) return false;
to.Id = value;
return true;
}
}
/// <summary></summary>
public class MyStructIdWriter : WriterToRef<int, MyStruct>
{
/// <summary></summary>
public override bool TryWrite(int value, ref MyStruct to, IServiceProvider? context = null)
{
to.Id = value;
return true;
}
}
Handler processes WriterRequest.
// Create service
IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassIdWriterBuilder()), CachePolicies.Default);
// Create field description
IFieldDescription fieldDescription = new FieldDescription().Read(typeof(MyClass).GetField("Id")!).SetReadOnly();
// Writer request
WriterRequest request = new WriterRequest(new NetField(fieldDescription));
// Get writer
IWriter<int, MyClass> myClassIdWriter = service.GetRequired<WriterRequest, IWriter<int, MyClass>>(request);
// Create class
MyClass myClass = new MyClass(6, "");
// Write
myClassIdWriter.Write(2023, myClass);
public class MyClassIdWriterBuilder : IHandler<WriterRequest, IWriterBase>
{
[Order(-100)]
public void Handle(IQuery<WriterRequest, IWriterBase> query)
{
// Already handled
if (query.Handled()) return;
//
if (query.Request.Target is not IFieldDescription fieldDescription) return;
// Get record type
Type recordType = fieldDescription.Record?.Type ?? (fieldDescription.Writer as MemberInfo)?.DeclaringType!;
// This handler only handles "MyClass"
if (!typeof(MyClass).Equals(recordType)) return;
//
if (!"Id".Equals(fieldDescription.Name?.ToString())) return;
// Create writer
IWriterBase writer = new MyClassIdWriter();
// Decorate IWriterBase<object, object> support
writer = WriterAdapter.Create(writer);
// Assign writer
query.Response.SetValue(writer);
}
}
Referer
Referer can be created with base class.
/// <summary></summary>
public class MyClassIdReferer : IReferer<MyClass, int>
{
public bool CanRefer => true;
public Type FromType => typeof(MyClass);
public Type ToType => typeof(int);
public ref int GetReference(MyClass record, IServiceProvider? context = null) => ref record.Id;
public bool Accept(IWriterBaseVisitor visitor) => visitor is not IRefererVisitor v ? true : v.Visit(refererT: this);
}
/// <summary></summary>
public class MyStructIdReferer : IRefererFromRef<MyStruct, int>
{
public bool CanRefer => true;
public Type FromType => typeof(MyStruct);
public Type ToType => typeof(int);
public ref int GetReference(ref MyStruct record, IServiceProvider? context = null) => ref record.Id;
public bool Accept(IWriterBaseVisitor visitor) => visitor is not IRefererVisitor v ? true : v.Visit(refererTFR: this);
}
Handler processes RefererRequest.
// Create service
IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassIdRefererBuilder()), CachePolicies.Default);
// Create field description
IFieldDescription fieldDescription = new FieldDescription().Read(typeof(MyClass).GetField("Id")!).SetReadOnly();
// Referer request
RefererRequest request = new RefererRequest(new NetField(fieldDescription));
// Get referer
IReferer<MyClass, int> myClassIdReferer = service.GetRequired<RefererRequest, IReferer<MyClass, int>>(request);
// Create class
MyClass myClass = new MyClass(6, "");
// Read
ref int id = ref myClassIdReferer.GetReference(myClass);
public class MyClassIdRefererBuilder : IHandler<RefererRequest, IWriterBase>
{
[Order(-100)]
public void Handle(IQuery<RefererRequest, IWriterBase> query)
{
// Already handled
if (query.Handled()) return;
//
if (query.Request.Target is not IFieldDescription fieldDescription) return;
// Get record type
Type recordType = fieldDescription.Record?.Type ?? (fieldDescription.Referer as MemberInfo)?.DeclaringType!;
// This handler only handles "MyClass"
if (!typeof(MyClass).Equals(recordType)) return;
//
if (!"Id".Equals(fieldDescription.Name?.ToString())) return;
// Create referer
IWriterBase referer = new MyClassIdReferer();
// Assign referer
query.Response.SetValue(referer);
}
}
Full Example
Full example
using System;
using System.Reflection;
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 field
{
public static void Run()
{
{
// <10>
// Create description
FieldInfo fi = typeof(MyClass).GetField("Id")!;
// Create request
AccessorRequest request = new AccessorRequest(new NetField(fi));
// Create accessor
IContentAccessor<MyClass, int> idAccessor = Services.Create(NetAccessorHandlers.Instance).GetRequired<IRequest, IContentAccessor<MyClass, int>>(request);
// </10>
}
{
// <11>
// Create description
FieldInfo fi = typeof(MyClass).GetField("Id")!;
IFieldDescription fieldDescription =
new FieldDescription()
.SetName("Id")
.SetType(typeof(int))
.SetReader(fi)
.SetWriter(fi)
.SetReferer(fi)
.SetReadOnly();
// Create request
ContentAccessorRequest request = new ContentAccessorRequest(new NetField(fieldDescription));
// Create accessor
IContentAccessor<MyClass, int> idAccessor =
Services.Create(NetAccessorHandlers.Instance).GetRequired<ContentAccessorRequest, IContentAccessor<MyClass, int>>(request);
// </11>
}
{
// <11B>
// Create container target
IContainerTarget target = new NetField(typeof(MyClass).GetField("Id")!, typeof(object));
// Create request
ContentAccessorRequest request = new ContentAccessorRequest(target);
// Create accessor
IContentAccessor<MyClass, object> idAccessor =
Services.Create(NetAccessorHandlers.Instance).GetRequired<ContentAccessorRequest, IContentAccessor<MyClass, object>>(request);
// </11B>
}
{
// <12>
// Get target
FieldInfo fi = typeof(MyClass).GetField("Id")!;
// Create description request
IRequestFor<IFieldDescription> fieldDescriptionRequest = new FieldDescriptionRequest(fi);
// Create request
IRequestFor<IContentAccessor> fieldAccessorRequest = new ContentAccessorRequest(new NetField(fieldDescriptionRequest));
// Create accessor
IContentAccessor<MyClass, int> idAccessor = Services.Create(NetAccessorHandlers.Instance).GetRequired<IRequestFor<IContentAccessor>, IContentAccessor<MyClass, int>>(fieldAccessorRequest);
// </12>
{
// <51>
MyClass myRecord = new MyClass(50, "ABC");
int id = idAccessor.Reader.Read(myRecord);
// </51>
}
{
// <51E>
var myClassIdReader = DelegateWriter.Reader((MyClass record) => record.Id);
var myStructIdReader = DelegateWriter.Reader((MyStruct record) => record.Id);
// </51E>
}
{
// <51H>
// Create service
IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassIdReaderBuilder()), CachePolicies.Default);
// Create field description
IFieldDescription fieldDescription = new FieldDescription().Read(typeof(MyClass).GetField("Id")!).SetReadOnly();
// Reader request
ReaderRequest request = new ReaderRequest(new NetField(fieldDescription));
// Get reader
IWriterBase<MyClass, int> myClassIdReader = service.GetRequired<ReaderRequest, IWriterBase<MyClass, int>>(request);
// Create class
MyClass myClass = new MyClass(6, "");
// Read
int id = myClassIdReader.Read(myClass);
// </51H>
}
{
// <52>
MyClass myRecord = new MyClass(50, "ABC");
idAccessor.Writer.Write(10, myRecord);
// </52>
}
{
// <52E>
var myClassIdWriter = DelegateWriter.Writer((int value, MyClass record) => record.Id = value);
var myStructIdWriter = DelegateWriter.Writer((int value, ref MyStruct record) => record.Id = value);
// </52E>
}
{
// <52H>
// Create service
IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassIdWriterBuilder()), CachePolicies.Default);
// Create field description
IFieldDescription fieldDescription = new FieldDescription().Read(typeof(MyClass).GetField("Id")!).SetReadOnly();
// Writer request
WriterRequest request = new WriterRequest(new NetField(fieldDescription));
// Get writer
IWriter<int, MyClass> myClassIdWriter = service.GetRequired<WriterRequest, IWriter<int, MyClass>>(request);
// Create class
MyClass myClass = new MyClass(6, "");
// Write
myClassIdWriter.Write(2023, myClass);
// </52H>
}
{
// <53>
IReferer<MyClass, int> referer1 = new MyClassIdReferer();
MyClass myRecord = new MyClass(50, "ABC");
ref int pointer = ref referer1.GetReference(myRecord);
IRefererFromRef<MyStruct, int> referer2 = new MyStructIdReferer();
MyStruct myStruct = new MyStruct(7, "");
ref int id2 = ref referer2.GetReference(ref myStruct);
// </53>
}
{
// <53H>
// Create service
IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassIdRefererBuilder()), CachePolicies.Default);
// Create field description
IFieldDescription fieldDescription = new FieldDescription().Read(typeof(MyClass).GetField("Id")!).SetReadOnly();
// Referer request
RefererRequest request = new RefererRequest(new NetField(fieldDescription));
// Get referer
IReferer<MyClass, int> myClassIdReferer = service.GetRequired<RefererRequest, IReferer<MyClass, int>>(request);
// Create class
MyClass myClass = new MyClass(6, "");
// Read
ref int id = ref myClassIdReferer.GetReference(myClass);
// </53H>
}
}
}
// <100>
public class MyClass
{
public int Id;
public string Label;
public MyClass(int id, string label)
{
Id = id;
Label = label;
}
}
public struct MyStruct
{
public int Id;
public string Label;
public MyStruct(int id, string label)
{
Id = id;
Label = label;
}
}
// </100>
// <51F>
/// <summary></summary>
public class MyClassIdReader : WriterToRef<MyClass, int>
{
/// <summary></summary>
public override bool TryWrite(MyClass from, ref int to, IServiceProvider? context = null)
{
if (from == null) return false;
to = from.Id;
return true;
}
}
/// <summary></summary>
public class MyStructIdReader : WriterToRef<MyStruct, int>
{
/// <summary></summary>
public override bool TryWrite(MyStruct from, ref int to, IServiceProvider? context = null)
{
to = from.Id;
return true;
}
}
// </51F>
// <51G>
public class MyClassIdReaderBuilder : IHandler<ReaderRequest, IWriterBase>
{
[Order(-100)]
public void Handle(IQuery<ReaderRequest, IWriterBase> query)
{
// Already handled
if (query.Handled()) return;
// Place here field description
IFieldDescription fieldDescription;
// Get field description
if (query.Request.Target is INetField netFieldType && netFieldType.ContainerType is IFieldDescription fieldDescription1) fieldDescription = fieldDescription1;
else if (query.Request.Target is INetType netType && netType.ContainerType is IFieldDescription fieldDescription2) fieldDescription = fieldDescription2;
else if (query.Request.Target is IFieldDescription fieldDescription3) fieldDescription = fieldDescription3;
else return;
// Get record type
Type recordType = fieldDescription.Record?.Type ?? (fieldDescription.Reader as MemberInfo)?.DeclaringType!;
// This handler only handles "MyClass"
if (!typeof(MyClass).Equals(recordType)) return;
//
if (!"Id".Equals(fieldDescription.Name?.ToString())) return;
// Create reader
IWriterBase reader = new MyClassIdReader();
// Decorate IWriterBase<object, object> support
reader = WriterAdapter.Create(reader);
// Assign reader
query.Response.SetValue(reader);
}
}
// </51G>
// <52F>
/// <summary></summary>
public class MyClassIdWriter : Writer<int, MyClass>
{
/// <summary></summary>
public override bool TryWrite(int value, MyClass to, IServiceProvider? context = null)
{
if (to == null) return false;
to.Id = value;
return true;
}
}
/// <summary></summary>
public class MyStructIdWriter : WriterToRef<int, MyStruct>
{
/// <summary></summary>
public override bool TryWrite(int value, ref MyStruct to, IServiceProvider? context = null)
{
to.Id = value;
return true;
}
}
// </52F>
// <52G>
public class MyClassIdWriterBuilder : IHandler<WriterRequest, IWriterBase>
{
[Order(-100)]
public void Handle(IQuery<WriterRequest, IWriterBase> query)
{
// Already handled
if (query.Handled()) return;
//
if (query.Request.Target is not IFieldDescription fieldDescription) return;
// Get record type
Type recordType = fieldDescription.Record?.Type ?? (fieldDescription.Writer as MemberInfo)?.DeclaringType!;
// This handler only handles "MyClass"
if (!typeof(MyClass).Equals(recordType)) return;
//
if (!"Id".Equals(fieldDescription.Name?.ToString())) return;
// Create writer
IWriterBase writer = new MyClassIdWriter();
// Decorate IWriterBase<object, object> support
writer = WriterAdapter.Create(writer);
// Assign writer
query.Response.SetValue(writer);
}
}
// </52G>
// <53F>
/// <summary></summary>
public class MyClassIdReferer : IReferer<MyClass, int>
{
public bool CanRefer => true;
public Type FromType => typeof(MyClass);
public Type ToType => typeof(int);
public ref int GetReference(MyClass record, IServiceProvider? context = null) => ref record.Id;
public bool Accept(IWriterBaseVisitor visitor) => visitor is not IRefererVisitor v ? true : v.Visit(refererT: this);
}
/// <summary></summary>
public class MyStructIdReferer : IRefererFromRef<MyStruct, int>
{
public bool CanRefer => true;
public Type FromType => typeof(MyStruct);
public Type ToType => typeof(int);
public ref int GetReference(ref MyStruct record, IServiceProvider? context = null) => ref record.Id;
public bool Accept(IWriterBaseVisitor visitor) => visitor is not IRefererVisitor v ? true : v.Visit(refererTFR: this);
}
// </53F>
// <53G>
public class MyClassIdRefererBuilder : IHandler<RefererRequest, IWriterBase>
{
[Order(-100)]
public void Handle(IQuery<RefererRequest, IWriterBase> query)
{
// Already handled
if (query.Handled()) return;
//
if (query.Request.Target is not IFieldDescription fieldDescription) return;
// Get record type
Type recordType = fieldDescription.Record?.Type ?? (fieldDescription.Referer as MemberInfo)?.DeclaringType!;
// This handler only handles "MyClass"
if (!typeof(MyClass).Equals(recordType)) return;
//
if (!"Id".Equals(fieldDescription.Name?.ToString())) return;
// Create referer
IWriterBase referer = new MyClassIdReferer();
// Assign referer
query.Response.SetValue(referer);
}
}
// </53G>
}