1 #Region "Microsoft.VisualBasic::2c7b689e041bbd11e16644e14e0004a8, Microsoft.VisualBasic.Core\ComponentModel\DataSource\Property\DynamicProperty.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class DynamicPropertyBase
35     
36     '         Properties: MyHashCode, Properties
37     
38     '         FunctionEnumerateKeys, HasProperty, ToString
39     
40     
41     ' /********************************************************************************/
42
43 #End Region
44
45 Imports System.Runtime.CompilerServices
46 Imports System.Xml.Serialization
47 Imports Microsoft.VisualBasic.Language
48 Imports Microsoft.VisualBasic.Linq
49
50 Namespace ComponentModel.DataSourceModel
51
52     ''' <summary>
53     ''' This abstract object has a <see cref="propertyTable"/> dictionary keeps as 
54     ''' a dynamics property source.
55     ''' </summary>
56     ''' <typeparam name="T"></typeparam>
57     Public MustInherit Class DynamicPropertyBase(Of T)
58         Implements IDynamicMeta(Of T)
59
60         ''' <summary>
61         ''' The dynamics property object with specific type of value.
62         ''' </summary>
63         ''' <returns></returns>
64         ''' <remarks>Can not serialize the dictionary object in to xml document.</remarks>
65         <XmlIgnore> Public Overridable Property Properties As Dictionary(Of String, T) Implements IDynamicMeta(Of T).Properties
66             Get
67                 If propertyTable Is Nothing Then
68                     propertyTable = New Dictionary(Of String, T)
69                 End If
70                 Return propertyTable
71             End Get
72             Set(value As Dictionary(Of String, T))
73                 propertyTable = value
74             End Set
75         End Property
76
77         ''' <summary>
78         ''' 动态属性表
79         ''' </summary>
80         Dim propertyTable As Dictionary(Of String, T)
81
82         ''' <summary>
83         ''' Gets/sets item value by using property name.
84         ''' (这个函数为安全的函数,当目标属性不存在的时候,会返回空值)
85         ''' </summary>
86         ''' <param name="name"></param>
87         ''' <returns></returns>
88         Default Public Overloads Property ItemValue(name$) As T
89             <MethodImpl(MethodImplOptions.AggressiveInlining)>
90             Get
91                 If Properties.ContainsKey(name) Then
92                     Return Properties(name)
93                 Else
94                     Return Nothing
95                 End If
96             End Get
97             Set(value As T)
98                 Properties(name) = value
99             End Set
100         End Property
101
102         ''' <summary>
103         ''' Get a value package at once using a key collection, 
104         ''' if the key is not exists in the property, then its 
105         ''' correspoding value is nothing.
106         ''' </summary>
107         ''' <param name="keys"></param>
108         ''' <returns></returns>
109         Default Public Overloads Property ItemValue(keys As IEnumerable(Of String)) As T()
110             <MethodImpl(MethodImplOptions.AggressiveInlining)>
111             Get
112                 Return keys.Select(Function(s) Me(s)).ToArray
113             End Get
114             Set(value As T())
115                 For Each key As SeqValue(Of StringIn keys.SeqIterator
116                     Me(key.value) = value(key)
117                 Next
118             End Set
119         End Property
120
121         ''' <summary>
122         ''' Determines whether the System.Collections.Generic.Dictionary`2 contains the specified
123         ''' key.
124         ''' </summary>
125         ''' <param name="name$">The key to locate in the System.Collections.Generic.Dictionary`2.</param>
126         ''' <returns>
127         ''' true if the System.Collections.Generic.Dictionary`2 contains an element with
128         ''' the specified key; otherwise, false.
129         ''' </returns>
130         Public Function HasProperty(name$) As Boolean
131             If propertyTable Is Nothing Then
132                 Return False
133             Else
134                 Return propertyTable.ContainsKey(name)
135             End If
136         End Function
137
138         ''' <summary>
139         ''' 枚举这个动态字典类型之中的所有的键名,这个函数是默认不包含有类型自有的属性名称的
140         ''' </summary>
141         ''' <param name="joinProperties">是否包括属性名称,默认不包含</param>
142         ''' <returns></returns>
143         Public Function EnumerateKeys(Optional joinProperties As Boolean = FalseAs String()
144             Dim out As New List(Of String)
145
146             If joinProperties Then
147                 out += MyClass.GetType _
148                     .GetProperties(PublicProperty) _
149                     .Where(Function(p) p.GetIndexParameters.IsNullOrEmpty) _
150                     .Select(Function(p) p.Name) _
151                     .ToArray
152             End If
153
154             If Not propertyTable Is Nothing Then
155                 out += propertyTable.Keys
156             End If
157
158             Return out.Distinct.ToArray
159         End Function
160
161         Public Overrides Function ToString() As String
162             Return $"{Properties.Count} Property(s)."
163         End Function
164
165         ''' <summary>
166         ''' Using for debugger view, this property is usually usefull for the dictionary view 
167         ''' to see if any duplicated was existed? 
168         ''' </summary>
169         ''' <returns></returns>
170         Protected Overridable ReadOnly Property MyHashCode As Integer
171             <MethodImpl(MethodImplOptions.AggressiveInlining)>
172             Get
173                 Return GetHashCode()
174             End Get
175         End Property
176
177         <MethodImpl(MethodImplOptions.AggressiveInlining)>
178         Public Shared Narrowing Operator CType(dynamic As DynamicPropertyBase(Of T)) As Func(Of String, T)
179             Return Function(pName$) dynamic(pName)
180         End Operator
181     End Class
182 End Namespace