• Avalanche.Core
Search Results for

    Show / Hide Table of Contents
    • Avalanche.Accessor
      • Introduction
      • IAccessor
        • IAccessor
        • IListAccessor
        • IMapAccessor
        • IRecordAccessor
        • IContentAccessor
        • IOneOfAccessor
        • IAnyAccessor
      • .Net
        • Introduction
        • IList<T>
        • IDictionary<K,V>
        • FieldInfo
        • OneOfAttribute
        • StructLayoutAttribute
        • Class
      • Protobuf
        • Introduction
      • Articles
        • Dependency Injection
        • AccessorMessages
    • Avalanche.Binding
      • Introduction
    • Avalanche.Configuration
      • Introduction
      • Configuration Binding
      • ConfigurationExtensions
      • MemoryConfiguration
      • PrintTree
      • Saving IOptions
      • Yaml
    • Avalanche.Converter
      • Introduction
      • EnumConverter
      • Func<,>
      • HexConverter
      • PrimitiveConverter
      • StringConverter
    • Avalanche.Core
      • License
    • Avalanche.DataType
      • Introduction
      • DataType
        • IDataType
        • IListType
        • IMapType
        • IRecordType
        • IFieldType
        • IOneOfType
        • IAnyType
        • IStringType
        • IValueType
        • IIntegerType
        • IEnumerationType
        • IRealType
      • .Net
        • Introduction
        • IList<T>
        • IDictionary<K,V>
        • FieldInfo
        • Enum
        • OneOfAttribute
        • StructLayoutAttribute
        • Class
      • Protobuf
        • Introduction
      • Articles
        • DataTypeRequest
        • PrintTree
        • DataTypeMessages
    • Avalanche.Emit
      • Introduction
      • TypeBuilder
      • ConstructorBuilder
      • MethodBuilder
      • PropertyBuilder
      • FieldBuilder
      • Emit
      • Utilities
    • Avalanche.FileSystem
      • Introduction
      • Abstractions
        • IFileSystem
          • IFileSystemBrowse
          • IFileSystemCreateDirectory
          • IFileSystemDelete
          • IFileSystemFileAttribute
          • IFileSystemMount
          • IFileSystemMove
          • IFileSystemObserve
          • IFileSystemOpen
        • IEvent
        • IEntry
        • IOption
        • IToken
      • FileSystem
      • VirtualFileSystem
      • MemoryFileSystem
      • EmbeddedFileSystem
      • HttpFileSystem
      • Decoration
      • IFileProvider
      • Events
      • Utilities
        • Dispose
        • File Scanner
        • Visit Tree
        • File Operation
        • FilterEnumerable
        • PollingFilterWatchToken
    • Avalanche.Identity
      • Introduction
      • Identity
      • IdentityParts
      • IdentityInterner
      • IdentityComparer
      • Print Tree
      • IdentityAccessors
        • Introduction
        • TypeName
    • Avalanche.Localization
      • Introduction
      • Localization
      • LocalizationFile
      • LocalizationFiles
      • LocalizationFileSystem
      • LocalizationFileFormat
      • LocalizationLine
      • LocalizationLines
      • TemplateFormat
      • CultureProvider
      • FallbackCultureProvider
      • ResourceManager
      • LocalizationError
      • Microsoft.Extensions
        • Introduction
        • DependencyInjection
        • FileProvider
        • Logging
        • ITextLocalizer
        • IFileLocalizer
        • Localization
      • Asp.Net
        • Introduction
        • Supplying localization
        • Inject to pages
        • Culture Assigned
        • Minimalistic Api
        • Diagnostics
      • Pluralization
        • Introduction
        • Multiple plural parameters
        • Custom PluralRules
        • Invariant Culture
        • Unit Prefix
        • IPluralRule
        • IPluralNumber
        • IPluralRules
        • CLDRs
        • Unicode.CLDR40
        • Unicode.CLDR41
        • Unicode.CLDR42
      • Articles
        • Alphabet localization
        • Benchmarks
        • Caching
        • Class Library
        • Demo
        • Diagnostics
        • Embedded resources
        • Emplacement
        • File localization
        • Text localization
        • Printing templates
    • Avalanche.Message
      • Introduction
      • IMessage
      • IMessageProvider
      • IMessageDescription
      • IMessageDescriptions
      • MessageLevel
      • Message printing
      • Messages and Exceptions
      • Microsoft.Extensions
        • DependencyInjection
      • Articles
        • Aggregate Messages
        • Localization
        • Logging
        • Validation
    • Avalanche.Options
      • Introduction
      • OptionsExtensions
      • OptionsMonitorCast
    • Avalanche.Service
      • Introduction
      • Service
        • Introduction
        • IService
        • IServiceDisposable
        • IServiceDecoration
        • IServiceCast
        • IServiceObservable
        • IServiceContainer
        • Construction
        • Query
        • CancellationToken
        • CachePolicy
        • Scope
      • Handler
        • Introduction
        • IHandler
        • IHandlerCast
        • IHandlerDecoration
        • IHandlerWithOrder
        • CancellationToken
        • Cyclicity
        • Delegates
        • Invokable
        • ExportAttribute
        • OrderAttribute
        • PrintTree
        • Recursion
      • Query
        • Introduction
        • IQuery
        • IQueryCast
        • IQueryDecoration
      • Entry
        • Introduction
        • IEntry
        • IEntryCast
        • IEntryDecoration
        • IEntryObservable
        • IEntryVisitable
        • EntryState
      • Request
        • Introduction
        • IRequest
        • IRequestFor
        • IRequestToBeCached
        • IRequestToBeDisposed
        • RequestAttribute
        • ContextParameterAttribute
        • Print Tree
      • Dependency Injection
        • Introduction
        • Asp.Net
        • ServiceRequest<T>
        • Decorating a service
        • Handler
        • CachePolicy
        • CancellationToken
        • QueryLogger
        • IHostBuilder
      • Examples
        • NodeCount
        • Expression
        • Mapper
      • Articles
        • Benchmarks
        • Error Handling
        • ServiceMessages
    • Avalanche.StatusCode
      • Introduction
      • HResult
        • Introduction
        • HResult.Facilities
        • BasicMessages
        • RpcMessages
        • DispatchMessages
        • StorageMessages
        • ItfMessages
        • Win32Messages
        • WindowsMessages
        • SspiMessages
        • CertMessages
        • MediaServerMessages
        • SetupApiMessages
        • ScardMessages
        • ComPlusMessages
        • ClrMessages
        • UserModeFilterManagerMessages
        • GraphicsMessages
        • TpmServicesMessages
        • TpmSoftwareMessages
        • PlaMessages
        • FveMessages
        • FwpMessages
        • NdisMessages
        • DltMessages
      • System
        • Introduction
        • AccessControlMessages
        • AggregateMessages
        • AppDomainMessages
        • ArgumentMessages
        • ArgumentNullMessages
        • ArgumentOutOfRangeMessages
        • ArithmeticMessages
        • ArrayMessages
        • AssemblyMessages
        • BadImageFormatMessages
        • CodeContractMessages
        • CodePageMessages
        • CollectionsMessages
        • CompilerServiceMessages
        • CryptographyMessages
        • CultureMessages
        • DiagnosticsMessages
        • EventSourceMessages
        • ExecutionEngineMessages
        • FormatMessages
        • HostProtectionMessages
        • IOMessages
        • IndexOutOfRangeMessages
        • InteropServiceMessages
        • InvalidCastMessages
        • InvalidOperationMessages
        • IsolatedStorageMessages
        • LazyMessages
        • MarshalerMessages
        • MemoryMessages
        • MiscellaneousMessages
        • NotImplementedMessages
        • NotSupportedMessages
        • ObjectDisposedMessages
        • OperationCanceledMessages
        • OverflowMessages
        • PlatformMessages
        • PolicyMessages
        • PrincipalMessages
        • ProgramMessages
        • ReferenceMessages
        • ReflectionMessages
        • RegionMessages
        • RemotingMessages
        • ResourcesMessages
        • SecurityMessages
        • SerializationMessages
        • StackMessages
        • TaskMessages
        • TextMessages
        • ThreadingMessages
        • TimeZoneMessages
        • TypeMessages
        • XmlMessages
      • HttpStatusCode
      • OpcUaStatusCode
    • Avalanche.Template
      • Introduction
      • TemplateFormats
      • ITemplatePrintable
      • ITemplateFormatPrintable
      • ITemplateText
      • ITemplateBreakdown
      • ITemplateFormat
      • ITemplateFormats
      • Extract Arguments
      • Emplacement
    • Avalanche.Tokenizer
      • Introduction
      • IToken
      • ITokenizer
      • Tokenizers
    • Avalanche.Utilities
      • Introduction
      • Collections
        • Tuples
        • StructList
        • ArrayList
        • BijectionMap
        • LocakableDictionary
        • LockableList
        • MapList
        • Pipe
        • RingQueue
        • EnumerableExtensions
        • TupleUtilities
        • ArrayUtilities
      • Comparers
        • IGraphComparer
        • IGraphComparable
        • AlphaNumericComparer
        • EnumerableComparer
        • EnumerableGraphComparer
        • ReferenceComparer
        • KeyValuePairComparer
        • DefaultComparerProvider
        • RecordComparer
      • Cloners
        • ICloner
        • IGraphCloner
        • IGraphCloneable
        • ListCloner
        • DictionaryCloner
        • FieldCloner
        • PassthroughCloner
        • RecordCloner
        • ClonerProvider
      • Dispose
        • IDisposeAttachable
        • IDisposeBelatable
      • Provider
        • Introduction
        • ProviderBase
        • Delegate
        • Pipe
        • Cache
        • ResultCapture
        • AsReadOnly
        • AsService
        • IProviderEvent
      • Record
        • IRecordDescription
        • IFieldDescription
        • IConstructorDescription
        • IConstructionDescription
        • IParameterDescription
        • IRecordProviders
        • RecordDelegates
          • RecordCreate
          • RecordClone
          • RecordCopy
          • IRecordDelegates
        • FieldDelegates
          • FieldRead
          • FieldWrite
          • RecreateWith
          • IFieldDelegates
      • Reflection
        • EnumDescription
      • String
        • IEscaper
        • UnicodeString
        • Hex
      • Miscellaneous
        • IIdGenerator
        • Permutation
        • IReadOnly
        • IUserDataContainer
        • ITreeNode
        • Void
    • Avalanche.Writer
      • Introduction
      • ConstantWriter
      • Context
      • ConvertWriter
      • DefaultConstructor
      • DelegateWriter
      • PassthroughWriter
      • Referer
      • TypeCast
      • Writer
      • WriterPipe
      • WriterMessages

    IRecordAccessor from class

    AccessorRequest<NetRecord> requests for record accessor of record-like class and struct types. (Avalanche.Accessor.Net.dll)

    // Create container target
    IContainerTarget target = new NetRecord(typeof(MyClass));
    // Create request
    AccessorRequest request = new AccessorRequest(target);
    // Issue request
    IRecordAccessor<MyClass> accessor =
        Services.Create(NetAccessorHandlers.Instance)
        .GetRequired<IRequest, IRecordAccessor<MyClass>>(request);
    

    Sealed class is processed as Record if requested with NetType IContentTarget. If not sealed, then as Any.

    public sealed record MyClass(int Id, string Label);
    

    RecordAccessorRequest(Type) also requests for IRecordAccessor<T>.

    // Create container target
    IContainerTarget target = new NetRecord(typeof(MyClass));
    // Create request
    RecordAccessorRequest request = new RecordAccessorRequest(target);
    // Issue request
    IRecordAccessor<MyClass> accessor =
        Services.Create(NetAccessorHandlers.Instance)
        .GetRequired<RecordAccessorRequest, IRecordAccessor<MyClass>>(request);
    

    Dependency injection request to IRecordAccessor<> is forwarded as RecordAccessorRequest.

    IServiceProvider service = Services.Create(NetAccessorHandlers.Instance);
    IRecordAccessor<MyClass> accessor = service.GetRequiredService<IRecordAccessor<MyClass>>();
    

    IRecordDescription can be requested with NetRecord target.

    // Create request
    RecordDescriptionRequest request = new RecordDescriptionRequest(new NetRecord(typeof(MyClass)));
    // Issue request
    IRecordDescription description =
        Services.Create(NetAccessorHandlers.Instance)
        .GetRequired<RecordDescriptionRequest, IRecordDescription>(request);
    

    Usage

    .DefaultConstructor creates a record with default value.

    MyClass record = accessor.DefaultConstructor.Read();
    

    .Constructor creates a record from tuple.

    MyClass record = accessor.Constructor.ReadAs<(int id, string label), MyClass>((10, "Hello"));
    

    .Deconstructor reads values as an tuple.

    MyClass record = new MyClass(10, "Hello");
    (int id, string label) = accessor.Deconstructor.ReadAs<MyClass, (int id, string label)>(record);
    

    .Fields contains record fields.

    MyClass record = new MyClass(10, "Hello");
    accessor.Fields[0].Writer.WriteAs<int, MyClass>(11, record);
    int id = accessor.Fields[0].Reader.ReadAs<MyClass, int>(record);
    

    .IsAssigned tests whether a record is assigned in container.

    MyClass record = new MyClass(10, "Hello");
    bool nonNull = accessor.IsAssigned.Read(record);
    

    .Unassign removes record at container.

    MyClass record = new MyClass(10, "Hello");
    accessor.Unassign.Write(default, ref record);
    
    public sealed record MyClass(int Id, string Label);
    
    public record struct MyStruct(int Id, string Label);
    

    Implementation

    The default implementations work for most cases, however, more specific custom implementations can be crafted.

    DefaultConstructor

    Default constructor can be adapted from delegate.

    var myClassDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyClass>(@void => new MyClass(default, default));
    var myStructDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyStruct>(@void => new MyStruct(default, default));
    

    Default constructor can be created with base class.

    /// <summary></summary>
    public class MyClassDefaultConstructor2 : RecordDefaultConstructorBaseClass<MyClass>
    {
        /// <summary></summary>
        public override bool TryWrite(Avalanche.Void from, ref MyClass to, IServiceProvider? context = null)
        {
            to = new MyClass(default, default!);
            return true;
        }
    }
    
    /// <summary></summary>
    public class MyStructDefaultConstructor2 : RecordDefaultConstructorBaseStruct<MyStruct>
    {
        /// <summary></summary>
        public override bool TryWrite(Avalanche.Void from, ref MyStruct to, IServiceProvider? context = null)
        {
            to = new MyStruct(default, default!);
            return true;
        }
    }
    

    Handler processes DefaultConstructorRequest.

    // Create service
    IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassDefaultConstructorBuilder()), CachePolicies.Default);
    // Constructor request
    DefaultConstructorRequest myClassRequest = new DefaultConstructorRequest(new NetRecord(typeof(MyClass)));
    // Get constructor
    IWriterToRef<Avalanche.Void, MyClass> myClassDefaultConstructor =
        service.GetRequired<DefaultConstructorRequest, IWriterToRef<Avalanche.Void, MyClass>>(myClassRequest);
    //
    MyClass myClass = myClassDefaultConstructor.Read();
    
    public class MyClassDefaultConstructorBuilder : IHandler<DefaultConstructorRequest, IWriter>
    {
        [Order(-100)]
        public void Handle(IQuery<DefaultConstructorRequest, IWriter> query)
        {
            // Already handled
            if (query.Handled()) return;
    
            // Place type here
            Type? recordType = null;
            // 
            if (query.Request.Target is IConstructionDescription constructionDescription1)
            {
                recordType = constructionDescription1.Constructor?.Type ?? constructionDescription1.Constructor?.Record?.Type;
            }
            //
            else if (query.Request.Target is IRecordDescription recordDescription1) recordType = recordDescription1?.Type;
            //
            else if (query.Request.Target is Type type1) recordType = type1;
            //
            else return;
    
            // This handler only handles "MyClass"
            if (recordType == null || !recordType.Equals(typeof(MyClass))) return;
            // Assign constructor
            query.Response.SetValue(new MyClassDefaultConstructor2());
    
        }
    }
    

    Constructor

    Constructor can be adapted from delegate.

    var myClassDeconstructor = DelegateWriter.Reader<MyClass, (int, string)>(record => (record.Id, record.Label));
    var myStructDeconstructor = DelegateWriter.Reader<MyStruct, (int, string)>(record => (record.Id, record.Label));
    

    Constructor can be created with base class.

    /// <summary></summary>
    public class MyClassConstructor1 : WriterToRef<(int, string), MyClass>
    {
        /// <summary></summary>
        public override bool TryWrite((int, string) from, ref MyClass to, IServiceProvider? context = null)
        {
            to = new MyClass(from.Item1, from.Item2);
            return true;
        }
    }
    
    /// <summary></summary>
    public class MyStructConstructor1 : WriterToRef<(int, string), MyStruct>
    {
        /// <summary></summary>
        public override bool TryWrite((int, string) from, ref MyStruct to, IServiceProvider? context = null)
        {
            to = new MyStruct(from.Item1, from.Item2);
            return true;
        }
    }
    

    Handler processes ConstructorRequest.

    // Create service
    IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassConstructorBuilder()), CachePolicies.Default);
    // Constructor request
    ConstructorRequest myClassRequest = new ConstructorRequest(new NetRecord(typeof(MyClass)));
    // Get constructor
    IWriterBase<(int, string), MyClass> myClassConstructor =
        service.GetRequired<ConstructorRequest, IWriterBase<(int, string), MyClass>>(myClassRequest);
    //
    MyClass myClass = myClassConstructor.Read((15, "ZYX"));
    
    public class MyClassConstructorBuilder : IHandler<ConstructorRequest, IWriter>
    {
        [Order(-100)]
        public void Handle(IQuery<ConstructorRequest, IWriter> query)
        {
            // Already handled
            if (query.Handled()) return;
    
            // Place type here
            Type? recordType = null;
            // Get record type
            if (query.Request.Target is IRecordDescription recordDescription1) recordType = recordDescription1?.Type;
            else if (query.Request.Target is INetTarget netType1 && netType1.ContainerType is IRecordDescription recordDescription2) recordType = recordDescription2.Type;
            else if (query.Request.Target is INetTarget netType2 && netType2.ContainerType is Type type1) recordType = type1;
            else return;
    
            // This handler only handles "MyClass"
            if (recordType == null || !recordType.Equals(typeof(MyClass))) return;
            // Assign constructor
            query.Response.SetValue(new MyClassConstructor1());
    
        }
    }
    

    Deconstructor

    Deconstructor can be adapted from delegate.

    var myClassDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyClass>(@void => new MyClass(default, default));
    var myStructDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyStruct>(@void => new MyStruct(default, default));
    

    Deconstructor can be created with base class.

    /// <summary></summary>
    public class MyClassDeconstructor1 : WriterToRef<MyClass, (int, string)>
    {
        /// <summary></summary>
        public override bool TryWrite(MyClass from, ref (int, string) to, IServiceProvider? context = null)
        {
            to.Item1 = from.Id;
            to.Item2 = from.Label;
            return true;
        }
    }
    
    /// <summary></summary>
    public class MyStructDeconstructor1 : WriterToRef<MyStruct, (int, string)>
    {
        /// <summary></summary>
        public override bool TryWrite(MyStruct from, ref (int, string) to, IServiceProvider? context = null)
        {
            to.Item1 = from.Id;
            to.Item2 = from.Label;
            return true;
        }
    }
    

    Handler processes DeconstructorRequest.

    // Create service
    IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassDeconstructorBuilder()), CachePolicies.Default);
    // Constructor request
    DeconstructorRequest myClassRequest = new DeconstructorRequest(new NetRecord(typeof(MyClass)));
    // Get deconstructor
    IWriterToRef<MyClass, (int, string)> myClassDeconstructor =
        service.GetRequired<DeconstructorRequest, IWriterToRef<MyClass, (int, string)>>(myClassRequest);
    //
    (int, string) tuple = myClassDeconstructor.Read(new MyClass(80, "A"));
    
    public class MyClassDeconstructorBuilder : IHandler<DeconstructorRequest, IWriter>
    {
        [Order(-100)]
        public void Handle(IQuery<DeconstructorRequest, IWriter> query)
        {
            // Already handled
            if (query.Handled()) return;
    
            // Place type here
            Type? recordType = null;
            // Get record type
            if (query.Request.Target is IRecordDescription recordDescription1) recordType = recordDescription1?.Type;
            else if (query.Request.Target is INetTarget netType1 && netType1.ContainerType is IRecordDescription recordDescription2) recordType = recordDescription2.Type;
            else if (query.Request.Target is INetTarget netType2 && netType2.ContainerType is Type type1) recordType = type1;
            else return;
    
            // This handler only handles "MyClass"
            if (recordType == null || !recordType.Equals(typeof(MyClass))) return;
            // Assign constructor
            query.Response.SetValue(new MyClassDeconstructor1());
        }
    }
    

    Full Example

    Full example
    using System;
    using System.Linq;
    using Avalanche.Accessor;
    using Avalanche.DataType;
    using Avalanche.Service;
    using Avalanche.Utilities;
    using Avalanche.Utilities.Record;
    using Avalanche.Writer;
    using Microsoft.Extensions.DependencyInjection;
    
    public class @class
    {
        public static void Run()
        {
            {
                // <10>
                // Create container target
                IContainerTarget target = new NetRecord(typeof(MyClass));
                // Create request
                AccessorRequest request = new AccessorRequest(target);
                // Issue request
                IRecordAccessor<MyClass> accessor =
                    Services.Create(NetAccessorHandlers.Instance)
                    .GetRequired<IRequest, IRecordAccessor<MyClass>>(request);
                // </10>
            }
            {
                // <11>
                // Create container target
                IContainerTarget target = new NetRecord(typeof(MyClass));
                // Create request
                RecordAccessorRequest request = new RecordAccessorRequest(target);
                // Issue request
                IRecordAccessor<MyClass> accessor =
                    Services.Create(NetAccessorHandlers.Instance)
                    .GetRequired<RecordAccessorRequest, IRecordAccessor<MyClass>>(request);
                // </11>
            }
            {
                // <12>
                // Create request
                RecordDescriptionRequest request = new RecordDescriptionRequest(new NetRecord(typeof(MyClass)));
                // Issue request
                IRecordDescription description =
                    Services.Create(NetAccessorHandlers.Instance)
                    .GetRequired<RecordDescriptionRequest, IRecordDescription>(request);
                // </12>
            }
            {
                // <14>
                IServiceProvider service = Services.Create(NetAccessorHandlers.Instance);
                IRecordAccessor<MyClass> accessor = service.GetRequiredService<IRecordAccessor<MyClass>>();
                // </14>
            }        
            {
                // <15>
                // Create request
                RecordDescriptionRequest request = new RecordDescriptionRequest(new NetRecord(typeof(MyClass)));
                // Issue request
                IRecordDescription description =
                    Services.Create(NetAccessorHandlers.Instance)
                    .GetRequired<RecordDescriptionRequest, IRecordDescription>(request);
                // </15>
            }
            /*
            {
                // <16>
                // Create record
                var record = new { Name = "User", Id = 100 };
                // Issue request
                IRecordAccessor accessor =
                    Services.Create(NetAccessorHandlers.Instance)
                    .GetRequired<IRequest, IRecordAccessor>(new AccessorRequest(new NetRecord(record.GetType())));
                // Read name
                string name = accessor.Fields[0].Reader.TypeCast<object, string>().Read(record);
                // </16>
            }
            */
    
            {
                IRecordAccessor<MyClass> accessor = Services.Create(NetAccessorHandlers.Instance).GetRequiredService<IRecordAccessor<MyClass>>();
                {
                    // <51>
                    MyClass record = accessor.DefaultConstructor.Read();
                    // </51>
                }
                {
                    // <51E>
                    var myClassDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyClass>(@void => new MyClass(default, default));
                    var myStructDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyStruct>(@void => new MyStruct(default, default));
                    // </51E>
                }
                {
                    // <51H>
                    // Create service
                    IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassDefaultConstructorBuilder()), CachePolicies.Default);
                    // Constructor request
                    DefaultConstructorRequest myClassRequest = new DefaultConstructorRequest(new NetRecord(typeof(MyClass)));
                    // Get constructor
                    IWriterToRef<Avalanche.Void, MyClass> myClassDefaultConstructor =
                        service.GetRequired<DefaultConstructorRequest, IWriterToRef<Avalanche.Void, MyClass>>(myClassRequest);
                    //
                    MyClass myClass = myClassDefaultConstructor.Read();
                    // </51H>
                }
                {
                    // <52>
                    MyClass record = accessor.Constructor.ReadAs<(int id, string label), MyClass>((10, "Hello"));
                    // </52>
                }
                {
                    // <52E>
                    var myClassDeconstructor = DelegateWriter.Reader<MyClass, (int, string)>(record => (record.Id, record.Label));
                    var myStructDeconstructor = DelegateWriter.Reader<MyStruct, (int, string)>(record => (record.Id, record.Label));
                    // </52E>
                }
                {
                    // <52H>
                    // Create service
                    IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassConstructorBuilder()), CachePolicies.Default);
                    // Constructor request
                    ConstructorRequest myClassRequest = new ConstructorRequest(new NetRecord(typeof(MyClass)));
                    // Get constructor
                    IWriterBase<(int, string), MyClass> myClassConstructor =
                        service.GetRequired<ConstructorRequest, IWriterBase<(int, string), MyClass>>(myClassRequest);
                    //
                    MyClass myClass = myClassConstructor.Read((15, "ZYX"));
                    // </52H>
                }
                {
                    // <53>
                    MyClass record = new MyClass(10, "Hello");
                    (int id, string label) = accessor.Deconstructor.ReadAs<MyClass, (int id, string label)>(record);
                    // </53>
                }
                {
                    // <53E>
                    var myClassDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyClass>(@void => new MyClass(default, default));
                    var myStructDefaultConstructor = DelegateWriter.Reader<Avalanche.Void, MyStruct>(@void => new MyStruct(default, default));
                    // </53E>
                }
                {
                    // <53H>
                    // Create service
                    IService service = Services.Create((NetAccessorHandlers.Instance, new MyClassDeconstructorBuilder()), CachePolicies.Default);
                    // Constructor request
                    DeconstructorRequest myClassRequest = new DeconstructorRequest(new NetRecord(typeof(MyClass)));
                    // Get deconstructor
                    IWriterToRef<MyClass, (int, string)> myClassDeconstructor =
                        service.GetRequired<DeconstructorRequest, IWriterToRef<MyClass, (int, string)>>(myClassRequest);
                    //
                    (int, string) tuple = myClassDeconstructor.Read(new MyClass(80, "A"));
                    // </53H>
                }
                {
                    // <54>
                    MyClass record = new MyClass(10, "Hello");
                    accessor.Fields[0].Writer.WriteAs<int, MyClass>(11, record);
                    int id = accessor.Fields[0].Reader.ReadAs<MyClass, int>(record);
                    // </54>
                }
                {
                    // <62>
                    MyClass record = new MyClass(10, "Hello");
                    bool nonNull = accessor.IsAssigned.Read(record);
                    // </62>
                }
                {
                    // <63>
                    MyClass record = new MyClass(10, "Hello");
                    accessor.Unassign.Write(default, ref record);
                    // </63>
                }
            }
    
        }
    
        // <51F>
        /// <summary></summary>
        public class MyClassDefaultConstructor2 : RecordDefaultConstructorBaseClass<MyClass>
        {
            /// <summary></summary>
            public override bool TryWrite(Avalanche.Void from, ref MyClass to, IServiceProvider? context = null)
            {
                to = new MyClass(default, default!);
                return true;
            }
        }
    
        /// <summary></summary>
        public class MyStructDefaultConstructor2 : RecordDefaultConstructorBaseStruct<MyStruct>
        {
            /// <summary></summary>
            public override bool TryWrite(Avalanche.Void from, ref MyStruct to, IServiceProvider? context = null)
            {
                to = new MyStruct(default, default!);
                return true;
            }
        }
        // </51F>
        // <51G>
        public class MyClassDefaultConstructorBuilder : IHandler<DefaultConstructorRequest, IWriter>
        {
            [Order(-100)]
            public void Handle(IQuery<DefaultConstructorRequest, IWriter> query)
            {
                // Already handled
                if (query.Handled()) return;
    
                // Place type here
                Type? recordType = null;
                // 
                if (query.Request.Target is IConstructionDescription constructionDescription1)
                {
                    recordType = constructionDescription1.Constructor?.Type ?? constructionDescription1.Constructor?.Record?.Type;
                }
                //
                else if (query.Request.Target is IRecordDescription recordDescription1) recordType = recordDescription1?.Type;
                //
                else if (query.Request.Target is Type type1) recordType = type1;
                //
                else return;
    
                // This handler only handles "MyClass"
                if (recordType == null || !recordType.Equals(typeof(MyClass))) return;
                // Assign constructor
                query.Response.SetValue(new MyClassDefaultConstructor2());
    
            }
        }
        // </51G>
    
        // <52F>
        /// <summary></summary>
        public class MyClassConstructor1 : WriterToRef<(int, string), MyClass>
        {
            /// <summary></summary>
            public override bool TryWrite((int, string) from, ref MyClass to, IServiceProvider? context = null)
            {
                to = new MyClass(from.Item1, from.Item2);
                return true;
            }
        }
    
        /// <summary></summary>
        public class MyStructConstructor1 : WriterToRef<(int, string), MyStruct>
        {
            /// <summary></summary>
            public override bool TryWrite((int, string) from, ref MyStruct to, IServiceProvider? context = null)
            {
                to = new MyStruct(from.Item1, from.Item2);
                return true;
            }
        }
        // </52F>
        // <52G>
        public class MyClassConstructorBuilder : IHandler<ConstructorRequest, IWriter>
        {
            [Order(-100)]
            public void Handle(IQuery<ConstructorRequest, IWriter> query)
            {
                // Already handled
                if (query.Handled()) return;
    
                // Place type here
                Type? recordType = null;
                // Get record type
                if (query.Request.Target is IRecordDescription recordDescription1) recordType = recordDescription1?.Type;
                else if (query.Request.Target is INetTarget netType1 && netType1.ContainerType is IRecordDescription recordDescription2) recordType = recordDescription2.Type;
                else if (query.Request.Target is INetTarget netType2 && netType2.ContainerType is Type type1) recordType = type1;
                else return;
    
                // This handler only handles "MyClass"
                if (recordType == null || !recordType.Equals(typeof(MyClass))) return;
                // Assign constructor
                query.Response.SetValue(new MyClassConstructor1());
    
            }
        }
        // </52G>
    
        // <53F>
        /// <summary></summary>
        public class MyClassDeconstructor1 : WriterToRef<MyClass, (int, string)>
        {
            /// <summary></summary>
            public override bool TryWrite(MyClass from, ref (int, string) to, IServiceProvider? context = null)
            {
                to.Item1 = from.Id;
                to.Item2 = from.Label;
                return true;
            }
        }
    
        /// <summary></summary>
        public class MyStructDeconstructor1 : WriterToRef<MyStruct, (int, string)>
        {
            /// <summary></summary>
            public override bool TryWrite(MyStruct from, ref (int, string) to, IServiceProvider? context = null)
            {
                to.Item1 = from.Id;
                to.Item2 = from.Label;
                return true;
            }
        }
        // </53F>
        // <53G>
        public class MyClassDeconstructorBuilder : IHandler<DeconstructorRequest, IWriter>
        {
            [Order(-100)]
            public void Handle(IQuery<DeconstructorRequest, IWriter> query)
            {
                // Already handled
                if (query.Handled()) return;
    
                // Place type here
                Type? recordType = null;
                // Get record type
                if (query.Request.Target is IRecordDescription recordDescription1) recordType = recordDescription1?.Type;
                else if (query.Request.Target is INetTarget netType1 && netType1.ContainerType is IRecordDescription recordDescription2) recordType = recordDescription2.Type;
                else if (query.Request.Target is INetTarget netType2 && netType2.ContainerType is Type type1) recordType = type1;
                else return;
    
                // This handler only handles "MyClass"
                if (recordType == null || !recordType.Equals(typeof(MyClass))) return;
                // Assign constructor
                query.Response.SetValue(new MyClassDeconstructor1());
            }
        }
        // </53G>
    
        // <100>
        public sealed record MyClass(int Id, string Label);
        // </100>
        // <101>
        public record struct MyStruct(int Id, string Label);
        // </101>
    }
    
    In This Article
    Back to top Copyright © Toni Kalajainen