@@ -77,40 +77,103 @@ public static BotControllerHandlers MakeHandlers()
77
77
. OrderBy ( c => c . on . Filter == null )
78
78
. ThenByDescending ( c => c . on . Order )
79
79
80
- . Select ( c => new HandlerItem ( c . on . Handler , c . m , GetFilter ( c . m , c . on . Filter ) ) ) ;
80
+ . Select ( c => new HandlerItem ( c . on . Handler , c . m , GetFilter ( c . m , c . on ) ) ) ;
81
81
82
82
return new BotControllerHandlers ( handlers ) ;
83
83
84
- static ActionFilter ? GetFilter ( MethodInfo target , string ? filterMethod )
84
+ static ActionFilter ? GetFilter ( MethodInfo target , OnAttribute on )
85
85
{
86
- if ( filterMethod == null )
86
+ var filters = target . GetCustomAttributes < FilterAttribute > ( ) . ToArray ( ) ;
87
+
88
+ if ( filters . Length == 0 && on . Filter == null )
87
89
{
88
90
return null ;
89
91
}
90
92
91
- if ( filterMethod . Contains ( '.' ) )
93
+ if ( filters . Length != 0 && on . Filter != null )
92
94
{
93
- var typeName = filterMethod . Substring ( 0 , filterMethod . LastIndexOf ( '.' ) ) ;
94
- var methodName = filterMethod . Substring ( filterMethod . LastIndexOf ( '.' ) + 1 ) ;
95
+ throw new BotfException ( "Use only Filter() attribute to pass filter methods of handlers" ) ;
96
+ }
95
97
96
- var type = Type . GetType ( typeName ) ;
97
- if ( type == null )
98
- {
99
- throw new BotfException ( $ "Filter method name is wrong. Can't find class type `{ typeName } `. Action method is `{ target . DeclaringType ! . Name } .{ target . Name } `") ;
100
- }
98
+ if ( on . Filter != null )
99
+ {
100
+ var methodInTarget = FilterAttribute . GetMethod ( on . Filter , target . DeclaringType ) ;
101
+ CheckFilterMethod ( methodInTarget , on . Filter , target . DeclaringType ! . Name ) ;
102
+ return ( ActionFilter ) ActionFilter . CreateDelegate ( typeof ( ActionFilter ) , methodInTarget ! ) ;
103
+ }
104
+
105
+ if ( filters . Length == 0 )
106
+ {
107
+ return null ;
108
+ }
101
109
102
- var method = type . GetMethod ( methodName , BindingFlags . Static | BindingFlags . Public | BindingFlags . NonPublic ) ;
103
- CheckFilterMethod ( method , methodName , typeName , target ) ;
110
+ ActionFilter ? result = null ;
111
+
112
+ for ( int i = 0 ; i < filters . Length ; i ++ )
113
+ {
114
+ var filter = filters [ i ] ;
115
+ var method = filter . GetMethod ( target . DeclaringType ) ;
116
+ CheckFilterMethod ( method , filter . Filter , target . DeclaringType ! . Name ) ;
117
+ var action = ( ActionFilter ) ActionFilter . CreateDelegate ( typeof ( ActionFilter ) , method ! ) ;
104
118
105
- return ( ActionFilter ) ActionFilter . CreateDelegate ( typeof ( ActionFilter ) , method ! ) ;
119
+ if ( result == null )
120
+ {
121
+ if ( filter . Operation == FilterAttribute . BoolOp . Not )
122
+ {
123
+ result = ( IUpdateContext ctx ) =>
124
+ {
125
+ ctx . SetFilterParameter ( filter . Param ) ;
126
+ return ! action ( ctx ) ;
127
+ } ;
128
+ }
129
+ else
130
+ {
131
+ result = ( IUpdateContext ctx ) =>
132
+ {
133
+ ctx . SetFilterParameter ( filter . Param ) ;
134
+ return action ( ctx ) ;
135
+ } ;
136
+ }
137
+ }
138
+ else
139
+ {
140
+ var currentResult = result ;
141
+ result = ( IUpdateContext ctx ) =>
142
+ {
143
+ var leftResult = currentResult ( ctx ) ;
144
+
145
+ ctx . SetFilterParameter ( filter . Param ) ;
146
+ var rightResult = action ( ctx ) ;
147
+
148
+ if ( filter . Operation == FilterAttribute . BoolOp . And )
149
+ {
150
+ return leftResult && rightResult ;
151
+ }
152
+ else if ( filter . Operation == FilterAttribute . BoolOp . Or )
153
+ {
154
+ return leftResult || rightResult ;
155
+ }
156
+ else if ( filter . Operation == FilterAttribute . BoolOp . AndNot )
157
+ {
158
+ return leftResult && ! rightResult ;
159
+ }
160
+ else if ( filter . Operation == FilterAttribute . BoolOp . OrNot )
161
+ {
162
+ return leftResult || ! rightResult ;
163
+ }
164
+ else if ( filter . Operation == FilterAttribute . BoolOp . Not )
165
+ {
166
+ throw new NotSupportedException ( $ "Operation NOT is supported only for first filter") ;
167
+ }
168
+
169
+ throw new NotSupportedException ( $ "Operation type { filter . Operation } is not supported") ;
170
+ } ;
171
+ }
106
172
}
107
-
108
- var methodInTarget = target . DeclaringType ! . GetMethod ( filterMethod , BindingFlags . Static | BindingFlags . Public | BindingFlags . NonPublic ) ;
109
- CheckFilterMethod ( methodInTarget , filterMethod , target . DeclaringType . Name , target ) ;
110
173
111
- return ( ActionFilter ) ActionFilter . CreateDelegate ( typeof ( ActionFilter ) , methodInTarget ! ) ;
174
+ return result ;
112
175
113
- static void CheckFilterMethod ( MethodInfo ? filter , string methodName , string typeName , MethodInfo target )
176
+ static void CheckFilterMethod ( MethodInfo ? filter , string methodName , string typeName )
114
177
{
115
178
if ( filter == null
116
179
|| filter . ReturnType != typeof ( bool )
0 commit comments