-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
101 lines (88 loc) · 3.16 KB
/
Copy pathProgram.cs
File metadata and controls
101 lines (88 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
namespace ExpressionTreesExample
{
class Program
{
static void Main()
{
var cities = new List<City>(Enumerable.Range(0, 30).Select(x => new City { ru_Name = $"ru{x}", en_Name = $"en{x * 2}" }))
.AsQueryable();
var exprVisitor = new ExprVisitor();
var filter = "1";
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("ru");
var query = cities
.Where(x => x.Name.Contains(filter))
.Visit(exprVisitor); // changing query here
foreach (var city in query)
Console.WriteLine(city.Name);
Console.ReadLine();
}
}
public class City
{
[ExpressionLocalizable]
public string Name
{
get
{
switch (Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName)
{
case "ru":
return ru_Name;
case "en":
return en_Name;
default:
throw new NotSupportedException("Language is not supported");
}
}
set
{
switch (Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName)
{
case "ru":
ru_Name = value;
break;
case "en":
en_Name = value;
break;
default:
throw new NotSupportedException("Language is not supported");
}
}
}
public string ru_Name { get; set; }
public string en_Name { get; set; }
}
[AttributeUsage(AttributeTargets.Property)]
public class ExpressionLocalizableAttribute : Attribute { }
public class ExprVisitor : ExpressionVisitor
{
protected override Expression VisitMember(MemberExpression node)
{
if (node.Member.GetCustomAttribute<ExpressionLocalizableAttribute>() == null)
return base.VisitMember(node);
var nodeType = node.Expression.Type;
var localizedPropertyName = $"{Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName}_{node.Member.Name}";
var property = nodeType.GetProperty(localizedPropertyName);
if (property == null)
{
throw new NotSupportedException($"No such property '{localizedPropertyName}' in type '{nodeType.Name}'!");
}
return Expression.MakeMemberAccess(node.Expression, property);
}
}
public static class QueryExtensions
{
public static IQueryable<TResult> Visit<TResult>(this IQueryable<TResult> query, ExpressionVisitor visitor)
{
var expr = visitor.Visit(query.Expression);
return query.Provider.CreateQuery<TResult>(expr);
}
}
}