2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq.Expressions;
5 using System.Reflection;
6 using System.Reflection.Emit;
7 using System.Security.Permissions;
9 using System.Runtime.CompilerServices;
11 namespace System.Data.Linq.Mapping {
12 using System.Data.Linq.Provider;
13 using System.Diagnostics.CodeAnalysis;
15 internal delegate V DGet<T, V>(T t);
16 internal delegate void DSet<T, V>(T t, V v);
17 internal delegate void DRSet<T, V>(ref T t, V v);
19 internal static class FieldAccessor {
21 [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
22 internal static MetaAccessor Create(Type objectType, FieldInfo fi) {
23 if (!fi.ReflectedType.IsAssignableFrom(objectType))
24 throw Error.InvalidFieldInfo(objectType, fi.FieldType, fi);
26 Delegate drset = null;
28 if (!objectType.IsGenericType) {
29 DynamicMethod mget = new DynamicMethod(
32 new Type[] { objectType },
35 ILGenerator gen = mget.GetILGenerator();
36 gen.Emit(OpCodes.Ldarg_0);
37 gen.Emit(OpCodes.Ldfld, fi);
38 gen.Emit(OpCodes.Ret);
39 dget = mget.CreateDelegate(typeof(DGet<,>).MakeGenericType(objectType, fi.FieldType));
41 DynamicMethod mset = new DynamicMethod(
44 new Type[] { objectType.MakeByRefType(), fi.FieldType },
47 gen = mset.GetILGenerator();
48 gen.Emit(OpCodes.Ldarg_0);
49 if (!objectType.IsValueType) {
50 gen.Emit(OpCodes.Ldind_Ref);
52 gen.Emit(OpCodes.Ldarg_1);
53 gen.Emit(OpCodes.Stfld, fi);
54 gen.Emit(OpCodes.Ret);
55 drset = mset.CreateDelegate(typeof(DRSet<,>).MakeGenericType(objectType, fi.FieldType));
57 return (MetaAccessor)Activator.CreateInstance(
58 typeof(Accessor<,>).MakeGenericType(objectType, fi.FieldType),
59 BindingFlags.Instance | BindingFlags.NonPublic, null,
60 new object[] { fi, dget, drset }, null
64 class Accessor<T, V> : MetaAccessor<T, V> {
69 internal Accessor(FieldInfo fi, DGet<T, V> dget, DRSet<T, V> drset) {
74 public override V GetValue(T instance) {
75 if (this.dget != null)
76 return this.dget(instance);
77 return (V)fi.GetValue(instance);
79 public override void SetValue(ref T instance, V value) {
80 if (this.drset != null)
81 this.drset(ref instance, value);
83 this.fi.SetValue(instance, value);
88 internal static class PropertyAccessor {
90 internal static MetaAccessor Create(Type objectType, PropertyInfo pi, MetaAccessor storageAccessor) {
92 Delegate drset = null;
93 Type dgetType = typeof(DGet<,>).MakeGenericType(objectType, pi.PropertyType);
94 MethodInfo getMethod = pi.GetGetMethod(true);
96 Delegate dget = Delegate.CreateDelegate(dgetType, getMethod, true);
98 throw Error.CouldNotCreateAccessorToProperty(objectType, pi.PropertyType, pi);
102 if (!objectType.IsValueType) {
103 dset = Delegate.CreateDelegate(typeof(DSet<,>).MakeGenericType(objectType, pi.PropertyType), pi.GetSetMethod(true), true);
106 DynamicMethod mset = new DynamicMethod(
109 new Type[] { objectType.MakeByRefType(), pi.PropertyType },
112 ILGenerator gen = mset.GetILGenerator();
113 gen.Emit(OpCodes.Ldarg_0);
114 if (!objectType.IsValueType) {
115 gen.Emit(OpCodes.Ldind_Ref);
117 gen.Emit(OpCodes.Ldarg_1);
118 gen.Emit(OpCodes.Call, pi.GetSetMethod(true));
119 gen.Emit(OpCodes.Ret);
120 drset = mset.CreateDelegate(typeof(DRSet<,>).MakeGenericType(objectType, pi.PropertyType));
124 Type saType = (storageAccessor != null) ? storageAccessor.Type : pi.PropertyType;
125 return (MetaAccessor)Activator.CreateInstance(
126 typeof(Accessor<,,>).MakeGenericType(objectType, pi.PropertyType, saType),
127 BindingFlags.Instance|BindingFlags.NonPublic, null,
128 new object[] {pi, dget, dset, drset, storageAccessor}, null
133 class Accessor<T,V, V2> : MetaAccessor<T,V> where V2 : V {
138 MetaAccessor<T, V2> storage;
140 internal Accessor(PropertyInfo pi, DGet<T, V> dget, DSet<T, V> dset, DRSet<T, V> drset, MetaAccessor<T,V2> storage) {
145 this.storage = storage;
147 public override V GetValue(T instance) {
148 return this.dget(instance);
150 public override void SetValue(ref T instance, V value) {
151 if (this.dset != null) {
152 this.dset(instance, value);
154 else if (this.drset != null) {
155 this.drset(ref instance, value);
157 else if (this.storage != null) {
158 this.storage.SetValue(ref instance, (V2)value);
161 throw Error.UnableToAssignValueToReadonlyProperty(this.pi);
167 // deferred type accessors
168 internal class LinkValueAccessor<T, V> : MetaAccessor<T, V> {
169 MetaAccessor<T, Link<V>> acc;
170 internal LinkValueAccessor(MetaAccessor<T, Link<V>> acc) {
173 public override bool HasValue(object instance) {
174 Link<V> link = this.acc.GetValue((T)instance);
175 return link.HasValue;
177 public override bool HasAssignedValue(object instance) {
178 Link<V> link = this.acc.GetValue((T)instance);
179 return link.HasAssignedValue;
181 public override bool HasLoadedValue(object instance) {
182 Link<V> link = this.acc.GetValue((T)instance);
183 return link.HasLoadedValue;
185 public override V GetValue(T instance) {
186 Link<V> link = this.acc.GetValue(instance);
189 public override void SetValue(ref T instance, V value) {
190 this.acc.SetValue(ref instance, new Link<V>(value));
194 internal class LinkDefValueAccessor<T, V> : MetaAccessor<T, V> {
195 MetaAccessor<T, Link<V>> acc;
196 internal LinkDefValueAccessor(MetaAccessor<T, Link<V>> acc) {
199 public override V GetValue(T instance) {
200 Link<V> link = this.acc.GetValue(instance);
201 return link.UnderlyingValue;
203 public override void SetValue(ref T instance, V value) {
204 this.acc.SetValue(ref instance, new Link<V>(value));
208 internal class LinkDefSourceAccessor<T, V> : MetaAccessor<T, IEnumerable<V>> {
209 MetaAccessor<T, Link<V>> acc;
210 internal LinkDefSourceAccessor(MetaAccessor<T, Link<V>> acc) {
213 public override IEnumerable<V> GetValue(T instance) {
214 Link<V> link = this.acc.GetValue(instance);
215 return (IEnumerable<V>)link.Source;
217 public override void SetValue(ref T instance, IEnumerable<V> value) {
218 Link<V> link = this.acc.GetValue(instance);
219 if (link.HasAssignedValue || link.HasLoadedValue) {
220 throw Error.LinkAlreadyLoaded();
222 this.acc.SetValue(ref instance, new Link<V>(value));
226 internal class EntityRefValueAccessor<T, V> : MetaAccessor<T, V> where V : class {
227 MetaAccessor<T, EntityRef<V>> acc;
228 internal EntityRefValueAccessor(MetaAccessor<T, EntityRef<V>> acc) {
231 public override V GetValue(T instance) {
232 EntityRef<V> er = this.acc.GetValue(instance);
235 public override void SetValue(ref T instance, V value) {
236 this.acc.SetValue(ref instance, new EntityRef<V>(value));
238 public override bool HasValue(object instance) {
239 EntityRef<V> er = this.acc.GetValue((T)instance);
242 public override bool HasAssignedValue(object instance) {
243 EntityRef<V> er = this.acc.GetValue((T)instance);
244 return er.HasAssignedValue;
246 public override bool HasLoadedValue(object instance) {
247 EntityRef<V> er = this.acc.GetValue((T)instance);
248 return er.HasLoadedValue;
252 internal class EntityRefDefValueAccessor<T, V> : MetaAccessor<T, V> where V : class {
253 MetaAccessor<T, EntityRef<V>> acc;
254 internal EntityRefDefValueAccessor(MetaAccessor<T, EntityRef<V>> acc) {
257 public override V GetValue(T instance) {
258 EntityRef<V> er = this.acc.GetValue(instance);
259 return er.UnderlyingValue;
261 public override void SetValue(ref T instance, V value) {
262 this.acc.SetValue(ref instance, new EntityRef<V>(value));
266 internal class EntityRefDefSourceAccessor<T, V> : MetaAccessor<T, IEnumerable<V>> where V : class {
267 MetaAccessor<T, EntityRef<V>> acc;
268 internal EntityRefDefSourceAccessor(MetaAccessor<T, EntityRef<V>> acc) {
271 public override IEnumerable<V> GetValue(T instance) {
272 EntityRef<V> er = this.acc.GetValue(instance);
273 return (IEnumerable<V>)er.Source;
275 public override void SetValue(ref T instance, IEnumerable<V> value) {
276 EntityRef<V> er = this.acc.GetValue(instance);
277 if (er.HasAssignedValue || er.HasLoadedValue) {
278 throw Error.EntityRefAlreadyLoaded();
280 this.acc.SetValue(ref instance, new EntityRef<V>(value));
284 internal class EntitySetValueAccessor<T, V> : MetaAccessor<T, EntitySet<V>> where V : class {
285 MetaAccessor<T, EntitySet<V>> acc;
286 internal EntitySetValueAccessor(MetaAccessor<T, EntitySet<V>> acc) {
289 public override EntitySet<V> GetValue(T instance) {
290 return this.acc.GetValue(instance);
292 public override void SetValue(ref T instance, EntitySet<V> value) {
293 EntitySet<V> eset = this.acc.GetValue(instance);
295 eset = new EntitySet<V>();
296 this.acc.SetValue(ref instance, eset);
300 public override bool HasValue(object instance) {
301 EntitySet<V> es = this.acc.GetValue((T)instance);
302 return es != null && es.HasValues;
304 public override bool HasAssignedValue(object instance) {
305 EntitySet<V> es = this.acc.GetValue((T)instance);
306 return es != null && es.HasAssignedValues;
308 public override bool HasLoadedValue(object instance) {
309 EntitySet<V> es = this.acc.GetValue((T)instance);
310 return es != null && es.HasLoadedValues;
314 internal class EntitySetDefValueAccessor<T, V> : MetaAccessor<T, IEnumerable<V>> where V : class {
315 MetaAccessor<T, EntitySet<V>> acc;
316 internal EntitySetDefValueAccessor(MetaAccessor<T, EntitySet<V>> acc) {
319 public override IEnumerable<V> GetValue(T instance) {
320 EntitySet<V> eset = this.acc.GetValue(instance);
321 return eset.GetUnderlyingValues();
323 public override void SetValue(ref T instance, IEnumerable<V> value) {
324 EntitySet<V> eset = this.acc.GetValue(instance);
326 eset = new EntitySet<V>();
327 this.acc.SetValue(ref instance, eset);
333 internal class EntitySetDefSourceAccessor<T, V> : MetaAccessor<T, IEnumerable<V>> where V : class {
334 MetaAccessor<T, EntitySet<V>> acc;
335 internal EntitySetDefSourceAccessor(MetaAccessor<T, EntitySet<V>> acc) {
338 public override IEnumerable<V> GetValue(T instance) {
339 EntitySet<V> eset = this.acc.GetValue(instance);
340 return (IEnumerable<V>)eset.Source;
342 public override void SetValue(ref T instance, IEnumerable<V> value) {
343 EntitySet<V> eset = this.acc.GetValue(instance);
345 eset = new EntitySet<V>();
346 this.acc.SetValue(ref instance, eset);
348 eset.SetSource(value);