diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Castle.Core.csproj nmock3-62490\MAIN\Source\Castle\Castle.Core.csproj --- nmock3-62490-original\MAIN\Source\Castle\Castle.Core.csproj Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Castle.Core.csproj Sun Feb 13 18:56:53 2011 @@ -0,0 +1,629 @@ + + + + $(MSBuildProjectDirectory)\..\.. + v4.0 + Client + + + NET40-Debug + AnyCPU + 9.0.30729 + 2.0 + {E4FA5B53-7D36-429E-8E5C-53D5479242BA} + Library + Properties + Castle + Castle.Core + true + ..\..\buildscripts\CastleKey.snk + + + + + v4.0 + Client + bin\NET40-Debug\ + true + full + false + TRACE;DEBUG;PHYSICALASSEMBLY DOTNET DOTNET40 CLIENTPROFILE + prompt + 4 + true + + + 1591 + true + + + v4.0 + Client + bin\NET40-Release\ + pdbonly + true + TRACE;PHYSICALASSEMBLY DOTNET DOTNET40 CLIENTPROFILE + prompt + 4 + bin\NET40-Release\Castle.Core.xml + 1591 + true + + + v3.5 + + + bin\NET35-Debug\ + TRACE;DEBUG;PHYSICALASSEMBLY DOTNET DOTNET35 + + + true + true + 1591 + pdbonly + AnyCPU + prompt + true + + + v3.5 + + + bin\NET35-Release\ + TRACE;PHYSICALASSEMBLY DOTNET DOTNET35 + bin\NET35-Release\Castle.Core.xml + true + true + 1591 + pdbonly + AnyCPU + prompt + + + v4.0 + + + Silverlight 4.0 + bin\SL40-Release\ + TRACE;PHYSICALASSEMBLY SILVERLIGHT SL4 + bin\SL40-Release\Castle.Core.xml + true + true + 1591 1685 + pdbonly + AnyCPU + prompt + + + v4.0 + + + Silverlight 4.0 + true + bin\SL40-Debug\ + TRACE;DEBUG;PHYSICALASSEMBLY SILVERLIGHT SL4 + + + true + 1591 1685 + full + AnyCPU + prompt + + + + + true + bin\SL30-Debug\ + TRACE;DEBUG;PHYSICALASSEMBLY SILVERLIGHT SL3 + + + true + 1591 1685 + full + AnyCPU + prompt + + + + + bin\SL30-Release\ + TRACE;PHYSICALASSEMBLY SILVERLIGHT SL3 + bin\SL30-Release\Castle.Core.xml + true + true + 1591 1685 + pdbonly + AnyCPU + prompt + + + + + bin\MONO26-Debug\ + TRACE;DEBUG;PHYSICALASSEMBLY MONO MONO26 + bin\MONO26-Debug\Castle.Core.xml + false + full + true + 1591 + AnyCPU + prompt + true + + + + + bin\MONO26-Release\ + TRACE;PHYSICALASSEMBLY MONO MONO26 + bin\MONO26-Release\Castle.Core.xml + true + pdbonly + true + 1591 + AnyCPU + + + + + bin\MONO28-Debug\ + TRACE;DEBUG;PHYSICALASSEMBLY MONO MONO28 + bin\MONO28-Debug\Castle.Core.xml + false + full + true + 1591 + AnyCPU + prompt + true + + + + + bin\MONO28-Release\ + TRACE;PHYSICALASSEMBLY MONO MONO28 + bin\MONO28-Release\Castle.Core.xml + true + pdbonly + true + 1591 + AnyCPU + + + + + + + + + + + + CommonAssemblyInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + Code + + + + + Code + + + + + Code + + + Code + + + Code + + + Code + + + + Code + + + + + Code + + + Code + + + Code + + + + Code + + + Code + + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Code + + + + Code + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CastleKey.snk + + + + + + + + + \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapter.cs Sun Feb 13 19:16:30 2011 @@ -0,0 +1,178 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"; +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Abstract adapter for the support + /// needed by the + /// + internal abstract class AbstractDictionaryAdapter : IDictionary + { + /// + /// Adds an element with the provided key and value to the object. + /// + /// The to use as the key of the element to add. + /// The to use as the value of the element to add. + /// An element with the same key already exists in the object. + /// key is null. + /// The is read-only.-or- The has a fixed size. + public void Add(object key, object value) + { + throw new NotSupportedException(); + } + + /// + /// Removes all elements from the object. + /// + /// The object is read-only. + public void Clear() + { + throw new NotSupportedException(); + } + + /// + /// Determines whether the object contains an element with the specified key. + /// + /// The key to locate in the object. + /// + /// true if the contains an element with the key; otherwise, false. + /// + /// key is null. + public abstract bool Contains(object key); + + /// + /// Returns an object for the object. + /// + /// + /// An object for the object. + /// + public IDictionaryEnumerator GetEnumerator() + { + throw new NotSupportedException(); + } + + /// + /// Gets a value indicating whether the object has a fixed size. + /// + /// + /// true if the object has a fixed size; otherwise, false. + public bool IsFixedSize + { + get { throw new NotSupportedException(); } + } + + /// + /// Gets a value indicating whether the object is read-only. + /// + /// + /// true if the object is read-only; otherwise, false. + public abstract bool IsReadOnly { get; } + + /// + /// Gets an object containing the keys of the object. + /// + /// + /// An object containing the keys of the object. + public ICollection Keys + { + get { throw new NotSupportedException(); } + } + + /// + /// Removes the element with the specified key from the object. + /// + /// The key of the element to remove. + /// The object is read-only.-or- The has a fixed size. + /// key is null. + public void Remove(object key) + { + throw new NotSupportedException(); + } + + /// + /// Gets an object containing the values in the object. + /// + /// + /// An object containing the values in the object. + public ICollection Values + { + get { throw new NotSupportedException(); } + } + + /// + /// Gets or sets the with the specified key. + /// + /// + public abstract object this[object key] { get; set; } + + /// + /// Copies the elements of the to an , starting at a particular index. + /// + /// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + /// The zero-based index in array at which copying begins. + /// array is null. + /// The type of the source cannot be cast automatically to the type of the destination array. + /// index is less than zero. + /// array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. + public void CopyTo(Array array, int index) + { + throw new NotSupportedException(); + } + + /// + /// Gets the number of elements contained in the . + /// + /// + /// The number of elements contained in the . + public int Count + { + get { throw new NotSupportedException(); } + } + + /// + /// Gets a value indicating whether access to the is synchronized (thread safe). + /// + /// + /// true if access to the is synchronized (thread safe); otherwise, false. + public virtual bool IsSynchronized + { + get { return false; } + } + + /// + /// Gets an object that can be used to synchronize access to the . + /// + /// + /// An object that can be used to synchronize access to the . + public virtual object SyncRoot + { + get { return this; } + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// + /// An object that can be used to iterate through the collection. + /// + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotSupportedException(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapterVisitor.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapterVisitor.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapterVisitor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\AbstractDictionaryAdapterVisitor.cs Sun Feb 13 19:16:35 2011 @@ -0,0 +1,100 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Abstract implementation of . + /// + internal abstract class AbstractDictionaryAdapterVisitor : IDictionaryAdapterVisitor + { + public virtual void VisitDictionaryAdapter(IDictionaryAdapter dictionaryAdapter) + { + foreach (var property in dictionaryAdapter.This.Properties.Values) + { + Type collectionItemType; + if (IsCollection(property, out collectionItemType)) + { + VisitCollection(dictionaryAdapter, property, collectionItemType); + } + else if (property.PropertyType.IsInterface) + { + VisitInterface(dictionaryAdapter, property); + } + else + { + VisitProperty(dictionaryAdapter, property); + } + } + } + + void IDictionaryAdapterVisitor.VisitProperty(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property) + { + VisitProperty(dictionaryAdapter, property); + } + + protected virtual void VisitProperty(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property) + { + } + + void IDictionaryAdapterVisitor.VisitInterface(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property) + { + VisitInterface(dictionaryAdapter, property); + } + + protected virtual void VisitInterface(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property) + { + + } + + void IDictionaryAdapterVisitor.VisitCollection(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property, + Type collectionItemType) + { + VisitCollection(dictionaryAdapter, property, collectionItemType); + } + + protected virtual void VisitCollection(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property, + Type collectionItemType) + { + VisitProperty(dictionaryAdapter, property); + } + + private static bool IsCollection(PropertyDescriptor property, out Type collectionItemType) + { + collectionItemType = null; + var propertyType = property.PropertyType; + if (propertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(propertyType)) + { + if (propertyType.IsArray) + { + collectionItemType = propertyType.GetElementType(); + } + else if (propertyType.IsGenericType) + { + var arguments = propertyType.GetGenericArguments(); + collectionItemType = arguments[0]; + } + else + { + collectionItemType = typeof(object); + } + return true; + } + return false; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\ComponentAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\ComponentAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\ComponentAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\ComponentAttribute.cs Sun Feb 13 19:33:00 2011 @@ -0,0 +1,94 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Identifies a property should be represented as a nested component. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + internal class ComponentAttribute : DictionaryBehaviorAttribute, IDictionaryKeyBuilder, + IDictionaryPropertyGetter, IDictionaryPropertySetter + { + /// + /// Applies no prefix. + /// + public bool NoPrefix + { + get { return Prefix == ""; } + set + { + if (value) + { + Prefix = ""; + } + } + } + + /// + /// Gets or sets the prefix. + /// + /// The prefix. + public string Prefix { get; set; } + + #region IDictionaryKeyBuilder Members + + string IDictionaryKeyBuilder.GetKey(IDictionaryAdapter dictionaryAdapter, string key, + PropertyDescriptor property) + { + return Prefix ?? key + "_"; + } + + #endregion + + #region IDictionaryPropertyGetter + + object IDictionaryPropertyGetter.GetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, object storedValue, PropertyDescriptor property, bool ifExists) + { + if (storedValue == null) + { + var component = dictionaryAdapter.This.ExtendedProperties[property.PropertyName]; + + if (component == null) + { + var descriptor = new PropertyDescriptor(property.Property, null); + descriptor.AddKeyBuilder(new KeyPrefixAttribute(key)); + component = dictionaryAdapter.This.Factory.GetAdapter( + property.Property.PropertyType, dictionaryAdapter.This.Dictionary, descriptor); + dictionaryAdapter.This.ExtendedProperties[property.PropertyName] = component; + } + + return component; + } + + return storedValue; + } + + #endregion + + #region IDictionaryPropertySetter Members + + public bool SetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, ref object value, PropertyDescriptor property) + { + dictionaryAdapter.This.ExtendedProperties.Remove(property.PropertyName); + return true; + } + + #endregion + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryAdapterAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryAdapterAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryAdapterAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryAdapterAttribute.cs Sun Feb 13 19:33:06 2011 @@ -0,0 +1,32 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Identifies the dictionary adapter types. + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + internal class DictionaryAdapterAttribute : Attribute + { + public DictionaryAdapterAttribute(Type interfaceType) + { + InterfaceType = interfaceType; + } + + public Type InterfaceType { get; private set; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryBehaviorAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryBehaviorAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryBehaviorAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\DictionaryBehaviorAttribute.cs Sun Feb 13 19:33:11 2011 @@ -0,0 +1,38 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Assignes a specific dictionary key. + /// + internal abstract class DictionaryBehaviorAttribute : Attribute, IDictionaryBehavior + { + public const int FiratExecutionOrder = 0; + public const int DefaultExecutionOrder = int.MaxValue / 2; + public const int LastExecutionOrder = int.MaxValue; + + public DictionaryBehaviorAttribute() + { + ExecutionOrder = DefaultExecutionOrder; + } + + /// + /// Determines relative order to apply related behaviors. + /// + public int ExecutionOrder { get; set; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\FetchAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\FetchAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\FetchAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\FetchAttribute.cs Sun Feb 13 19:33:19 2011 @@ -0,0 +1,46 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Identifies an interface or property to be pre-feteched. + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = false)] + internal class FetchAttribute : Attribute + { + /// + /// Instructs fetching to occur. + /// + public FetchAttribute() : this(true) + { + } + + /// + /// Instructs fetching according to + /// + /// + public FetchAttribute(bool fetch) + { + Fetch = fetch; + } + + /// + /// Gets whether or not fetching should occur. + /// + public bool Fetch { get; private set; } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\GroupAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\GroupAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\GroupAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\GroupAttribute.cs Sun Feb 13 19:33:25 2011 @@ -0,0 +1,48 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Assigns a property to a group. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] + internal class GroupAttribute : Attribute + { + /// + /// Constructs a group assignment. + /// + /// The group name. + public GroupAttribute(object group) + { + Group = new [] { group }; + } + + /// + /// Constructs a group assignment. + /// + /// The group name. + public GroupAttribute(params object[] group) + { + Group = group; + } + + /// + /// Gets the group the property is assigned to. + /// + public object[] Group { get; private set; } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyAttribute.cs Sun Feb 13 19:33:30 2011 @@ -0,0 +1,52 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Assigns a specific dictionary key. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + internal class KeyAttribute : DictionaryBehaviorAttribute, IDictionaryKeyBuilder + { + private readonly String key; + + /// + /// Initializes a new instance of the class. + /// + /// The key. + public KeyAttribute(String key) + { + this.key = key; + } + + /// + /// Initializes a new instance of the class. + /// + /// The compound key. + public KeyAttribute(String[] keys) + { + this.key = string.Join(",", keys); + } + + public String Key { get; private set; } + String IDictionaryKeyBuilder.GetKey(IDictionaryAdapter dictionaryAdapter, String key, PropertyDescriptor property) + { + return this.key; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyPrefixAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyPrefixAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyPrefixAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeyPrefixAttribute.cs Sun Feb 13 19:33:34 2011 @@ -0,0 +1,58 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Assigns a prefix to the keyed properties of an interface. + /// + [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = true)] + internal class KeyPrefixAttribute : DictionaryBehaviorAttribute, IDictionaryKeyBuilder + { + private String keyPrefix; + + /// + /// Initializes a default instance of the class. + /// + public KeyPrefixAttribute() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The prefix for the keyed properties of the interface. + public KeyPrefixAttribute(String keyPrefix) + { + this.keyPrefix = keyPrefix; + } + + /// + /// Gets the prefix key added to the properties of the interface. + /// + public String KeyPrefix + { + get { return keyPrefix; } + set { keyPrefix = value; } + } + + String IDictionaryKeyBuilder.GetKey(IDictionaryAdapter dictionaryAdapter, String key, PropertyDescriptor property) + { + return keyPrefix + key; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeySubstitutionAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeySubstitutionAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeySubstitutionAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\KeySubstitutionAttribute.cs Sun Feb 13 19:33:40 2011 @@ -0,0 +1,44 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Substitutes part of key with another string. + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = true, Inherited = true)] + internal class KeySubstitutionAttribute : DictionaryBehaviorAttribute, IDictionaryKeyBuilder + { + private readonly String oldValue; + private readonly String newValue; + + /// + /// Initializes a new instance of the class. + /// + /// The old value. + /// The new value. + public KeySubstitutionAttribute(String oldValue, String newValue) + { + this.oldValue = oldValue; + this.newValue = newValue; + } + + String IDictionaryKeyBuilder.GetKey(IDictionaryAdapter dictionaryAdapter, String key, PropertyDescriptor property) + { + return key.Replace(oldValue, newValue); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\MultiLevelEditAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\MultiLevelEditAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\MultiLevelEditAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\MultiLevelEditAttribute.cs Sun Feb 13 19:33:45 2011 @@ -0,0 +1,30 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Requests support for multi-level editing. + /// + [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false)] + internal class MultiLevelEditAttribute : DictionaryBehaviorAttribute, IDictionaryInitializer + { + public void Initialize(IDictionaryAdapter dictionaryAdapter, object[] behaviors) + { + dictionaryAdapter.SupportsMultiLevelEdit = true; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\NewGuidAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\NewGuidAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\NewGuidAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\NewGuidAttribute.cs Sun Feb 13 19:33:50 2011 @@ -0,0 +1,40 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Generates a new GUID on demand. + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = false)] + internal class NewGuidAttribute : DictionaryBehaviorAttribute, IDictionaryPropertyGetter + { + private static readonly Guid UnassignedGuid = new Guid(); + + public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, object storedValue, PropertyDescriptor property, bool ifExists) + { + if (storedValue == null || storedValue.Equals(UnassignedGuid)) + { + storedValue = Guid.NewGuid(); + property.SetPropertyValue(dictionaryAdapter, key, ref storedValue, + dictionaryAdapter.This.Descriptor); + } + + return storedValue; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\OnDemandAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\OnDemandAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\OnDemandAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\OnDemandAttribute.cs Sun Feb 13 19:33:55 2011 @@ -0,0 +1,212 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + using System.Reflection; + + /// + /// Support for on-demand value resolution. + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = false)] + internal class OnDemandAttribute : DictionaryBehaviorAttribute, IDictionaryPropertyGetter + { + public OnDemandAttribute() + { + } + + public OnDemandAttribute(Type type) + { + if (type.GetConstructor(Type.EmptyTypes) == null) + { + throw new ArgumentException("On-demand values must have a parameterless constructor"); + } + + Type = type; + } + + public OnDemandAttribute(object value) + { + Value = value; + } + + public Type Type { get; private set; } + + public object Value { get; private set; } + + public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, + object storedValue, PropertyDescriptor property, bool ifExists) + { + if (storedValue == null && ifExists == false) + { + IValueInitializer initializer = null; + + if (Value != null) + { + storedValue = Value; + } + else + { + var type = Type ?? GetInferredType(dictionaryAdapter, property, out initializer); + + if (IsAcceptedType(type)) + { + if (type.IsInterface) + { + if (property.IsDynamicProperty == false) + { + if (storedValue == null) + { + storedValue = dictionaryAdapter.Create(property.PropertyType); + } + } + } + else if (type.IsArray) + { + storedValue = Array.CreateInstance(type.GetElementType(), 0); + } + else + { + if (storedValue == null) + { + object[] args = null; + ConstructorInfo constructor = null; + + if (property.IsDynamicProperty) + { + constructor = + (from ctor in type.GetConstructors() + let parms = ctor.GetParameters() + where parms.Length == 1 && + parms[0].ParameterType.IsAssignableFrom(dictionaryAdapter.Meta.Type) + select ctor).FirstOrDefault(); + + if (constructor != null) args = new[] { dictionaryAdapter }; + } + + if (constructor == null) + { + constructor = type.GetConstructor(Type.EmptyTypes); + } + + if (constructor != null) + { + storedValue = constructor.Invoke(args); + } + } + } + } + } + + if (storedValue != null) + { + using (dictionaryAdapter.SuppressNotificationsBlock()) + { +#if !SL3 + if (storedValue is ISupportInitialize) + { + ((ISupportInitialize)storedValue).BeginInit(); + ((ISupportInitialize)storedValue).EndInit(); + } +#endif + if (initializer != null) + { + initializer.Initialize(dictionaryAdapter, storedValue); + } + + property.SetPropertyValue(dictionaryAdapter, property.PropertyName, + ref storedValue, dictionaryAdapter.This.Descriptor); + } + } + } + + return storedValue; + } + + private bool IsAcceptedType(Type type) + { + return type != null && type != typeof(String) && !type.IsPrimitive && !type.IsEnum; + } + + private Type GetInferredType(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property, + out IValueInitializer initializer) + { + Type type = null; + initializer = null; + + type = property.PropertyType; + if (typeof(IEnumerable).IsAssignableFrom(type) == false) + { + return type; + } + + Type collectionType = null; + + if (type.IsGenericType) + { + var genericDef = type.GetGenericTypeDefinition(); + var genericArg = type.GetGenericArguments()[0]; + bool isBindingList = +#if SILVERLIGHT + false; +#else + genericDef == typeof(BindingList<>); +#endif + + if (isBindingList || genericDef == typeof(List<>)) + { + if (dictionaryAdapter.CanEdit) + { +#if SILVERLIGHT + collectionType = typeof(EditableList<>); +#else + collectionType = isBindingList ? typeof(EditableBindingList<>) : typeof(EditableList<>); +#endif + } + +#if SILVERLIGHT //never true +#else + if (isBindingList && genericArg.IsInterface) + { + Func addNew = () => dictionaryAdapter.Create(genericArg); + initializer = (IValueInitializer)Activator.CreateInstance( + typeof(BindingListInitializer<>).MakeGenericType(genericArg), + null, addNew, null, null); + } +#endif + } + else if (genericDef == typeof(IList<>) || genericDef == typeof(ICollection<>)) + { + collectionType = dictionaryAdapter.CanEdit ? typeof(EditableList<>) : typeof(List<>); + } + + if (collectionType != null) + { + return collectionType.MakeGenericType(genericArg); + } + } + else if (type == typeof(IList) || type == typeof(ICollection)) + { + return dictionaryAdapter.CanEdit ? typeof(EditableList) : typeof(List); + } + + return type; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\PropagateNotificationsAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\PropagateNotificationsAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\PropagateNotificationsAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\PropagateNotificationsAttribute.cs Sun Feb 13 19:34:00 2011 @@ -0,0 +1,37 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Suppress property change notifications. + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = false)] + internal class PropagateNotificationsAttribute : DictionaryBehaviorAttribute, IDictionaryInitializer + { + public PropagateNotificationsAttribute(bool propagateNotifications) + { + PropagateNotifications = propagateNotifications; + } + + public bool PropagateNotifications { get; private set; } + + public void Initialize(IDictionaryAdapter dictionaryAdapter, object[] behaviors) + { + dictionaryAdapter.PropagateChildNotifications = PropagateNotifications; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringFormatAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringFormatAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringFormatAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringFormatAttribute.cs Sun Feb 13 19:34:04 2011 @@ -0,0 +1,77 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Provides simple string formatting from existing properties. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] + internal class StringFormatAttribute : DictionaryBehaviorAttribute, IDictionaryPropertyGetter + { + private static readonly char[] PropertyDelimeters = new[] { ',', ' ' }; + + public StringFormatAttribute(string format, string properties) + { + if (format == null) + { + throw new ArgumentNullException("format"); + } + + Format = format; + Properties = properties; + } + + /// + /// Gets the string format. + /// + public string Format { get; private set; } + + /// + /// Gets the format properties. + /// + public string Properties { get; private set; } + + #region IDictionaryPropertyGetter + + object IDictionaryPropertyGetter.GetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, object storedValue, PropertyDescriptor property, bool ifExists) + { + return string.Format(Format, GetFormatArguments(dictionaryAdapter, property.Property.Name)).Trim(); + } + + #endregion + + private object[] GetFormatArguments(IDictionaryAdapter dictionaryAdapter, string formattedPropertyName) + { + var properties = Properties.Split(PropertyDelimeters, StringSplitOptions.RemoveEmptyEntries); + var arguments = new object[properties.Length]; + for (int i = 0; i < properties.Length; ++i) + { + var propertyName = properties[i]; + if (propertyName != formattedPropertyName) + { + arguments[i] = dictionaryAdapter.GetProperty(propertyName, false); + } + else + { + arguments[i] = "(recursive)"; + } + } + return arguments; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringListAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringListAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringListAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringListAttribute.cs Sun Feb 13 19:34:10 2011 @@ -0,0 +1,251 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.ComponentModel; + using System.Text; + + /// + /// Identifies a property should be represented as a delimited string value. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + internal class StringListAttribute : DictionaryBehaviorAttribute, + IDictionaryPropertyGetter, + IDictionaryPropertySetter + { + private char separator = ','; + + /// + /// Gets the separator. + /// + public char Separator + { + get { return separator; } + set { separator = value; } + } + + #region IDictionaryPropertyGetter + + object IDictionaryPropertyGetter.GetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, object storedValue, PropertyDescriptor property, bool ifExists) + { + var propertyType = property.PropertyType; + + if (storedValue == null || !storedValue.GetType().IsInstanceOfType(propertyType)) + { + if (propertyType.IsGenericType) + { + Type genericDef = propertyType.GetGenericTypeDefinition(); + + if (genericDef == typeof(IList<>) || + genericDef == typeof(ICollection<>) || + genericDef == typeof(List<>) || + genericDef == typeof(IEnumerable<>)) + { + var paramType = propertyType.GetGenericArguments()[0]; + var converter = TypeDescriptor.GetConverter(paramType); + + if (converter != null && converter.CanConvertFrom(typeof(string))) + { + var genericList = typeof(StringListWrapper<>).MakeGenericType(new[] {paramType}); + return Activator.CreateInstance(genericList, key, storedValue, separator, + dictionaryAdapter.This.Dictionary); + } + } + } + } + + return storedValue; + } + + #endregion + + #region IDictionaryPropertySetter Members + + bool IDictionaryPropertySetter.SetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, ref object value, PropertyDescriptor property) + { + var enumerable = value as IEnumerable; + if (enumerable != null) + { + value = BuildString(enumerable, separator); + } + return true; + } + + #endregion + + internal static string BuildString(IEnumerable enumerable, char separator) + { + bool first = true; + var builder = new StringBuilder(); + + foreach(object item in enumerable) + { + if (first) + { + first = false; + } + else + { + builder.Append(separator); + } + + builder.Append(item.ToString()); + } + + return builder.ToString(); + } + } + + #region StringList + + internal class StringListWrapper : IList + { + private readonly string key; + private readonly char separator; + private readonly IDictionary dictionary; + private readonly List inner; + + public StringListWrapper(string key, string list, + char separator, IDictionary dictionary) + { + this.key = key; + this.separator = separator; + this.dictionary = dictionary; + inner = new List(); + + ParseList(list); + } + + #region IList Members + + public int IndexOf(T item) + { + return inner.IndexOf(item); + } + + public void Insert(int index, T item) + { + inner.Insert(index, item); + SynchronizeDictionary(); + } + + public void RemoveAt(int index) + { + inner.RemoveAt(index); + SynchronizeDictionary(); + } + + public T this[int index] + { + get { return inner[index]; } + set + { + inner[index] = value; + SynchronizeDictionary(); + } + } + + #endregion + + #region ICollection Members + + public void Add(T item) + { + inner.Add(item); + SynchronizeDictionary(); + } + + public void Clear() + { + inner.Clear(); + SynchronizeDictionary(); + } + + public bool Contains(T item) + { + return inner.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + inner.CopyTo(array, arrayIndex); + } + + public int Count + { + get { return inner.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove(T item) + { + if (inner.Remove(item)) + { + SynchronizeDictionary(); + return true; + } + return false; + } + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator() + { + return inner.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + return inner.GetEnumerator(); + } + + #endregion + + private void ParseList(string list) + { + if (list != null) + { + var converter = TypeDescriptor.GetConverter(typeof(T)); + + foreach(var item in list.Split(separator)) + { + inner.Add((T) converter.ConvertFrom(item)); + } + } + } + + private void SynchronizeDictionary() + { + dictionary[key] = StringListAttribute.BuildString(inner, separator); + } + } + + #endregion +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringStorageAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringStorageAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringStorageAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringStorageAttribute.cs Sun Feb 13 19:34:16 2011 @@ -0,0 +1,26 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"; +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + internal class StringStorageAttribute : DictionaryBehaviorAttribute, IDictionaryPropertySetter + { + public bool SetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, + ref object value, PropertyDescriptor property) + { + value = (value != null) ? value.ToString() : null; + return true; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringValuesAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringValuesAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringValuesAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\StringValuesAttribute.cs Sun Feb 13 19:34:21 2011 @@ -0,0 +1,70 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Converts all properties to strings. + /// + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, + AllowMultiple = false, Inherited = true)] + internal class StringValuesAttribute : DictionaryBehaviorAttribute, IDictionaryPropertySetter + { + private string format; + + /// + /// Gets or sets the format. + /// + /// The format. + public string Format + { + get { return format; } + set { format = value; } + } + + #region IDictionaryPropertySetter Members + + bool IDictionaryPropertySetter.SetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, ref object value, PropertyDescriptor property) + { + if (value != null) + { + value = GetPropertyAsString(property, value); + } + return true; + } + + #endregion + + private string GetPropertyAsString(PropertyDescriptor property, object value) + { + if (!string.IsNullOrEmpty(format)) + { + return String.Format(format, value); + } + + var converter = property.TypeConverter; + + if (converter != null && converter.CanConvertTo(typeof(string))) + { + return (string) converter.ConvertTo(value, typeof(string)); + } + + return value.ToString(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\SuppressNotificationsAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\SuppressNotificationsAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\SuppressNotificationsAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\SuppressNotificationsAttribute.cs Sun Feb 13 19:34:25 2011 @@ -0,0 +1,30 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Suppress property change notifications. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] + internal class SuppressNotificationsAttribute : DictionaryBehaviorAttribute, IPropertyDescriptorInitializer + { + public void Initialize(PropertyDescriptor propertyDescriptor, object[] behaviors) + { + propertyDescriptor.SuppressNotifications = true; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\TypeKeyPrefixAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\TypeKeyPrefixAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\TypeKeyPrefixAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\TypeKeyPrefixAttribute.cs Sun Feb 13 19:34:31 2011 @@ -0,0 +1,32 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Assigns a prefix to the keyed properties using the interface name. + /// + [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = true)] + internal class TypeKeyPrefixAttribute : DictionaryBehaviorAttribute, IDictionaryKeyBuilder + { + String IDictionaryKeyBuilder.GetKey(IDictionaryAdapter dictionaryAdapter, + String key, PropertyDescriptor property) + { + return property.Property.DeclaringType.FullName + "#" + key; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XmlNamespaceAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XmlNamespaceAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XmlNamespaceAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XmlNamespaceAttribute.cs Sun Feb 13 19:34:35 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = true)] + internal class XmlNamespaceAttribute : Attribute + { + public XmlNamespaceAttribute(string namespaceUri, string prefix) + { + NamespaceUri = namespaceUri; + Prefix = prefix; + } + + public bool Default { get; set; } + + public string NamespaceUri { get; private set; } + + public string Prefix { get; private set; } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathAttribute.cs Sun Feb 13 19:34:40 2011 @@ -0,0 +1,44 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if !SILVERLIGHT + using System; + using System.Xml.XPath; + + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = true)] + internal class XPathAttribute : Attribute + { + private string expression; + + public XPathAttribute(string expression) + { + Expression = expression; + } + + public string Expression + { + get { return expression; } + private set + { + expression = value; + CompiledExpression = XPathExpression.Compile(expression); + } + } + + public XPathExpression CompiledExpression { get; private set; } + } +#endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathFunctionAttribute.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathFunctionAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathFunctionAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Attributes\XPathFunctionAttribute.cs Sun Feb 13 19:34:45 2011 @@ -0,0 +1,55 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if !SILVERLIGHT + using System; + using System.Xml.Xsl; + + [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = true)] + internal class XPathFunctionAttribute : Attribute + { + protected XPathFunctionAttribute(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentException("Name cannot be empty", "name"); + } + Name = name; + } + + public XPathFunctionAttribute(string name, Type functionType) : this(name) + { + if (typeof(IXsltContextFunction).IsAssignableFrom(functionType) == false) + { + throw new ArgumentException("The functionType does not implement IXsltContextFunction"); + } + + var defaultCtor = functionType.GetConstructor(Type.EmptyTypes); + if (defaultCtor == null) + { + throw new ArgumentException("The functionType does not have a parameterless constructor"); + } + Function = (IXsltContextFunction)Activator.CreateInstance(functionType); + } + + public string Name { get; private set; } + + public IXsltContextFunction Function { get; protected set; } + + public string Prefix { get; set; } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\CascadingDictionaryAdapter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\CascadingDictionaryAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\CascadingDictionaryAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\CascadingDictionaryAdapter.cs Sun Feb 13 19:16:40 2011 @@ -0,0 +1,56 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System.Collections; + + internal class CascadingDictionaryAdapter : AbstractDictionaryAdapter + { + private readonly IDictionary primary; + private readonly IDictionary secondary; + + public CascadingDictionaryAdapter(IDictionary primary, IDictionary secondary) + { + this.primary = primary; + this.secondary = secondary; + } + + public IDictionary Primary + { + get { return primary; } + } + + public IDictionary Secondary + { + get { return secondary; } + } + + public override bool IsReadOnly + { + get { return primary.IsReadOnly; } + } + + public override bool Contains(object key) + { + return primary.Contains(key) || secondary.Contains(key); + } + + public override object this[object key] + { + get { return primary[key] ?? secondary[key]; } + set { primary[key] = value; } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultPropertyGetter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultPropertyGetter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultPropertyGetter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultPropertyGetter.cs Sun Feb 13 19:16:45 2011 @@ -0,0 +1,68 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System.ComponentModel; + + /// + /// Manages conversion between property values. + /// + internal class DefaultPropertyGetter : IDictionaryPropertyGetter + { + private readonly TypeConverter converter; + + /// + /// Initializes a new instance of the class. + /// + /// The converter. + public DefaultPropertyGetter(TypeConverter converter) + { + this.converter = converter; + } + + /// + /// + /// + public int ExecutionOrder + { + get { return DictionaryBehaviorAttribute.LastExecutionOrder; } + } + + /// + /// Gets the effective dictionary value. + /// + /// The dictionary adapter. + /// The key. + /// The stored value. + /// The property. + /// true if return only existing. + /// The effective property value. + public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, object storedValue, PropertyDescriptor property, bool ifExists) + { + var propertyType = property.PropertyType; + + if (storedValue != null && propertyType.IsInstanceOfType(storedValue) == false) + { + if (converter != null && converter.CanConvertFrom(storedValue.GetType())) + { + return converter.ConvertFrom(storedValue); + } + } + + return storedValue; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultXmlSerializer.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultXmlSerializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultXmlSerializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DefaultXmlSerializer.cs Sun Feb 13 19:16:50 2011 @@ -0,0 +1,90 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT + +namespace Castle.Components.DictionaryAdapter +{ + using System.Text; + using System.Xml; + using System.Xml.Serialization; + using System.Xml.XPath; + + internal class DefaultXmlSerializer : IXPathSerializer + { + public static readonly DefaultXmlSerializer Instance = new DefaultXmlSerializer(); + + private DefaultXmlSerializer() + { + } + + public bool WriteObject(XPathResult result, XPathNavigator node, object value) + { + var rootOverride = new XmlRootAttribute(node.LocalName) + { + Namespace = node.NamespaceURI + }; + + var xml = new StringBuilder(); + var settings = new XmlWriterSettings + { + OmitXmlDeclaration = true, + Indent = false + }; + var namespaces = new XmlSerializerNamespaces(); + namespaces.Add(string.Empty, string.Empty); + if (string.IsNullOrEmpty(node.NamespaceURI) == false) + { + var prefix = result.Context.AddNamespace(node.NamespaceURI); + namespaces.Add(prefix, node.NamespaceURI); + } + + var serializer = new XmlSerializer(result.Type, rootOverride); + + using (var writer = XmlWriter.Create(xml, settings)) + { + serializer.Serialize(writer, value, namespaces); + writer.Flush(); + } + + node.ReplaceSelf(xml.ToString()); + + return true; + } + + public bool ReadObject(XPathResult result, XPathNavigator node, out object value) + { + var rootOverride = new XmlRootAttribute(node.LocalName) + { + Namespace = node.NamespaceURI + }; + + var serializer = new XmlSerializer(result.Type, rootOverride); + + using (var reader = node.ReadSubtree()) + { + reader.MoveToContent(); + if (serializer.CanDeserialize(reader)) + { + value = serializer.Deserialize(reader); + return true; + } + } + + value = null; + return false; + } + } +} +#endif \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Create.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Create.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Create.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Create.cs Sun Feb 13 19:28:11 2011 @@ -0,0 +1,66 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; +#if !SILVERLIGHT + using System.Collections.Specialized; +#else + using HybridDictionary = System.Collections.Generic.Dictionary; +#endif + internal abstract partial class DictionaryAdapterBase : IDictionaryCreate + { + public T Create() + { + return Create(new HybridDictionary()); + } + + public object Create(Type type) + { + return Create(type, new HybridDictionary()); + } + + public T Create(IDictionary dictionary) + { + return (T)Create(typeof(T), dictionary ?? new HybridDictionary()); + } + + public object Create(Type type, IDictionary dictionary) + { + if (This.CreateStrategy != null) + { + return This.CreateStrategy.Create(this, type, dictionary); + } + else + { + dictionary = dictionary ?? new HybridDictionary(); + return This.Factory.GetAdapter(type, dictionary, This.Descriptor); + } + } + + public T Create(Action init) + { + return Create(new HybridDictionary(), init); + } + + public T Create(IDictionary dictionary, Action init) + { + var adapter = Create(dictionary ?? new HybridDictionary()); + if (init != null) init(adapter); + return adapter; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.cs Sun Feb 13 19:28:16 2011 @@ -0,0 +1,235 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + using System.ComponentModel; + using System.Linq; + + internal abstract partial class DictionaryAdapterBase : IDictionaryAdapter + { + public DictionaryAdapterBase(DictionaryAdapterInstance instance) + { + This = instance; + + CanEdit = typeof(IEditableObject).IsAssignableFrom(Meta.Type); + CanNotify = typeof(INotifyPropertyChanged).IsAssignableFrom(Meta.Type); + CanValidate = typeof(IDataErrorInfo).IsAssignableFrom(Meta.Type); + + Initialize(); + } + + public abstract DictionaryAdapterMeta Meta { get; } + + public DictionaryAdapterInstance This { get; private set; } + + public string GetKey(string propertyName) + { + PropertyDescriptor descriptor; + if (This.Properties.TryGetValue(propertyName, out descriptor)) + { + return descriptor.GetKey(this, propertyName, This.Descriptor); + } + return null; + } + + public virtual object GetProperty(string propertyName, bool ifExists) + { + PropertyDescriptor descriptor; + if (This.Properties.TryGetValue(propertyName, out descriptor)) + { + var propertyValue = descriptor.GetPropertyValue(this, propertyName, null, This.Descriptor, ifExists); + if (propertyValue is IEditableObject) + { + AddEditDependency((IEditableObject)propertyValue); + } + ComposeChildNotifications(descriptor, null, propertyValue); + return propertyValue; + } + return null; + } + + public T GetPropertyOfType(string propertyName) + { + var propertyValue = GetProperty(propertyName, false); + return propertyValue != null ? (T)propertyValue : default(T); + } + + public object ReadProperty(string key) + { + object propertyValue = null; + if (GetEditedProperty(key, out propertyValue) == false) + { + var dictionary = GetDictionary(This.Dictionary, ref key); + if (dictionary != null) propertyValue = dictionary[key]; + } + return propertyValue; + } + + public virtual bool SetProperty(string propertyName, ref object value) + { + bool stored = false; + + PropertyDescriptor descriptor; + if (This.Properties.TryGetValue(propertyName, out descriptor)) + { + if (ShouldNotify == false) + { + stored = descriptor.SetPropertyValue(this, propertyName, ref value, This.Descriptor); + Invalidate(); + return stored; + } + + var existingValue = GetProperty(propertyName, true); + if (NotifyPropertyChanging(descriptor, existingValue, value) == false) + { + return false; + } + + var trackPropertyChange = TrackPropertyChange(descriptor, existingValue, value); + + stored = descriptor.SetPropertyValue(this, propertyName, ref value, This.Descriptor); + + if (stored && trackPropertyChange != null) + { + trackPropertyChange.Notify(); + } + } + + return stored; + } + + public void StoreProperty(PropertyDescriptor property, string key, object value) + { + if (property == null || EditProperty(property, key, value) == false) + { + var dictionary = GetDictionary(This.Dictionary, ref key); + if (dictionary != null) dictionary[key] = value; + } + } + + public void ClearProperty(PropertyDescriptor property, string key) + { + if (property == null || ClearEditProperty(property, key) == false) + { + var dictionary = GetDictionary(This.Dictionary, ref key); + if (dictionary != null) dictionary.Remove(key); + } + } + + public void CopyTo(IDictionaryAdapter other) + { + CopyTo(other, null); + } + + public void CopyTo(IDictionaryAdapter other, Predicate selector) + { + if (Meta.Type.IsAssignableFrom(other.Meta.Type) == false) + { + throw new ArgumentException(string.Format( + "Unable to copy to {0}. Type must be assignable from {1}.", + other.Meta.Type.FullName, Meta.Type.FullName)); + } + + selector = selector ?? (p => true); + + foreach (var property in This.Properties.Values.Where(p => selector(p))) + { + var propertyValue = GetProperty(property.PropertyName, true); + if (propertyValue != null) + other.SetProperty(property.PropertyName, ref propertyValue); + } + } + + public T Coerce() where T : class + { + return (T)This.Factory.GetAdapter(typeof(T), This.Dictionary, This.Descriptor); + } + + public override bool Equals(object obj) + { + var other = obj as IDictionaryAdapter; + + if (other == null) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (Meta.Type != other.Meta.Type) + { + return false; + } + + if (This.EqualityHashCodeStrategy != null) + { + return This.EqualityHashCodeStrategy.Equals(this, other); + } + + return base.Equals(obj); + } + + public override int GetHashCode() + { + if (This.OldHashCode.HasValue) + { + return This.OldHashCode.Value; + } + + int hashCode; + if (This.EqualityHashCodeStrategy == null || + This.EqualityHashCodeStrategy.GetHashCode(this, out hashCode) == false) + { + hashCode = base.GetHashCode(); + } + + This.OldHashCode = hashCode; + return hashCode; + } + + protected void Initialize() + { + foreach (var initializer in This.Initializers) + { + initializer.Initialize(this, Meta.Behaviors); + } + + foreach (var property in This.Properties.Values.Where(p => p.Fetch)) + { + GetProperty(property.PropertyName, false); + } + } + + private static IDictionary GetDictionary(IDictionary dictionary, ref string key) + { + if (key.StartsWith("!") == false) + { + var parts = key.Split(','); + for (var i = 0; i < parts.Length - 1; ++i) + { + dictionary = dictionary[parts[i]] as IDictionary; + if (dictionary == null) return null; + } + key = parts[parts.Length - 1]; + } + return dictionary; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Edit.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Edit.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Edit.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Edit.cs Sun Feb 13 19:28:21 2011 @@ -0,0 +1,265 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + + internal abstract partial class DictionaryAdapterBase + { + private int suppressEditingCount = 0; + private Stack> updates; +#if SL3 + private List editDependencies; +#else + private HashSet editDependencies; +#endif + struct Edit + { + public Edit(PropertyDescriptor property, object propertyValue) + { + Property = property; + PropertyValue = propertyValue; + } + public readonly PropertyDescriptor Property; + public object PropertyValue; + } + + public bool CanEdit + { + get { return suppressEditingCount == 0 && updates != null; } + set { updates = value ? new Stack>() : null; } + } + + public bool IsEditing + { + get { return CanEdit && updates != null && updates.Count > 0; } + } + + public bool SupportsMultiLevelEdit { get; set; } + + public bool IsChanged + { + get + { + if (IsEditing && updates.Any(level => level.Count > 0)) + return true; + + return This.Properties.Values + .Where(prop => typeof(IChangeTracking).IsAssignableFrom(prop.PropertyType)) + .Select(prop => GetProperty(prop.PropertyName, true)) + .Cast().Any(track => track != null && track.IsChanged); + } + } + + public void BeginEdit() + { + if (CanEdit && (IsEditing == false || SupportsMultiLevelEdit)) + { + updates.Push(new Dictionary()); + } + } + + public void CancelEdit() + { + if (IsEditing) + { + if (editDependencies != null) + { + foreach (var editDependency in editDependencies.ToArray()) + { + editDependency.CancelEdit(); + } + editDependencies.Clear(); + } + + using (SuppressEditingBlock()) + { + using (TrackReadonlyPropertyChanges()) + { + var top = updates.Peek(); + + if (top.Count > 0) + { + foreach (var update in top.Values) + { + var existing = update; + existing.PropertyValue = GetProperty(existing.Property.PropertyName, true); + } + + updates.Pop(); + + foreach (var update in top.Values.ToArray()) + { + var oldValue = update.PropertyValue; + var newValue = GetProperty(update.Property.PropertyName, true); + + if (!Object.Equals(oldValue, newValue)) + { + + NotifyPropertyChanging(update.Property, oldValue, newValue); + NotifyPropertyChanged(update.Property, oldValue, newValue); + + } + } + } + } + } + } + } + + public void EndEdit() + { + if (IsEditing) + { + using (SuppressEditingBlock()) + { + var top = updates.Pop(); + + if (top.Count > 0) foreach (var update in top.ToArray()) + { + StoreProperty(null, update.Key, update.Value.PropertyValue); + } + } + + if (editDependencies != null) + { + foreach (var editDependency in editDependencies.ToArray()) + { + editDependency.EndEdit(); + } + editDependencies.Clear(); + } + } + } + + public void RejectChanges() + { + CancelEdit(); + } + + public void AcceptChanges() + { + EndEdit(); + } + + public IDisposable SuppressEditingBlock() + { + return new SuppressEditingScope(this); + } + + public void SuppressEditing() + { + ++suppressEditingCount; + } + + public void ResumeEditing() + { + --suppressEditingCount; + } + + protected bool GetEditedProperty(string propertyName, out object propertyValue) + { + if (updates != null) foreach (var level in updates.ToArray()) + { + Edit edit; + if (level.TryGetValue(propertyName, out edit)) + { + propertyValue = edit.PropertyValue; + return true; + } + } + propertyValue = null; + return false; + } + + protected bool EditProperty(PropertyDescriptor property, string key, object propertyValue) + { + if (IsEditing) + { + updates.Peek()[key] = new Edit(property, propertyValue); + return true; + } + return false; + } + + protected bool ClearEditProperty(PropertyDescriptor property, string key) + { + if (IsEditing) + { + updates.Peek().Remove(key); + return true; + } + return false; + } + + protected void AddEditDependency(IEditableObject editDependency) + { + if (IsEditing) + { + if (editDependencies == null) + { +#if SL3 + editDependencies = new List(); +#else + editDependencies = new HashSet(); +#endif + } + +#if SL3 + if(AddDependency(editDependency)) +#else + if (editDependencies.Add(editDependency)) +#endif + { + editDependency.BeginEdit(); + } + } + } +#if SL3 + private bool AddDependency(IEditableObject editDependency) + { + if (editDependencies.Contains(editDependency)) + { + return false; + } + editDependencies.Add(editDependency); + return true; + } +#endif + + #region Nested Class: SuppressEditingScope + + class SuppressEditingScope : IDisposable + { + private readonly DictionaryAdapterBase adapter; + + public SuppressEditingScope(DictionaryAdapterBase adapter) + { + this.adapter = adapter; + this.adapter.SuppressEditing(); + } + + public void Dispose() + { + adapter.ResumeEditing(); + } + } + + #endregion + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Notify.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Notify.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Notify.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Notify.cs Sun Feb 13 19:28:26 2011 @@ -0,0 +1,329 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + + internal abstract partial class DictionaryAdapterBase + { + private int suppressNotificationCount = 0; + private bool propagateChildNotifications = true; + private Dictionary composedChildNotifications; + + [ThreadStatic] + private static TrackPropertyChangeScope readonlyTrackingScope; + + public event PropertyChangingEventHandler PropertyChanging; + public event PropertyChangedEventHandler PropertyChanged; + + + public bool CanNotify { get; set; } + + public bool ShouldNotify + { + get { return CanNotify && suppressNotificationCount == 0; } + } + + public bool PropagateChildNotifications + { + get { return propagateChildNotifications; } + set { propagateChildNotifications = value; } + } + + public IDisposable SuppressNotificationsBlock() + { + return new SuppressNotificationsScope(this); + } + + public void SuppressNotifications() + { + ++suppressNotificationCount; + } + + public void ResumeNotifications() + { + --suppressNotificationCount; + } + protected bool NotifyPropertyChanging(PropertyDescriptor property, object oldValue, object newValue) + { + if (!property.SuppressNotifications) + { + var propertyChanging = PropertyChanging; + + if (propertyChanging != null) + { + var eventArgs = new PropertyModifyingEventArgs(property.PropertyName, oldValue, newValue); + propertyChanging(this, eventArgs); + return !eventArgs.Cancel; + } + } + return true; + } + + protected void NotifyPropertyChanged(PropertyDescriptor property, object oldValue, object newValue) + { + if (!property.SuppressNotifications) + { + var propertyChanged = PropertyChanged; + + ComposeChildNotifications(property, oldValue, newValue); + + if (propertyChanged != null) + { + propertyChanged(this, new PropertyModifiedEventArgs(property.PropertyName, oldValue, newValue)); + } + } + } + + protected void NotifyPropertyChanged(string propertyName) + { + if (ShouldNotify) + { + var propertyChanged = PropertyChanged; + + if (propertyChanged != null) + { + propertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + } + + protected TrackPropertyChangeScope TrackPropertyChange(PropertyDescriptor property, + object oldValue, object newValue) + { + if (ShouldNotify && !property.SuppressNotifications) + { + return new TrackPropertyChangeScope(this, property, oldValue); + } + return null; + } + + protected TrackPropertyChangeScope TrackReadonlyPropertyChanges() + { + if (ShouldNotify && readonlyTrackingScope == null) + { + var scope = new TrackPropertyChangeScope(this); + readonlyTrackingScope = scope; + return scope; + } + return null; + } + + private void ComposeChildNotifications(PropertyDescriptor property, object oldValue, object newValue) + { + if (composedChildNotifications == null) + composedChildNotifications = new Dictionary(); + + if (oldValue != null) + { + object handler; + if (composedChildNotifications.TryGetValue(oldValue, out handler)) + { + composedChildNotifications.Remove(oldValue); + + if (oldValue is INotifyPropertyChanged) + { + ((INotifyPropertyChanged)oldValue).PropertyChanged -= Child_PropertyChanged; +#if !SILVERLIGHT + if (oldValue is INotifyPropertyChanging) + { + ((INotifyPropertyChanging)oldValue).PropertyChanging -= Child_PropertyChanging; + } + } + else if (oldValue is IBindingList) + { + ((IBindingList)oldValue).ListChanged -= (ListChangedEventHandler)handler; +#endif + } + } + } + + if (newValue != null && !composedChildNotifications.ContainsKey(newValue)) + { + if (newValue is INotifyPropertyChanged) + { + ((INotifyPropertyChanged)newValue).PropertyChanged += Child_PropertyChanged; + +#if !SILVERLIGHT + if (newValue is INotifyPropertyChanging) + { + ((INotifyPropertyChanging)newValue).PropertyChanging += Child_PropertyChanging; + } + + composedChildNotifications.Add(newValue, null); + } + else if (newValue is IBindingList) + { + ListChangedEventHandler handler = (sender, args) => + { + if (propagateChildNotifications) + { + var propertyChanged = PropertyChanged; + + if (propertyChanged != null) + { + if (args.PropertyDescriptor != null) + { + var propertyName = args.PropertyDescriptor.Name; + propertyChanged(sender, new PropertyChangedEventArgs(propertyName)); + } + propertyChanged(this, new PropertyChangedEventArgs(property.PropertyName)); + } + } + }; + ((IBindingList)newValue).ListChanged += handler; + + composedChildNotifications.Add(newValue, handler); +#endif + } + } + } + + private void Child_PropertyChanging(object sender, PropertyChangingEventArgs e) + { + if (propagateChildNotifications) + { + var propertyChanging = PropertyChanging; + + if (propertyChanging != null) + { + propertyChanging(sender, e); + } + } + } + + private void Child_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (propagateChildNotifications) + { + var propertyChanged = PropertyChanged; + + if (propertyChanged != null) + { + propertyChanged(sender, e); + } + } + } + + #region Nested Class: SuppressNotificationsScope + + class SuppressNotificationsScope : IDisposable + { + private readonly DictionaryAdapterBase adapter; + + public SuppressNotificationsScope(DictionaryAdapterBase adapter) + { + this.adapter = adapter; + this.adapter.SuppressNotifications(); + } + + public void Dispose() + { + this.adapter.ResumeNotifications(); + } + } + + #endregion + + #region Nested Class: TrackPropertyChangeScope + + public class TrackPropertyChangeScope : IDisposable + { + private readonly DictionaryAdapterBase adapter; + private readonly PropertyDescriptor property; + private readonly object existingValue; + private IDictionary readonlyProperties; + + public TrackPropertyChangeScope(DictionaryAdapterBase adapter) + { + this.adapter = adapter; + readonlyProperties = adapter.This.Properties.Values.Where( + pd => !pd.Property.CanWrite || pd.IsDynamicProperty) + .ToDictionary(pd => pd, pd => GetEffectivePropertyValue(pd)); + } + + public TrackPropertyChangeScope(DictionaryAdapterBase adapter, PropertyDescriptor property, + object existingValue) + : this(adapter) + { + this.property = property; + this.existingValue = existingValue; + existingValue = adapter.GetProperty(property.PropertyName, true); + } + + public bool Notify() + { + if (readonlyTrackingScope == this) + { + readonlyTrackingScope = null; + return NotifyReadonly(); + } + + var newValue = GetEffectivePropertyValue(property); + if (NotifyIfChanged(property, existingValue, newValue)) + { + if (readonlyTrackingScope == null) + NotifyReadonly(); + return true; + } + + return false; + } + + private bool NotifyReadonly() + { + bool changed = false; + foreach (var readonlyProperty in readonlyProperties) + { + var descriptor = readonlyProperty.Key; + var currentValue = GetEffectivePropertyValue(descriptor); + changed |= NotifyIfChanged(descriptor, readonlyProperty.Value, currentValue); + } + adapter.Invalidate(); + return changed; + } + + private bool NotifyIfChanged(PropertyDescriptor descriptor, object oldValue, object newValue) + { + if (!Object.Equals(oldValue, newValue)) + { + adapter.NotifyPropertyChanged(descriptor, oldValue, newValue); + return true; + } + return false; + } + + private object GetEffectivePropertyValue(PropertyDescriptor property) + { + var value = adapter.GetProperty(property.PropertyName, true); + if (value != null & property.IsDynamicProperty) + { + value = ((IDynamicValue)value).GetValue(); + } + return value; + } + + public void Dispose() + { + Notify(); + } + } + + #endregion + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Validate.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Validate.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Validate.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Validate.cs Sun Feb 13 19:28:31 2011 @@ -0,0 +1,114 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections.Generic; + using System.Linq; + + internal partial class DictionaryAdapterBase : IDictionaryValidate + { + private ICollection validators; + + public bool CanValidate { get; set; } + + public bool IsValid + { + get + { + if (CanValidate && validators != null) + { + return !validators.Any(v => !v.IsValid(this)); + } + return !CanValidate; + } + } + + public string Error + { + get + { + if (CanValidate && validators != null) + { + return string.Join(Environment.NewLine, validators.Select( + v => v.Validate(this)).Where(e => !string.IsNullOrEmpty(e)).ToArray()); + } + return String.Empty; + } + } + + public string this[String columnName] + { + get + { + if (CanValidate && validators != null) + { + PropertyDescriptor property; + if (This.Properties.TryGetValue(columnName, out property)) + { + return string.Join(Environment.NewLine, validators.Select( + v => v.Validate(this, property)).Where(e => !string.IsNullOrEmpty(e)) + .ToArray()); + } + } + return String.Empty; + } + } + + public DictionaryValidateGroup ValidateGroups(params object[] groups) + { + return new DictionaryValidateGroup(groups, this); + } + + public IEnumerable Validators + { + get + { + return validators ?? Enumerable.Empty(); + } + } + + public void AddValidator(IDictionaryValidator validator) + { + if (validators == null) + { + validators = +#if SL3 //Silverlight 3 does not have HashSet + new List(); +#else + new HashSet(); +#endif + } +#if SL3 //Silverlight 3 does not have HashSet + if(validators.Contains(validator)) return; +#else + validators.Add(validator); +#endif + } + + protected internal void Invalidate() + { + if (CanValidate) + { + if (validators != null) foreach (var validator in validators) + { + validator.Invalidate(this); + } + + NotifyPropertyChanged("IsValid"); + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterFactory.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterFactory.cs Sun Feb 13 19:28:37 2011 @@ -0,0 +1,627 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + using System.Collections.Generic; +#if !SILVERLIGHT + using System.Collections.Specialized; +#endif + using System.ComponentModel; + using System.Linq; + using System.Reflection; + using System.Reflection.Emit; + using System.Text; + using System.Threading; +#if !SILVERLIGHT + using System.Xml.XPath; +#endif + using System.Diagnostics; + + using Castle.Core.Internal; + + /// + /// Uses Reflection.Emit to expose the properties of a dictionary + /// through a dynamic implementation of a typed interface. + /// + internal class DictionaryAdapterFactory : IDictionaryAdapterFactory + { + private readonly Dictionary interfaceToAdapter = new Dictionary(); + private readonly object typesDictionaryLocker = new object(); + + #region IDictionaryAdapterFactory + + /// + public T GetAdapter(IDictionary dictionary) + { + return (T) GetAdapter(typeof(T), dictionary); + } + + /// + public object GetAdapter(Type type, IDictionary dictionary) + { + return InternalGetAdapter(type, dictionary, null); + } + + /// + public object GetAdapter(Type type, IDictionary dictionary, PropertyDescriptor descriptor) + { + return InternalGetAdapter(type, dictionary, descriptor); + } + + /// + public T GetAdapter(IDictionary dictionary) + { + return (T) GetAdapter(typeof(T), dictionary); + } + + /// + public object GetAdapter(Type type, IDictionary dictionary) + { + var adapter = new GenericDictionaryAdapter(dictionary); + return InternalGetAdapter(type, adapter, null); + } + +#if! SILVERLIGHT + /// + public T GetAdapter(NameValueCollection nameValues) + { + return GetAdapter(new NameValueCollectionAdapter(nameValues)); + } + + /// + public object GetAdapter(Type type, NameValueCollection nameValues) + { + return GetAdapter(type, new NameValueCollectionAdapter(nameValues)); + } + + /// + public T GetAdapter(IXPathNavigable xpathNavigable) + { + return (T)GetAdapter(typeof(T), xpathNavigable); + } + + /// + public object GetAdapter(Type type, IXPathNavigable xpathNavigable) + { + var xpath = new XPathAdapter(xpathNavigable); + return GetAdapter(type, new Hashtable(), new DictionaryDescriptor() + .AddBehavior(XPathBehavior.Instance).AddBehavior(xpath)); + } +#endif + + /// + public DictionaryAdapterMeta GetAdapterMeta(Type type) + { + return GetAdapterMeta(type, null); + } + + /// + public DictionaryAdapterMeta GetAdapterMeta(Type type, PropertyDescriptor descriptor) + { + if (type.IsInterface == false) + { + throw new ArgumentException("Only interfaces can be adapted and have metadata"); + } + + var adapterType = InternalGetAdapterType(type, descriptor); + var metaBindings = BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField; + return (DictionaryAdapterMeta)adapterType.InvokeMember("__meta", metaBindings, null, null, null); + } + + #endregion + + private Type InternalGetAdapterType(Type type, PropertyDescriptor descriptor) + { + if (type.IsInterface == false) + { + throw new ArgumentException("Only interfaces can be adapted to a dictionary"); + } + + Type adapterType; + if (interfaceToAdapter.TryGetValue(type, out adapterType) == false) + { + lock (typesDictionaryLocker) + { + if (interfaceToAdapter.TryGetValue(type, out adapterType) == false) + { + var appDomain = Thread.GetDomain(); + var adapterAssemblyName = GetAdapterAssemblyName(type); + var typeBuilder = CreateTypeBuilder(type, appDomain, adapterAssemblyName); + var adapterAssembly = CreateAdapterAssembly(type, typeBuilder, descriptor); + adapterType = CreateAdapterType(type, adapterAssembly); + interfaceToAdapter[type] = adapterType; + } + } + } + + return adapterType; + } + + private object InternalGetAdapter(Type type, IDictionary dictionary, PropertyDescriptor descriptor) + { + var adapterType = InternalGetAdapterType(type, descriptor); + return CreateAdapterInstance(dictionary, descriptor, adapterType); + } + + #region Dynamic Type Generation + + private static TypeBuilder CreateTypeBuilder(Type type, AppDomain appDomain, String adapterAssemblyName) + { + var assemblyName = new AssemblyName(adapterAssemblyName); + var assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule(adapterAssemblyName); + return CreateAdapterType(type, moduleBuilder); + } + + private static TypeBuilder CreateAdapterType(Type type, ModuleBuilder moduleBuilder) + { + var typeBuilder = moduleBuilder.DefineType(GetAdapterFullTypeName(type), + TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.BeforeFieldInit); + typeBuilder.AddInterfaceImplementation(type); + typeBuilder.SetParent(typeof(DictionaryAdapterBase)); + + var attribCtorParams = new[] { typeof(Type) }; + var attribCtorInfo = typeof(DictionaryAdapterAttribute).GetConstructor(attribCtorParams); + var attribBuilder = new CustomAttributeBuilder(attribCtorInfo, new[] { type }); + typeBuilder.SetCustomAttribute(attribBuilder); + + var debugAttribCtorParams = new[] { typeof(string) }; + var debugAttribCtorInfo = typeof(DebuggerDisplayAttribute).GetConstructor(debugAttribCtorParams); + var debugAttribBuilder = new CustomAttributeBuilder(debugAttribCtorInfo, new[] { "Type: {Meta.Type.FullName,nq}" }); + typeBuilder.SetCustomAttribute(debugAttribBuilder); + + return typeBuilder; + } + + private Assembly CreateAdapterAssembly(Type type, TypeBuilder typeBuilder, PropertyDescriptor descriptor) + { + var binding = FieldAttributes.Public | FieldAttributes.Static; + var metaField = typeBuilder.DefineField("__meta", typeof(DictionaryAdapterMeta), binding); + + CreateAdapterConstructor(typeBuilder); + + object[] behaviors; + IDictionaryInitializer[] initializers; + IDictionaryMetaInitializer[] metaInitializers; + var propertyMap = GetPropertyDescriptors(type, out initializers, out metaInitializers, out behaviors); + + CreateMetaProperty(typeBuilder, AdapterGetMeta, metaField); + + foreach (var property in propertyMap) + { + CreateAdapterProperty(typeBuilder, property.Value); + } + + var adapterType = typeBuilder.CreateType(); + var metaBindings = BindingFlags.Public | BindingFlags.Static | BindingFlags.SetField; + var meta = new DictionaryAdapterMeta(type, initializers, metaInitializers, behaviors, + propertyMap, descriptor as DictionaryDescriptor, this); + adapterType.InvokeMember("__meta", metaBindings, null, null, new[] { meta }); + + return typeBuilder.Assembly; + } + + #endregion + + #region CreateAdapterConstructor + + private static void CreateAdapterConstructor(TypeBuilder typeBuilder) + { + var constructorBuilder = typeBuilder.DefineConstructor( + MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.Standard, + new [] { typeof(DictionaryAdapterInstance) } + ); + + var ilGenerator = constructorBuilder.GetILGenerator(); + + var baseType = typeof(DictionaryAdapterBase); + var baseConstructorInfo = baseType.GetConstructors()[0]; + + ilGenerator.Emit(OpCodes.Ldarg_0); + ilGenerator.Emit(OpCodes.Ldarg_1); + ilGenerator.Emit(OpCodes.Call, baseConstructorInfo); + ilGenerator.Emit(OpCodes.Ret); + } + + #endregion + + #region CreateDictionaryAdapterMeta + + private static void CreateMetaProperty(TypeBuilder typeBuilder, PropertyInfo prop, FieldInfo field) + { + var propAttribs = MethodAttributes.Public | MethodAttributes.SpecialName | + MethodAttributes.HideBySig | MethodAttributes.ReuseSlot | + MethodAttributes.Virtual | MethodAttributes.Final; + + var getMethodBuilder = typeBuilder.DefineMethod("get_" + prop.Name, + propAttribs, prop.PropertyType, null); + + var getILGenerator = getMethodBuilder.GetILGenerator(); + if (field.IsStatic) + { + getILGenerator.Emit(OpCodes.Ldsfld, field); + } + else + { + getILGenerator.Emit(OpCodes.Ldarg_0); + getILGenerator.Emit(OpCodes.Ldfld, field); + } + getILGenerator.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(getMethodBuilder, prop.GetGetMethod()); + } + + #endregion + + #region CreateAdapterProperty + + private static void CreateAdapterProperty(TypeBuilder typeBuilder, PropertyDescriptor descriptor) + { + var property = descriptor.Property; + var propertyBuilder = typeBuilder.DefineProperty(property.Name, property.Attributes, property.PropertyType, null); + + var propAttribs = MethodAttributes.Public | MethodAttributes.SpecialName | + MethodAttributes.HideBySig | MethodAttributes.Virtual; + + if (property.CanRead) + { + CreatePropertyGetMethod(typeBuilder, propertyBuilder, descriptor, propAttribs); + } + + if (property.CanWrite) + { + CreatePropertySetMethod(typeBuilder, propertyBuilder, descriptor, propAttribs); + } + } + + private static void PreparePropertyMethod(PropertyDescriptor descriptor, ILGenerator propILGenerator) + { + propILGenerator.DeclareLocal(typeof(String)); + propILGenerator.DeclareLocal(typeof(object)); + + // key = propertyInfo.Name + propILGenerator.Emit(OpCodes.Ldstr, descriptor.PropertyName); + propILGenerator.Emit(OpCodes.Stloc_0); + } + + #endregion + + #region CreatePropertyGetMethod + + private static void CreatePropertyGetMethod(TypeBuilder typeBuilder, PropertyBuilder propertyBuilder, + PropertyDescriptor descriptor, MethodAttributes propAttribs) + { + var getMethodBuilder = typeBuilder.DefineMethod( + "get_" + descriptor.PropertyName, propAttribs, descriptor.PropertyType, null); + + var getILGenerator = getMethodBuilder.GetILGenerator(); + + var returnDefault = getILGenerator.DefineLabel(); + var storeResult = getILGenerator.DefineLabel(); + var loadResult = getILGenerator.DefineLabel(); + + PreparePropertyMethod(descriptor, getILGenerator); + + var result = getILGenerator.DeclareLocal(descriptor.PropertyType); + + // value = GetProperty(key, false) + getILGenerator.Emit(OpCodes.Ldarg_0); + getILGenerator.Emit(OpCodes.Ldloc_0); + getILGenerator.Emit(OpCodes.Ldc_I4_0); + getILGenerator.Emit(OpCodes.Callvirt, AdapterGetProperty); + getILGenerator.Emit(OpCodes.Stloc_1); + + // if (value == null) return null + getILGenerator.Emit(OpCodes.Ldloc_1); + getILGenerator.Emit(OpCodes.Brfalse_S, returnDefault); + + // return (propertyInfo.PropertyType) value + getILGenerator.Emit(OpCodes.Ldloc_1); + getILGenerator.Emit(OpCodes.Unbox_Any, descriptor.PropertyType); + getILGenerator.Emit(OpCodes.Br_S, storeResult); + + getILGenerator.MarkLabel(returnDefault); + getILGenerator.Emit(OpCodes.Ldloca_S, result); + getILGenerator.Emit(OpCodes.Initobj, descriptor.PropertyType); + getILGenerator.Emit(OpCodes.Br_S, loadResult); + + getILGenerator.MarkLabel(storeResult); + getILGenerator.Emit(OpCodes.Stloc_S, result); + + getILGenerator.MarkLabel(loadResult); + getILGenerator.Emit(OpCodes.Ldloc_S, result); + + getILGenerator.Emit(OpCodes.Ret); + + propertyBuilder.SetGetMethod(getMethodBuilder); + } + + #endregion + + #region CreatePropertySetMethod + + private static void CreatePropertySetMethod(TypeBuilder typeBuilder, PropertyBuilder propertyBuilder, + PropertyDescriptor descriptor, MethodAttributes propAttribs) + { + var setMethodBuilder = typeBuilder.DefineMethod( + "set_" + descriptor.PropertyName, propAttribs, null, new[] {descriptor.PropertyType}); + + var setILGenerator = setMethodBuilder.GetILGenerator(); + PreparePropertyMethod(descriptor, setILGenerator); + + setILGenerator.Emit(OpCodes.Ldarg_1); + if (descriptor.PropertyType.IsValueType) + { + setILGenerator.Emit(OpCodes.Box, descriptor.PropertyType); + } + setILGenerator.Emit(OpCodes.Stloc_1); + + // ignore = SetProperty(key, ref value) + setILGenerator.Emit(OpCodes.Ldarg_0); + setILGenerator.Emit(OpCodes.Ldloc_0); + setILGenerator.Emit(OpCodes.Ldloca_S, 1); + setILGenerator.Emit(OpCodes.Callvirt, AdapterSetProperty); + setILGenerator.Emit(OpCodes.Pop); + setILGenerator.Emit(OpCodes.Ret); + + propertyBuilder.SetSetMethod(setMethodBuilder); + } + + #endregion + + #region Property Descriptors + + private static Dictionary GetPropertyDescriptors( + Type type, out IDictionaryInitializer[] typeInitializers, + out IDictionaryMetaInitializer[] metaInitializers, out object[] typeBehaviors) + { + var propertyMap = new Dictionary(); + var interfaceBehaviors = typeBehaviors = ExpandBehaviors(GetInterfaceBehaviors(type)).ToArray(); + + typeInitializers = typeBehaviors.OfType().Prioritize().ToArray(); + metaInitializers = typeBehaviors.OfType().Prioritize().ToArray(); + var defaultFetch = typeBehaviors.OfType().Select(b => b.Fetch).FirstOrDefault(); + + CollectProperties(type, property => + { + var propertyBehaviors = ExpandBehaviors(GetPropertyBehaviors(property)).ToArray(); + var propertyDescriptor = new PropertyDescriptor(property, propertyBehaviors); + + var descriptorInitializers = propertyBehaviors.OfType(); + foreach (var descriptorInitializer in descriptorInitializers.OrderBy(b => b.ExecutionOrder)) + { + descriptorInitializer.Initialize(propertyDescriptor, propertyBehaviors); + } + + propertyDescriptor.AddKeyBuilders( + propertyBehaviors.OfType().Prioritize( + GetInterfaceBehaviors(property.ReflectedType)) + ); + + propertyDescriptor.AddGetters( + propertyBehaviors.OfType().Prioritize( + interfaceBehaviors.OfType()) + ); + AddDefaultGetter(propertyDescriptor); + + propertyDescriptor.AddSetters( + propertyBehaviors.OfType().Prioritize( + interfaceBehaviors.OfType()) + ); + + bool? propertyFetch = (from b in propertyBehaviors.OfType() select b.Fetch).FirstOrDefault(); + propertyDescriptor.Fetch = propertyFetch.GetValueOrDefault(defaultFetch); + + PropertyDescriptor existingDescriptor; + if (propertyMap.TryGetValue(property.Name, out existingDescriptor)) + { + var existingProperty = existingDescriptor.Property; + if (existingProperty.PropertyType == property.PropertyType) + { + if (property.CanRead && property.CanWrite) + { + propertyMap[property.Name] = propertyDescriptor; + } + return; + } + } + + propertyMap.Add(property.Name, propertyDescriptor); + }); + + return propertyMap; + } + + private static IEnumerable GetInterfaceBehaviors(Type type) where T : class + { + return AttributesUtil.GetTypeAttributes(type); + } + + private static IEnumerable GetPropertyBehaviors(MemberInfo member) where T : class + { + return AttributesUtil.GetAttributes(member); + } + + private static IEnumerable ExpandBehaviors(IEnumerable behaviors) + { + return behaviors.SelectMany(behavior => + { + if (behavior is IDictionaryBehaviorBuilder) + return ((IDictionaryBehaviorBuilder)behavior).BuildBehaviors().Cast(); + return Enumerable.Repeat(behavior, 1); + }); + } + + private static void CollectProperties(Type currentType, Action onProperty) + { + var types = new List(); + types.Add(currentType); + types.AddRange(currentType.GetInterfaces()); + var publicBindings = BindingFlags.Public | BindingFlags.Instance; + + foreach (Type type in types) + { + if (!InfrastructureTypes.Contains(type)) + { + foreach (var property in type.GetProperties(publicBindings)) + { + onProperty(property); + } + } + } + } + + private static void AddDefaultGetter(PropertyDescriptor descriptor) + { + if (descriptor.TypeConverter != null) + { + descriptor.AddGetter(new DefaultPropertyGetter(descriptor.TypeConverter)); + } + } + + private static readonly ICollection InfrastructureTypes = +#if SL3 //Silverlight 3 does not have HashSet + new List +#else + new HashSet +#endif + { + typeof (IEditableObject), + typeof (IDictionaryEdit), + typeof (IChangeTracking), + typeof (IRevertibleChangeTracking), + typeof (IDictionaryNotify), + typeof (IDataErrorInfo), + typeof (IDictionaryValidate), + typeof (IDictionaryAdapter) + }; + + #endregion + + #region Assembly Support + + private string GetAdapterAssemblyName(Type type) + { +#if SILVERLIGHT + string assemblyName; + var commaLocation = type.Assembly.FullName.IndexOf(','); + if(commaLocation>-1) + { + assemblyName = type.Assembly.FullName.Substring(0, commaLocation); + } + else + { + assemblyName = "UnnamedAssembly"; + } +#else + var assemblyName = type.Assembly.GetName().Name; +#endif + var safeTypeFullName = GetSafeTypeFullName(type); + return string.Concat(assemblyName, ".", safeTypeFullName, ".DictionaryAdapter"); + } + + private static String GetAdapterFullTypeName(Type type) + { + return type.Namespace + "." + GetAdapterTypeName(type); + } + + private static String GetAdapterTypeName(Type type) + { + return GetSafeTypeName(type).Substring(1) + "DictionaryAdapter"; + } + + public static string GetSafeTypeFullName(Type type) + { + if (type.IsGenericTypeDefinition) + { + return type.FullName.Replace("`", "_"); + } + + if (type.IsGenericType) + { + var name = new StringBuilder(); + if (!string.IsNullOrEmpty(type.Namespace)) + { + name.Append(type.Namespace).Append("."); + } + + AppendGenericTypeName(type, name); + return name.ToString(); + } + + return type.FullName; + } + + public static string GetSafeTypeName(Type type) + { + if (type.IsGenericTypeDefinition) + { + return type.Name.Replace("`", "_"); + } + + if (type.IsGenericType) + { + var name = new StringBuilder(); + AppendGenericTypeName(type, name); + return name.ToString(); + } + + return type.Name; + } + + private static void AppendGenericTypeName(Type type, StringBuilder sb) + { + // Replace back tick preceding parameter count with _ List`1 => List_1 + sb.Append(type.Name.Replace("`", "_")); + + // Append safe full name of each type argument, separated by _ + foreach (var argument in type.GetGenericArguments()) + { + sb.Append("_").Append(GetSafeTypeFullName(argument).Replace(".", "_")); + } + } + + private static Type CreateAdapterType(Type type, Assembly assembly) + { + var adapterFullTypeName = GetAdapterFullTypeName(type); + return assembly.GetType(adapterFullTypeName, true); + } + + private object CreateAdapterInstance(IDictionary dictionary, PropertyDescriptor descriptor, Type adapterType) + { + var metaBindings = BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField; + var meta = (DictionaryAdapterMeta)adapterType.InvokeMember("__meta", metaBindings, null, null, null); + var instance = new DictionaryAdapterInstance(dictionary, meta, descriptor, this); + return Activator.CreateInstance(adapterType, instance); + } + + #endregion + + #region Reflection Cache + + private static readonly PropertyInfo AdapterGetMeta = + typeof(IDictionaryAdapter).GetProperty("Meta"); + + private static readonly MethodInfo AdapterGetProperty = + typeof(IDictionaryAdapter).GetMethod("GetProperty"); + + private static readonly MethodInfo AdapterSetProperty = + typeof(IDictionaryAdapter).GetMethod("SetProperty"); + + #endregion + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterInstance.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterInstance.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterInstance.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterInstance.cs Sun Feb 13 19:28:42 2011 @@ -0,0 +1,91 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System.Collections; + using System.Collections.Generic; + using System.Linq; + + internal class DictionaryAdapterInstance + { + private IDictionary extendedProperties; + + public DictionaryAdapterInstance(IDictionary dictionary, DictionaryAdapterMeta meta, + PropertyDescriptor descriptor, IDictionaryAdapterFactory factory) + { + Dictionary = dictionary; + Descriptor = descriptor; + Factory = factory; + + Properties = meta.Properties; + Initializers = meta.Initializers; + MergeBehaviorOverrides(meta); + } + + internal int? OldHashCode { get; set; } + + public IDictionary Dictionary { get; private set; } + + public PropertyDescriptor Descriptor { get; private set; } + + public IDictionaryAdapterFactory Factory { get; private set; } + + public IDictionaryInitializer[] Initializers { get; private set; } + + public IDictionary Properties { get; private set; } + + public IDictionaryEqualityHashCodeStrategy EqualityHashCodeStrategy { get; set; } + + public IDictionaryCreateStrategy CreateStrategy { get; set; } + + public IDictionary ExtendedProperties + { + get + { + if (extendedProperties == null) + { + extendedProperties = new Dictionary(); + } + return extendedProperties; + } + } + + private void MergeBehaviorOverrides(DictionaryAdapterMeta meta) + { + if (Descriptor == null) return; + + var typeDescriptor = Descriptor as DictionaryDescriptor; + + if (typeDescriptor != null) + { + Initializers = Initializers.Prioritize(typeDescriptor.Initializers).ToArray(); + } + + Properties = new Dictionary(); + + foreach (var property in meta.Properties) + { + var propertyDescriptor = property.Value; + + var propertyOverride = new PropertyDescriptor(propertyDescriptor, false) + .AddKeyBuilders(propertyDescriptor.KeyBuilders.Prioritize(Descriptor.KeyBuilders)) + .AddGetters(propertyDescriptor.Getters.Prioritize(Descriptor.Getters)) + .AddSetters(propertyDescriptor.Setters.Prioritize(Descriptor.Setters)); + + Properties.Add(property.Key, propertyOverride); + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterMeta.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterMeta.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterMeta.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryAdapterMeta.cs Sun Feb 13 19:28:47 2011 @@ -0,0 +1,77 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + + [DebuggerDisplay("Type: {Type.FullName,nq}")] + internal class DictionaryAdapterMeta + { + private IDictionary extendedProperties; + + public DictionaryAdapterMeta(Type type, IDictionaryInitializer[] initializers, + IDictionaryMetaInitializer[] metaInitializers, + object[] behaviors, IDictionary properties, + DictionaryDescriptor descriptor, IDictionaryAdapterFactory factory) + { + Type = type; + Initializers = initializers; + MetaInitializers = metaInitializers; + Behaviors = behaviors; + Properties = properties; + + InitializeMeta(factory, descriptor); + } + + public Type Type { get; private set; } + + public object[] Behaviors { get; private set; } + + public IDictionaryInitializer[] Initializers { get; private set; } + + public IDictionaryMetaInitializer[] MetaInitializers { get; private set; } + + public IDictionary Properties { get; private set; } + + public IDictionary ExtendedProperties + { + get + { + if (extendedProperties == null) + { + extendedProperties = new Dictionary(); + } + return extendedProperties; + } + } + + private void InitializeMeta(IDictionaryAdapterFactory factory, DictionaryDescriptor descriptor) + { + if (descriptor != null) + { + MetaInitializers = MetaInitializers.Prioritize(descriptor.MetaInitializers).ToArray(); + } + + foreach (var metaInitializer in MetaInitializers) + { + metaInitializer.Initialize(factory, this); + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryDescriptor.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryDescriptor.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryDescriptor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryDescriptor.cs Sun Feb 13 19:28:53 2011 @@ -0,0 +1,205 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Linq; + using System.Collections.Generic; + using System.Reflection; + + internal class DictionaryDescriptor : PropertyDescriptor + { + private List initializers; + private List metaInitializers; + + private static readonly ICollection NoInitializers = new IDictionaryInitializer[0]; + private static readonly ICollection NoMetaInitializers = new IDictionaryMetaInitializer[0]; + + public DictionaryDescriptor() + { + } + + public DictionaryDescriptor(PropertyInfo property, object[] behaviors) + : base(property, behaviors) + { + } + + /// + /// Gets the initializers. + /// + /// The initializers. + public ICollection Initializers + { + get { return initializers ?? NoInitializers; } + } + + /// + /// Gets the meta-data initializers. + /// + /// The meta-data initializers. + public ICollection MetaInitializers + { + get { return metaInitializers ?? NoMetaInitializers; } + } + + /// + /// Adds the dictionary initializers. + /// + /// The initializers. + public DictionaryDescriptor AddInitializer(params IDictionaryInitializer[] inits) + { + return AddInitializers((IEnumerable)inits); + } + + /// + /// Adds the dictionary initializers. + /// + /// The initializers. + public DictionaryDescriptor AddInitializers(IEnumerable inits) + { + if (inits != null) + { + if (initializers == null) + { + initializers = new List(inits); + } + else + { + initializers.AddRange(inits); + } + } + return this; + } + + /// + /// Copies the initializers to the other + /// + /// + /// + public DictionaryDescriptor CopyInitializers(DictionaryDescriptor other) + { + if (initializers != null) + { + other.AddInitializers(initializers); + } + return this; + } + + /// + /// Copies the filtered initializers to the other + /// + /// + /// + /// + public DictionaryDescriptor CopyInitializers(DictionaryDescriptor other, Func selector) + { + if (selector == null) + { + throw new ArgumentNullException("selector"); + } + if (initializers != null) + { + other.AddInitializers(initializers.Where(selector)); + } + return this; + } + + /// + /// Adds the dictionary meta-data initializers. + /// + /// The meta-data initializers. + public DictionaryDescriptor AddMetaInitializer(params IDictionaryMetaInitializer[] inits) + { + return AddMetaInitializers((IEnumerable)inits); + } + + /// + /// Adds the dictionary meta-data initializers. + /// + /// The meta-data initializers. + public DictionaryDescriptor AddMetaInitializers(IEnumerable inits) + { + if (inits != null) + { + if (metaInitializers == null) + { + metaInitializers = new List(inits); + } + else + { + metaInitializers.AddRange(inits); + } + } + return this; + } + + /// + /// Copies the meta-initializers to the other + /// + /// + /// + public DictionaryDescriptor CopyMetaInitializers(DictionaryDescriptor other) + { + if (metaInitializers != null) + { + other.AddMetaInitializers(metaInitializers); + } + return this; + } + + /// + /// Copies the filtered meta-initializers to the other + /// + /// + /// + /// + public DictionaryDescriptor CopyMetaInitializers(DictionaryDescriptor other, + Func selector) + { + if (selector == null) + { + throw new ArgumentNullException("selector"); + } + if (metaInitializers != null) + { + other.AddMetaInitializers(metaInitializers.Where(selector)); + } + return this; + } + + public override PropertyDescriptor CopyBehaviors(PropertyDescriptor other) + { + if (other is DictionaryDescriptor) + { + var otherDict = (DictionaryDescriptor)other; + CopyMetaInitializers(otherDict).CopyInitializers(otherDict); + } + return base.CopyBehaviors(other); + } + + protected override void InternalAddBehavior(IDictionaryBehavior behavior) + { + if (behavior is IDictionaryInitializer) + { + AddInitializer((IDictionaryInitializer)behavior); + } + if (behavior is IDictionaryMetaInitializer) + { + AddMetaInitializer((IDictionaryMetaInitializer)behavior); + } + base.InternalAddBehavior(behavior); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryValidateGroup.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryValidateGroup.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryValidateGroup.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\DictionaryValidateGroup.cs Sun Feb 13 19:28:59 2011 @@ -0,0 +1,106 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + + internal class DictionaryValidateGroup : IDictionaryValidate, INotifyPropertyChanged, IDisposable + { + private readonly object[] groups; + private readonly IDictionaryAdapter adapter; + private readonly string[] propertyNames; + private readonly PropertyChangedEventHandler propertyChanged; + + public DictionaryValidateGroup(object[] groups, IDictionaryAdapter adapter) + { + this.groups = groups; + this.adapter = adapter; + + propertyNames = (from property in this.adapter.This.Properties.Values + from groupings in property.Behaviors.OfType() + where this.groups.Intersect(groupings.Group).Any() + select property.PropertyName).Distinct().ToArray(); + + if (propertyNames.Length > 0 && adapter.CanNotify) + { + propertyChanged += (sender, args) => + { + if (PropertyChanged != null) + PropertyChanged(this, args); + }; + this.adapter.PropertyChanged += propertyChanged; + } + } + + public event PropertyChangedEventHandler PropertyChanged; + + public bool CanValidate + { + get { return adapter.CanValidate; } + set { adapter.CanValidate = value; } + } + + public bool IsValid + { + get { return string.IsNullOrEmpty(Error); } + } + + public string Error + { + get + { + return string.Join(Environment.NewLine, + propertyNames.Select(propertyName => adapter[propertyName]) + .Where(errors => !string.IsNullOrEmpty(errors)).ToArray()); + } + } + + public string this[string columnName] + { + get + { + if (Array.IndexOf(propertyNames, columnName) >= 0) + { + return adapter[columnName]; + } + return string.Empty; + } + } + + public DictionaryValidateGroup ValidateGroups(params object[] groups) + { + groups = this.groups.Union(groups).ToArray(); + return new DictionaryValidateGroup(groups, adapter); + } + + public IEnumerable Validators + { + get { return adapter.Validators; } + } + + public void AddValidator(IDictionaryValidator validator) + { + throw new NotSupportedException(); + } + + public void Dispose() + { + adapter.PropertyChanged -= propertyChanged; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\GenericDictionaryAdapter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\GenericDictionaryAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\GenericDictionaryAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\GenericDictionaryAdapter.cs Sun Feb 13 19:35:08 2011 @@ -0,0 +1,62 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"; +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections.Generic; + + internal class GenericDictionaryAdapter : AbstractDictionaryAdapter + { + private readonly IDictionary dictionary; + + public GenericDictionaryAdapter(IDictionary dictionary) + { + this.dictionary = dictionary; + } + + public override bool IsReadOnly + { + get { return dictionary.IsReadOnly; } + } + + public override bool Contains(object key) + { + return dictionary.Keys.Contains(GetKey(key)); + } + + public override object this[object key] + { + get { return dictionary[GetKey(key)]; } + set { dictionary[GetKey(key)] = (TValue)value; } + } + + private static string GetKey(object key) + { + if (key == null) + { + throw new ArgumentNullException("key"); + } + return key.ToString(); + } + } + + internal static class GenericDictionaryAdapter + { + public static GenericDictionaryAdapter ForDictionaryAdapter(this IDictionary dictionary) + { + return new GenericDictionaryAdapter(dictionary); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapter.cs Sun Feb 13 19:29:10 2011 @@ -0,0 +1,48 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Contract for manipulating the Dictionary adapter. + /// + internal interface IDictionaryAdapter : IDictionaryEdit, IDictionaryNotify, IDictionaryValidate, IDictionaryCreate + { + DictionaryAdapterMeta Meta { get; } + + DictionaryAdapterInstance This { get; } + + string GetKey(string propertyName); + + object GetProperty(string propertyName, bool ifExists); + + object ReadProperty(string key); + + T GetPropertyOfType(string propertyName); + + bool SetProperty(string propertyName, ref object value); + + void StoreProperty(PropertyDescriptor property, string key, object value); + + void ClearProperty(PropertyDescriptor property, string key); + + void CopyTo(IDictionaryAdapter other); + + void CopyTo(IDictionaryAdapter other, Predicate selector); + + T Coerce() where T : class; + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterFactory.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterFactory.cs Sun Feb 13 19:29:15 2011 @@ -0,0 +1,125 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; +#if !SILVERLIGHT + using System.Collections.Specialized; + using System.Xml.XPath; +#endif + + /// + /// Defines the contract for building typed dictionary adapters. + /// + internal interface IDictionaryAdapterFactory + { + /// + /// Gets a typed adapter bound to the . + /// + /// The typed interface. + /// The underlying source of properties. + /// An implementation of the typed interface bound to the dictionary. + /// + /// The type represented by T must be an interface with properties. + /// + T GetAdapter(IDictionary dictionary); + + /// + /// Gets a typed adapter bound to the . + /// + /// The typed interface. + /// The underlying source of properties. + /// An implementation of the typed interface bound to the dictionary. + /// + /// The type represented by T must be an interface with properties. + /// + object GetAdapter(Type type, IDictionary dictionary); + + /// + /// Gets a typed adapter bound to the . + /// + /// The typed interface. + /// The underlying source of properties. + /// The property descriptor. + /// An implementation of the typed interface bound to the dictionary. + /// + /// The type represented by T must be an interface with properties. + /// + object GetAdapter(Type type, IDictionary dictionary, PropertyDescriptor descriptor); + +#if !SILVERLIGHT + /// + /// Gets a typed adapter bound to the . + /// + /// The typed interface. + /// The underlying source of properties. + /// An implementation of the typed interface bound to the namedValues. + /// + /// The type represented by T must be an interface with properties. + /// + T GetAdapter(NameValueCollection nameValues); + + /// + /// Gets a typed adapter bound to the . + /// + /// The typed interface. + /// The underlying source of properties. + /// An implementation of the typed interface bound to the namedValues. + /// + /// The type represented by T must be an interface with properties. + /// + object GetAdapter(Type type, NameValueCollection nameValues); + + /// + /// Gets a typed adapter bound to the . + /// + /// The typed interface. + /// The underlying source of properties. + /// An implementation of the typed interface bound to the xpath navigable. + /// + /// The type represented by T must be an interface with properties. + /// + T GetAdapter(IXPathNavigable xpathNavigable); + + /// + /// Gets a typed adapter bound to the . + /// + /// The typed interface. + /// The underlying source of properties. + /// An implementation of the typed interface bound to the xpath navigable. + /// + /// The type represented by T must be an interface with properties. + /// + object GetAdapter(Type type, IXPathNavigable xpathNavigable); +#endif + + /// + /// Gets the associated with the type. + /// + /// The typed interface. + /// The adapter meta-data. + DictionaryAdapterMeta GetAdapterMeta(Type type); + + /// + /// Gets the associated with the type. + /// + /// The typed interface. + /// The property descriptor. + /// The adapter meta-data. + DictionaryAdapterMeta GetAdapterMeta(Type type, PropertyDescriptor descriptor); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterVisitor.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterVisitor.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterVisitor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryAdapterVisitor.cs Sun Feb 13 19:29:20 2011 @@ -0,0 +1,33 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + /// + /// Conract for traversing a . + /// + internal interface IDictionaryAdapterVisitor + { + void VisitDictionaryAdapter(IDictionaryAdapter dictionaryAdapter); + + void VisitProperty(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property); + + void VisitInterface(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property); + + void VisitCollection(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property, + Type collectionItemType); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehavior.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehavior.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehavior.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehavior.cs Sun Feb 13 19:29:26 2011 @@ -0,0 +1,27 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + /// + /// Defines the contract for customizing dictionary access. + /// + internal interface IDictionaryBehavior + { + /// + /// Determines relative order to apply related behaviors. + /// + int ExecutionOrder { get; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehaviorBuilder.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehaviorBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehaviorBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryBehaviorBuilder.cs Sun Feb 13 19:29:32 2011 @@ -0,0 +1,30 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System.Collections.Generic; + + /// + /// Defines the contract for building s. + /// + internal interface IDictionaryBehaviorBuilder + { + /// + /// Builds the dictionary behaviors. + /// + /// + IEnumerable BuildBehaviors(); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreate.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreate.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreate.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreate.cs Sun Feb 13 19:29:38 2011 @@ -0,0 +1,37 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Contract for creating additional Dictionary adapters. + /// + internal interface IDictionaryCreate + { + T Create(); + + object Create(Type type); + + T Create(IDictionary dictionary); + + object Create(Type type, IDictionary dictionary); + + T Create(Action init); + + T Create(IDictionary dictionary, Action init); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreateStrategy.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreateStrategy.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreateStrategy.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryCreateStrategy.cs Sun Feb 13 19:29:51 2011 @@ -0,0 +1,24 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + internal interface IDictionaryCreateStrategy + { + object Create(IDictionaryAdapter adapter, Type type, IDictionary dictionary); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEdit.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEdit.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEdit.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEdit.cs Sun Feb 13 19:29:57 2011 @@ -0,0 +1,37 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.ComponentModel; + + /// + /// Contract for editing the Dictionary adapter. + /// + internal interface IDictionaryEdit : IEditableObject, IRevertibleChangeTracking + { + bool CanEdit { get; } + + bool IsEditing { get; } + + bool SupportsMultiLevelEdit { get; set; } + + IDisposable SuppressEditingBlock(); + + void SuppressEditing(); + + void ResumeEditing(); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEqualityHashCodeStrategy.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEqualityHashCodeStrategy.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEqualityHashCodeStrategy.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryEqualityHashCodeStrategy.cs Sun Feb 13 19:30:02 2011 @@ -0,0 +1,23 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + internal interface IDictionaryEqualityHashCodeStrategy + { + bool Equals(IDictionaryAdapter adapter1, IDictionaryAdapter adapter2); + + bool GetHashCode(IDictionaryAdapter adapter, out int hashCode); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryInitializer.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryInitializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryInitializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryInitializer.cs Sun Feb 13 19:30:09 2011 @@ -0,0 +1,29 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + /// + /// Contract for dictionary initialization. + /// + internal interface IDictionaryInitializer : IDictionaryBehavior + { + /// + /// Performs any initialization of the + /// + /// The dictionary adapter. + /// The dictionary behaviors. + void Initialize(IDictionaryAdapter dictionaryAdapter, object[] behaviors); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryKeyBuilder.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryKeyBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryKeyBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryKeyBuilder.cs Sun Feb 13 19:30:14 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + + /// + /// Defines the contract for building typed dictionary keys. + /// + internal interface IDictionaryKeyBuilder : IDictionaryBehavior + { + /// + /// Builds the specified key. + /// + /// The dictionary adapter. + /// The current key. + /// The property. + /// The updated key + String GetKey(IDictionaryAdapter dictionaryAdapter, String key, PropertyDescriptor property); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryMetaInitializer.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryMetaInitializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryMetaInitializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryMetaInitializer.cs Sun Feb 13 19:30:20 2011 @@ -0,0 +1,30 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + /// + /// Contract for dictionary meta-data initialization. + /// + internal interface IDictionaryMetaInitializer : IDictionaryBehavior + { + /// + /// Performs any initialization of the dictionary adapter meta-data. + /// + /// The dictionary adapter factory. + /// The dictionary adapter meta. + /// + void Initialize(IDictionaryAdapterFactory factory, DictionaryAdapterMeta dictionaryMeta); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryNotify.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryNotify.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryNotify.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryNotify.cs Sun Feb 13 20:03:05 2011 @@ -0,0 +1,81 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.ComponentModel; + + #region Class PropertyModifiedEventArgs + + internal class PropertyModifiedEventArgs : PropertyChangedEventArgs + { + public PropertyModifiedEventArgs(String propertyName, object oldPropertyValue, object newPropertyValue) + : base(propertyName) + { + OldPropertyValue = oldPropertyValue; + NewPropertyValue = newPropertyValue; + } + + public object OldPropertyValue { get; private set; } + + public object NewPropertyValue { get; private set; } + } + + #endregion + + #region Class PropertyModifyingEventArgs + + internal class PropertyModifyingEventArgs : PropertyChangingEventArgs + { + public PropertyModifyingEventArgs(String propertyName, object oldPropertyValue, object newPropertyValue) + : base(propertyName) + { + OldPropertyValue = oldPropertyValue; + NewPropertyValue = newPropertyValue; + } + + public object OldPropertyValue { get; private set; } + + public object NewPropertyValue { get; private set; } + + public bool Cancel { get; set; } + } + + internal delegate void PropertyModifyingEventHandler(object sender, PropertyModifyingEventArgs e); + + #endregion + + /// + /// Contract for managing Dictionary adapter notifications. + /// + internal interface IDictionaryNotify : +#if !SILVERLIGHT + INotifyPropertyChanging, +#endif + INotifyPropertyChanged + { + bool CanNotify { get; } + + bool ShouldNotify { get; } + + bool PropagateChildNotifications { get; set; } + + IDisposable SuppressNotificationsBlock(); + + void SuppressNotifications(); + + void ResumeNotifications(); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertyGetter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertyGetter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertyGetter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertyGetter.cs Sun Feb 13 19:30:34 2011 @@ -0,0 +1,36 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System.Collections; + + /// + /// Defines the contract for retrieving dictionary values. + /// + internal interface IDictionaryPropertyGetter : IDictionaryBehavior + { + /// + /// Gets the effective dictionary value. + /// + /// The dictionary adapter. + /// The key. + /// The stored value. + /// The property. + /// true if return only existing. + /// The effective property value. + object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, + object storedValue, PropertyDescriptor property, bool ifExists); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertySetter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertySetter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertySetter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryPropertySetter.cs Sun Feb 13 19:30:38 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + + /// + /// Defines the contract for updating dictionary values. + /// + internal interface IDictionaryPropertySetter : IDictionaryBehavior + { + /// + /// Sets the stored dictionary value. + /// + /// The dictionary adapter. + /// The key. + /// The stored value. + /// The property. + /// true if the property should be stored. + bool SetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, ref object value, + PropertyDescriptor property); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidate.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidate.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidate.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidate.cs Sun Feb 13 19:30:43 2011 @@ -0,0 +1,35 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System.Collections.Generic; + using System.ComponentModel; + + /// + /// Contract for validating Dictionary adapter. + /// + internal interface IDictionaryValidate : IDataErrorInfo, INotifyPropertyChanged + { + bool CanValidate { get; set; } + + bool IsValid { get; } + + DictionaryValidateGroup ValidateGroups(params object[] groups); + + IEnumerable Validators { get; } + + void AddValidator(IDictionaryValidator validator); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidator.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidator.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IDictionaryValidator.cs Sun Feb 13 19:30:48 2011 @@ -0,0 +1,50 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + /// + /// Contract for dictionary validation. + /// + internal interface IDictionaryValidator + { + /// + /// Determines if is valid. + /// + /// The dictionary adapter. + /// true if valid. + bool IsValid(IDictionaryAdapter dictionaryAdapter); + + /// + /// Validates the . + /// + /// The dictionary adapter. + /// The error summary information. + string Validate(IDictionaryAdapter dictionaryAdapter); + + /// + /// Validates the for a property. + /// + /// The dictionary adapter. + /// The property to validate. + /// The property summary information. + string Validate(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property); + + /// + /// Invalidates any results cached by the validator. + /// + /// The dictionary adapter. + void Invalidate(IDictionaryAdapter dictionaryAdapter); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IPropertyDescriptorInitializer.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IPropertyDescriptorInitializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IPropertyDescriptorInitializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IPropertyDescriptorInitializer.cs Sun Feb 13 19:30:53 2011 @@ -0,0 +1,29 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + /// + /// Contract for property descriptor initialization. + /// + internal interface IPropertyDescriptorInitializer : IDictionaryBehavior + { + /// + /// Performs any initialization of the + /// + /// The property descriptor. + /// The property behaviors. + void Initialize(PropertyDescriptor propertyDescriptor, object[] behaviors); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IXPathSerializer.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IXPathSerializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\IXPathSerializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\IXPathSerializer.cs Sun Feb 13 19:30:58 2011 @@ -0,0 +1,28 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT + +namespace Castle.Components.DictionaryAdapter +{ + using System.Xml.XPath; + + internal interface IXPathSerializer + { + bool WriteObject(XPathResult result, XPathNavigator node, object value); + + bool ReadObject(XPathResult result, XPathNavigator node, out object value); + } +} +#endif \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\NameValueCollectionAdapter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\NameValueCollectionAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\NameValueCollectionAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\NameValueCollectionAdapter.cs Sun Feb 13 19:31:04 2011 @@ -0,0 +1,85 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if! SILVERLIGHT + using System; + using System.Collections.Specialized; + + /// + /// + /// + internal class NameValueCollectionAdapter : AbstractDictionaryAdapter + { + private readonly NameValueCollection nameValues; + + /// + /// Initializes a new instance of the class. + /// + /// The name values. + public NameValueCollectionAdapter(NameValueCollection nameValues) + { + this.nameValues = nameValues; + } + + /// + /// Gets a value indicating whether the object is read-only. + /// + /// + /// true if the object is read-only; otherwise, false. + public override bool IsReadOnly + { + get { return false; } + } + + /// + /// Determines whether the object contains an element with the specified key. + /// + /// The key to locate in the object. + /// + /// true if the contains an element with the key; otherwise, false. + /// + /// key is null. + public override bool Contains(object key) + { + return Array.IndexOf(nameValues.AllKeys, key) >= 0; + } + + /// + /// Gets or sets the with the specified key. + /// + /// + public override object this[object key] + { + get { return nameValues[key.ToString()]; } + set + { + String val = (value != null) ? value.ToString() : null; + nameValues[key.ToString()] = val; + } + } + + /// + /// Adapts the specified name values. + /// + /// The name values. + /// + public static NameValueCollectionAdapter Adapt(NameValueCollection nameValues) + { + return new NameValueCollectionAdapter(nameValues); + } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\PropertyDescriptor.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\PropertyDescriptor.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\PropertyDescriptor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\PropertyDescriptor.cs Sun Feb 13 19:31:10 2011 @@ -0,0 +1,560 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Linq; + using System.Collections; + using System.Collections.Generic; + using System.ComponentModel; + using System.Reflection; + using System.Diagnostics; + + using Castle.Core.Internal; + + /// + /// Describes a dictionary property. + /// + [DebuggerDisplay("{Property.DeclaringType.FullName,nq}.{PropertyName,nq}")] + internal class PropertyDescriptor : IDictionaryKeyBuilder, IDictionaryPropertyGetter, IDictionaryPropertySetter + { + private List getters; + private List setters; + private List keyBuilders; + private IDictionary state; + + private static readonly object[] NoBehaviors = new object[0]; + private static readonly ICollection NoKeysBuilders = new IDictionaryKeyBuilder[0]; + private static readonly ICollection NoHGetters = new IDictionaryPropertyGetter[0]; + private static readonly ICollection NoSetters = new IDictionaryPropertySetter[0]; + + /// + /// Initializes an empty class. + /// + public PropertyDescriptor() + { + Behaviors = NoBehaviors; + } + + /// + /// Initializes a new instance of the class. + /// + /// The property. + /// The property behaviors. + public PropertyDescriptor(PropertyInfo property, object[] behaviors) : this() + { + Property = property; + Behaviors = behaviors ?? NoBehaviors; + IsDynamicProperty = typeof(IDynamicValue).IsAssignableFrom(property.PropertyType); + ObtainTypeConverter(); + } + + /// + /// Copies an existinginstance of the class. + /// + /// + /// + public PropertyDescriptor(PropertyDescriptor source, bool copyBehaviors) + { + Property = source.Property; + Behaviors = source.Behaviors; + IsDynamicProperty = source.IsDynamicProperty; + TypeConverter = source.TypeConverter; + SuppressNotifications = source.SuppressNotifications; + state = source.state; + Fetch = source.Fetch; + + if (copyBehaviors) + { + keyBuilders = source.keyBuilders; + getters = source.getters; + setters = source.setters; + } + } + + /// + /// + /// + public int ExecutionOrder + { + get { return 0; } + } + + /// + /// Gets the property name. + /// + public string PropertyName + { + get { return (Property != null) ? Property.Name : null; } + } + + /// + /// Gets the property type. + /// + public Type PropertyType + { + get { return (Property != null) ? Property.PropertyType : null; } + } + + /// + /// Gets the property. + /// + /// The property. + public PropertyInfo Property { get; private set; } + + /// + /// Returns true if the property is dynamic. + /// + public bool IsDynamicProperty { get; private set; } + + /// + /// Gets additional state. + /// + public IDictionary State + { + get + { + if (state == null) + { + state = new Dictionary(); + } + return state; + } + } + + /// + /// Determines if property should be fetched. + /// + public bool Fetch { get; set; } + + /// + /// Determines if notifications should occur. + /// + public bool SuppressNotifications { get; set; } + + /// + /// Gets the property behaviors. + /// + public object[] Behaviors { get; private set; } + + /// + /// Gets the type converter. + /// + /// The type converter. + public TypeConverter TypeConverter { get; private set; } + + /// + /// Gets the key builders. + /// + /// The key builders. + public ICollection KeyBuilders + { + get { return keyBuilders ?? NoKeysBuilders; } + } + + /// + /// Gets the setter. + /// + /// The setter. + public ICollection Setters + { + get { return setters ?? NoSetters; } + } + + /// + /// Gets the getter. + /// + /// The getter. + public ICollection Getters + { + get { return getters ?? NoHGetters; } + } + + #region IDictionaryKeyBuilder Members + + /// + /// Gets the key. + /// + /// The dictionary adapter. + /// The key. + /// The descriptor. + /// + public string GetKey(IDictionaryAdapter dictionaryAdapter, String key, PropertyDescriptor descriptor) + { + if (keyBuilders != null) + { + foreach (var builder in keyBuilders) + { + key = builder.GetKey(dictionaryAdapter, key, this); + } + } + + return key; + } + + /// + /// Adds the key builder. + /// + /// The builder. + public PropertyDescriptor AddKeyBuilder(params IDictionaryKeyBuilder[] builders) + { + return AddKeyBuilders((IEnumerable)builders); + } + + /// + /// Adds the key builders. + /// + /// The builders. + public PropertyDescriptor AddKeyBuilders(IEnumerable builders) + { + if (builders != null) + { + if (keyBuilders == null) + { + keyBuilders = new List(builders); + } + else + { + keyBuilders.AddRange(builders); + } + } + return this; + } + + /// + /// Copies the key builders to the other + /// + /// + /// + public PropertyDescriptor CopyKeyBuilders(PropertyDescriptor other) + { + if (keyBuilders != null) + { + other.AddKeyBuilders(keyBuilders); + } + return this; + } + + /// + /// Copies the selected key builders to the other + /// + /// + /// + /// + public PropertyDescriptor CopyKeyBuilders(PropertyDescriptor other, Func selector) + { + if (selector == null) + { + throw new ArgumentNullException("selector"); + } + if (keyBuilders != null) + { + other.AddKeyBuilders(keyBuilders.Where(selector)); + } + return this; + } + + #endregion + + #region IDictionaryPropertyGetter Members + + /// + /// Gets the property value. + /// + /// The dictionary adapter. + /// The key. + /// The stored value. + /// The descriptor. + /// true if return only existing. + /// + public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, object storedValue, PropertyDescriptor descriptor, bool ifExists) + { + key = GetKey(dictionaryAdapter, key, descriptor); + storedValue = storedValue ?? dictionaryAdapter.ReadProperty(key); + + if (getters != null) + { + foreach (var getter in getters) + { + storedValue = getter.GetPropertyValue(dictionaryAdapter, key, storedValue, this, ifExists); + } + } + + return storedValue; + } + + /// + /// Adds the dictionary getter. + /// + /// The getter. + public PropertyDescriptor AddGetter(params IDictionaryPropertyGetter[] getters) + { + return AddGetters((IEnumerable)getters); + } + + /// + /// Adds the dictionary getters. + /// + /// The getters. + public PropertyDescriptor AddGetters(IEnumerable gets) + { + if (gets != null) + { + if (getters == null) + { + getters = new List(gets); + } + else + { + getters.AddRange(gets); + } + } + return this; + } + + /// + /// Copies the property getters to the other + /// + /// + /// + public PropertyDescriptor CopyGetters(PropertyDescriptor other) + { + if (getters != null) + { + other.AddGetters(getters); + } + return this; + } + + /// + /// Copies the selected property getters to the other + /// + /// + /// + /// + public PropertyDescriptor CopyGetters(PropertyDescriptor other, Func selector) + { + if (selector == null) + { + throw new ArgumentNullException("selector"); + } + if (getters != null) + { + other.AddGetters(getters.Where(selector)); + } + return this; + } + + #endregion + + #region IDictionaryPropertySetter Members + + /// + /// Sets the property value. + /// + /// The dictionary adapter. + /// The key. + /// The value. + /// The descriptor. + /// + public bool SetPropertyValue(IDictionaryAdapter dictionaryAdapter, + string key, ref object value, PropertyDescriptor descriptor) + { + bool consumed = false; + + key = GetKey(dictionaryAdapter, key, descriptor); + + if (setters != null) + { + foreach(var setter in setters) + { + if (!setter.SetPropertyValue(dictionaryAdapter, key, ref value, this)) + { + consumed = true; + } + } + } + + if (!consumed) + { + dictionaryAdapter.StoreProperty(this, key, value); + } + + return !consumed; + } + + /// + /// Adds the dictionary setter. + /// + /// The setter. + public PropertyDescriptor AddSetter(params IDictionaryPropertySetter[] setters) + { + return AddSetters((IEnumerable)setters); + } + + /// + /// Adds the dictionary setters. + /// + /// The setters. + public PropertyDescriptor AddSetters(IEnumerable sets) + { + if (sets != null) + { + if (setters == null) + { + setters = new List(sets); + } + else + { + setters.AddRange(sets); + } + } + return this; + } + + /// + /// Copies the property setters to the other + /// + /// + /// + public PropertyDescriptor CopySetters(PropertyDescriptor other) + { + if (setters != null) + { + other.AddSetters(setters); + } + return this; + } + + /// + /// Copies the selected property setters to the other + /// + /// + /// + /// + public PropertyDescriptor CopySetters(PropertyDescriptor other, Func selector) + { + if (selector == null) + { + throw new ArgumentNullException("selector"); + } + if (setters != null) + { + other.AddSetters(setters.Where(selector)); + } + return this; + } + + #endregion + + /// + /// Adds the behaviors. + /// + /// + /// + public PropertyDescriptor AddBehavior(params IDictionaryBehavior[] behaviors) + { + return AddBehaviors((IEnumerable)behaviors); + } + + /// + /// Adds the behaviors. + /// + /// + /// + public PropertyDescriptor AddBehaviors(IEnumerable behaviors) + { + if (behaviors != null) + { + foreach (var behavior in behaviors) + { + InternalAddBehavior(behavior); + } + } + return this; + } + + /// + /// Adds the behaviors from the builders. + /// + /// + /// + public PropertyDescriptor AddBehaviors(params IDictionaryBehaviorBuilder[] builders) + { + AddBehaviors(builders.SelectMany(builder => builder.BuildBehaviors())); + return this; + } + + /// + /// Copies the behaviors to the other + /// + /// + /// + public virtual PropertyDescriptor CopyBehaviors(PropertyDescriptor other) + { + return CopyKeyBuilders(other).CopyGetters(other).CopySetters(other); + } + + /// + /// Copies the behaviors to the other + /// + /// + /// + /// + public PropertyDescriptor CopyBehaviors(PropertyDescriptor other, Func selector) + { + if (selector == null) + { + throw new ArgumentNullException("selector"); + } + return CopyKeyBuilders(other, key => selector(key)) + .CopyGetters(other, getter => selector(getter)) + .CopySetters(other, setter => selector(setter)); + } + + protected virtual void InternalAddBehavior(IDictionaryBehavior behavior) + { + if (behavior is IDictionaryKeyBuilder) + { + AddKeyBuilder((IDictionaryKeyBuilder)behavior); + } + + if (behavior is IDictionaryPropertyGetter) + { + AddGetter((IDictionaryPropertyGetter)behavior); + } + + if (behavior is IDictionaryPropertySetter) + { + AddSetter((IDictionaryPropertySetter)behavior); + } + } + + private void ObtainTypeConverter() + { + var converterType = AttributesUtil.GetTypeConverter(Property); + + if (converterType != null) + { + TypeConverter = (TypeConverter) Activator.CreateInstance(converterType); + } + else + { + TypeConverter = TypeDescriptor.GetConverter(PropertyType); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BehaviorVisitor.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BehaviorVisitor.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BehaviorVisitor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BehaviorVisitor.cs Sun Feb 13 19:32:52 2011 @@ -0,0 +1,78 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + using System.Collections.Generic; + + internal class BehaviorVisitor + { + private List, Func>> conditions; + + public BehaviorVisitor() + { + conditions = new List, Func>>(); + } + + public BehaviorVisitor OfType(Func apply) + { + return AddCondition(b => b is T, b => apply((T)b)); + } + + public BehaviorVisitor OfType(Action apply) + { + return AddCondition(b => b is T, b => { apply((T)b); return true; }); + } + + public BehaviorVisitor Match(Func match, Func apply) + { + return AddCondition(b => b is T && match((T)b), b => apply((T)b)); + } + + public BehaviorVisitor Match(Func match, Action apply) + { + return AddCondition(b => b is T && match((T)b), b => { apply((T)b); return true; }); + } + + public BehaviorVisitor Match(Func match, Func apply) + { + return Match(match, apply); + } + + public BehaviorVisitor Match(Func match, Action apply) + { + return Match(match, apply); + } + + public void Apply(IEnumerable behaviors) + { + foreach (var behavior in behaviors) + foreach (var condition in conditions) + { + if (condition.Key(behavior)) + { + condition.Value(behavior); + } + } + } + + private BehaviorVisitor AddCondition(Func predicate, Func action) + { + conditions.Add(new KeyValuePair, Func>(predicate, action)); + return this; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BindingListInitializer.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BindingListInitializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BindingListInitializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\BindingListInitializer.cs Sun Feb 13 19:32:41 2011 @@ -0,0 +1,77 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if !SILVERLIGHT + using System; + using System.ComponentModel; + + internal class BindingListInitializer : IValueInitializer + { + private readonly Action addAt; + private readonly Func addNew; + private readonly Action setAt; + private readonly Action removeAt; + private bool addingNew; + + public BindingListInitializer(Action addAt, Func addNew, + Action setAt, Action removeAt) + { + this.addAt = addAt; + this.addNew = addNew; + this.setAt = setAt; + this.removeAt = removeAt; + } + + public void Initialize(IDictionaryAdapter dictionaryAdapter, object value) + { + var bindingList = (BindingList)value; + if (addNew != null) + { + bindingList.AddingNew += (sender, args) => + { + args.NewObject = addNew(); + addingNew = true; + }; + } + bindingList.ListChanged += (sender, args) => + { + switch (args.ListChangedType) + { + case ListChangedType.ItemAdded: + if (addingNew == false && addAt != null) + { + addAt(args.NewIndex, bindingList[args.NewIndex]); + } + addingNew = false; + break; + case ListChangedType.ItemChanged: + if (setAt != null) + { + setAt(args.NewIndex, bindingList[args.NewIndex]); + } + break; + case ListChangedType.ItemDeleted: + if (removeAt != null) + { + removeAt(args.NewIndex); + } + break; + } + }; + } + } +#endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValue.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValue.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValue.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValue.cs Sun Feb 13 19:32:34 2011 @@ -0,0 +1,36 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + internal abstract class DynamicValue : IDynamicValue + { + object IDynamicValue.GetValue() + { + return Value; + } + + public abstract T Value { get; } + + public override string ToString() + { + var value = Value; + if (value != null) + { + return value.ToString(); + } + return base.ToString(); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValueDelegate.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValueDelegate.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValueDelegate.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\DynamicValueDelegate.cs Sun Feb 13 19:32:22 2011 @@ -0,0 +1,33 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + + internal class DynamicValueDelegate : DynamicValue + { + private readonly Func dynamicDelegate; + + public DynamicValueDelegate(Func dynamicDelegate) + { + this.dynamicDelegate = dynamicDelegate; + } + + public override T Value + { + get { return dynamicDelegate(); } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableBindingList.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableBindingList.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableBindingList.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableBindingList.cs Sun Feb 13 19:32:12 2011 @@ -0,0 +1,96 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if !SILVERLIGHT + using System.Collections.Generic; + using System.ComponentModel; + + internal class EditableBindingList : BindingList, IList, IEditableObject, IRevertibleChangeTracking + { + private bool isEditing; + private List snapshot; + + public EditableBindingList() + { + } + + public EditableBindingList(IList initial) + : base(initial) + { + } + + public bool IsChanged + { + get + { + if (snapshot == null || snapshot.Count != Count) + return false; + + var items = GetEnumerator(); + var snapshotItems = snapshot.GetEnumerator(); + + while (items.MoveNext() && snapshotItems.MoveNext()) + { + if (ReferenceEquals(items.Current, snapshotItems.Current) == false) + return false; + + var tracked = items.Current as IChangeTracking; + if (tracked != null && tracked.IsChanged) + return true; + } + + return false; + } + } + + public void BeginEdit() + { + if (!isEditing) + { + snapshot = new List(this); + isEditing = true; + } + } + + public void EndEdit() + { + isEditing = false; + snapshot = null; + } + + public void CancelEdit() + { + if (isEditing) + { + Clear(); + foreach (var item in snapshot) Add(item); + snapshot = null; + isEditing = false; + } + } + + public void AcceptChanges() + { + BeginEdit(); + } + + public void RejectChanges() + { + CancelEdit(); + } + } +#endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableList.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableList.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableList.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\EditableList.cs Sun Feb 13 19:35:14 2011 @@ -0,0 +1,91 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System.Collections; + using System.Collections.Generic; + using System.ComponentModel; + + internal class EditableList : List, IEditableObject, IRevertibleChangeTracking + { + private bool isEditing; + private List snapshot; + + public void BeginEdit() + { + if (!isEditing) + { + snapshot = new List(this); + isEditing = true; + } + } + + public bool IsChanged + { + get + { + if (snapshot == null || snapshot.Count != Count) + return false; + + var items = GetEnumerator(); + var snapshotItems = snapshot.GetEnumerator(); + + while (items.MoveNext() && snapshotItems.MoveNext()) + { + if (ReferenceEquals(items.Current, snapshotItems.Current) == false) + return false; + + var tracked = items.Current as IChangeTracking; + if (tracked != null && tracked.IsChanged) + return true; + } + + return false; + } + } + + public void EndEdit() + { + isEditing = false; + snapshot = null; + } + + public void CancelEdit() + { + if (isEditing) + { + Clear(); + AddRange(snapshot); + snapshot = null; + isEditing = false; + } + } + + public void AcceptChanges() + { + BeginEdit(); + } + + public void RejectChanges() + { + CancelEdit(); + } + } + + internal class EditableList : EditableList, IList + { + + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IDynamicValue.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IDynamicValue.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IDynamicValue.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IDynamicValue.cs Sun Feb 13 19:32:01 2011 @@ -0,0 +1,33 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + /// + /// Contract for dynamic value resolution. + /// + internal interface IDynamicValue + { + object GetValue(); + } + + /// + /// Contract for typed dynamic value resolution. + /// + /// + internal interface IDynamicValue : IDynamicValue + { + T Value { get; } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IValueInitializer.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IValueInitializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IValueInitializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\IValueInitializer.cs Sun Feb 13 19:31:53 2011 @@ -0,0 +1,7 @@ +namespace Castle.Components.DictionaryAdapter +{ + internal interface IValueInitializer + { + void Initialize(IDictionaryAdapter dictionaryAdapter, object value); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\PriorityBehavior.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\PriorityBehavior.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\Util\PriorityBehavior.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\Util\PriorityBehavior.cs Sun Feb 13 18:56:54 2011 @@ -0,0 +1,59 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections.Generic; + using System.Linq; + + static class PriorityBehaviorExtensions + { + class PriorityBehavior : IComparable> where T : IDictionaryBehavior + { + public PriorityBehavior(T behavior, int priority) + { + Behavior = behavior; + Priority = priority; + } + + public T Behavior { get; private set; } + + public int Priority { get; private set; } + + public int CompareTo(PriorityBehavior other) + { + var order = Behavior.ExecutionOrder - other.Behavior.ExecutionOrder; + return (order == 0) ? Priority - other.Priority : order; + } + } + + public static IEnumerable Prioritize(this IEnumerable first, params IEnumerable[] remaining) + where T : IDictionaryBehavior + { + var allBehaviors = new[] { first }.Union(remaining).Where(behaviors => behaviors != null && behaviors.Any()).ToArray(); + + switch (allBehaviors.Length) + { + case 0: + return Enumerable.Empty(); + case 1: + return allBehaviors[0].OrderBy(behavior => behavior.ExecutionOrder); + default: + return allBehaviors.SelectMany((bs, priority) => bs.Select(b => new PriorityBehavior(b, priority))) + .OrderBy(priority => priority).Select(priority => priority.Behavior);; + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathAdapter.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathAdapter.cs Sun Feb 13 19:31:16 2011 @@ -0,0 +1,693 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.f +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if !SILVERLIGHT + using System; + using System.Collections; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + using System.Xml; + using System.Xml.Serialization; + using System.Xml.XPath; + + internal class XPathAdapter : DictionaryBehaviorAttribute, IDictionaryInitializer, + IDictionaryPropertyGetter, IDictionaryPropertySetter, + IDictionaryCreateStrategy + { + private readonly Func createRoot; + private XPathNavigator root; + private XmlMetadata xmlMeta; + + public XPathNavigator Root + { + get { return EnsureOffRoot(); } + } + + public XPathAdapter Parent { get; private set; } + + public IXPathNavigable Source { get; private set; } + + public XPathContext Context { get; private set; } + + #region Init + + public XPathAdapter() : this(new XmlDocument()) + { + } + + public XPathAdapter(IXPathNavigable source) + { + Source = source; + Context = new XPathContext(); + root = source.CreateNavigator(); + } + + protected XPathAdapter(XPathNavigator source, XPathAdapter parent) + { + Parent = parent; + Context = parent.Context.CreateChild(); + root = source.Clone(); + } + + protected XPathAdapter(Func createSource, XPathAdapter parent) + { + Parent = parent; + Context = parent.Context.CreateChild(); + createRoot = createSource; + } + + void IDictionaryInitializer.Initialize(IDictionaryAdapter dictionaryAdapter, object[] behaviors) + { + var meta = dictionaryAdapter.Meta; + if (meta.MetaInitializers.OfType().FirstOrDefault() == null) + { + throw new InvalidOperationException(string.Format( + "Interface {0} requested xpath support, but was not configured properly. " + + "Did you forget to add an XPathBehavior?", meta.Type.FullName)); + } + + dictionaryAdapter.This.CreateStrategy = this; + + Context.ApplyBehaviors(behaviors); + xmlMeta = dictionaryAdapter.GetXmlMeta(); + + if (string.IsNullOrEmpty(xmlMeta.XmlType.Namespace) == false) + { + Context.AddNamespace(string.Empty, xmlMeta.XmlType.Namespace); + } + + if (Parent == null) + { + foreach (var behavior in behaviors) + { + if (behavior is XPathAttribute) + { + var attrib = (XPathAttribute)behavior; + var compiledExpression = attrib.CompiledExpression; + if (MoveOffRoot(root, XPathNodeType.Element) == false || Context.Matches(compiledExpression, root)) + { + break; + } + + var navigator = Context.SelectSingleNode(compiledExpression, root); + if (navigator != null) + { + root = navigator; + break; + } + } + } + MoveOffRoot(root, XPathNodeType.Element); + } + } + + #endregion + + #region Behaviors + + object IDictionaryPropertyGetter.GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, + object storedValue, PropertyDescriptor property, bool ifExists) + { + if (ShouldIgnoreProperty(property)) + { + return storedValue; + } + + var cached = dictionaryAdapter.This.ExtendedProperties[property.PropertyName]; + if (cached != null) return cached; + + var result = EvaluateProperty(key, property, dictionaryAdapter); + return ReadProperty(result, ifExists, dictionaryAdapter); + } + + bool IDictionaryPropertySetter.SetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, + ref object value, PropertyDescriptor property) + { + if (ShouldIgnoreProperty(property)) + { + return true; + } + + EnsureOffRoot(); + + if (root.CanEdit) + { + var result = EvaluateProperty(key, property, dictionaryAdapter); + if (result.CanWrite) + { + WriteProperty(result, value, dictionaryAdapter); + } + } + + return false; + } + + object IDictionaryCreateStrategy.Create(IDictionaryAdapter adapter, Type type, IDictionary dictionary) + { + dictionary = dictionary ?? new Hashtable(); + var descriptor = new DictionaryDescriptor(); + adapter.This.Descriptor.CopyBehaviors(descriptor, b => b is XPathAdapter == false); + descriptor.AddBehavior(XPathBehavior.Instance).AddBehavior(new XPathAdapter(new XmlDocument())); + return adapter.This.Factory.GetAdapter(type, dictionary, descriptor); + } + + #endregion + + #region Reading + + private object ReadProperty(XPathResult result, bool ifExists, IDictionaryAdapter dictionaryAdapter) + { + object value; + var propertyType = result.Type; + + if (ReadCustom(result, out value)) + return value; + + if (propertyType != typeof(string)) + { + if (typeof(IXPathNavigable).IsAssignableFrom(propertyType)) + return ReadFragment(result); + + if (propertyType.IsArray || typeof(IEnumerable).IsAssignableFrom(propertyType)) + return ReadCollection(result, dictionaryAdapter); + + if (propertyType.IsInterface) + return ReadComponent(result, ifExists, dictionaryAdapter); + } + + return ReadSimple(result); + } + + private object ReadFragment(XPathResult result) + { + var node = result.GetNavigator(false); + if (result.Type == typeof(XmlElement)) + { + var document = new XmlDocument(); + document.Load(node.ReadSubtree()); + return document.DocumentElement; + } + return node.Clone(); + } + + private object ReadSimple(XPathResult result) + { + var node = result.GetNavigator(false); + if (node != null) + { + if (result.Type.IsEnum) + return Enum.Parse(result.Type, node.Value); + + try + { + return node.ValueAs(result.Type); + } + catch (InvalidCastException) + { + object value; + if (DefaultXmlSerializer.Instance.ReadObject(result, node, out value)) + return value; + } + } + if (result.Result != null) + return Convert.ChangeType(result.Result, result.Type); + + return null; + } + + private object ReadComponent(XPathResult result, bool ifExists, IDictionaryAdapter dictionaryAdapter) + { + XPathAdapter adapter; + var source = result.GetNavigator(false); + if (source == null && ifExists) return null; + + var elementType = result.Type; + if (source != null) + { + if (result.XmlMeta != null) + { + elementType = result.XmlMeta.Type; + } + else + { + var xmlType = Context.GetXmlType(source); + elementType = dictionaryAdapter.GetXmlSubclass(xmlType, elementType) ?? elementType; + } + adapter = new XPathAdapter(source, this); + } + else + { + Func createSource = () => result.GetNavigator(true); + adapter = new XPathAdapter(createSource, this); + } + + var component = dictionaryAdapter.This.Factory.GetAdapter(elementType, new Hashtable(), + new DictionaryDescriptor().AddBehavior(XPathBehavior.Instance, adapter)); + + if (result.Property != null) + dictionaryAdapter.This.ExtendedProperties[result.Property.PropertyName] = component; + + return component; + } + + private object ReadCollection(XPathResult result, IDictionaryAdapter dictionaryAdapter) + { + if (result.Type.IsArray) + return ReadArray(result, dictionaryAdapter); + + if (result.Type.IsGenericType) + return ReadList(result, dictionaryAdapter); + + return null; + } + + private object ReadArray(XPathResult result, IDictionaryAdapter dictionaryAdapter) + { + var itemType = result.Type.GetElementType(); + var items = result.GetNodes(itemType, type => dictionaryAdapter.GetXmlMeta(type)) + .Select(node => ReadProperty(node, false, dictionaryAdapter)).ToArray(); + var array = Array.CreateInstance(itemType, items.Length); + items.CopyTo(array, 0); + return array; + } + + private object ReadList(XPathResult result, IDictionaryAdapter dictionaryAdapter) + { + Type listType = null, initializerType = null; + var arguments = result.Type.GetGenericArguments(); + var genericDef = result.Type.GetGenericTypeDefinition(); + var itemType = arguments[0]; + + if (genericDef == typeof(List<>)) + { + listType = typeof(EditableList<>).MakeGenericType(arguments); + } + else + { + listType = typeof(EditableBindingList<>).MakeGenericType(arguments); + initializerType = typeof(BindingListInitializer<>).MakeGenericType(arguments); + } + + var list = (IList)Activator.CreateInstance(listType); + Func getXmlMeta = type => dictionaryAdapter.GetXmlMeta(type); + + foreach (var item in result.GetNodes(itemType, getXmlMeta)) + { + list.Add(ReadProperty(item, false, dictionaryAdapter)); + } + + if (initializerType != null) + { + Func addNew = () => + { + var node = result.CreateNode(itemType, null, getXmlMeta); + return ReadProperty(node, false, dictionaryAdapter); + }; + + Action addAt = (index, item) => + { + var node = result.CreateNode(itemType, item, getXmlMeta); + WriteProperty(node, item, dictionaryAdapter); + }; + + Action setAt = (index, item) => + { + var node = result.GetNodeAt(itemType, index); + WriteProperty(node, item, dictionaryAdapter); + }; + + Action removeAt = index => result.RemoveAt(index); + + var initializer = (IValueInitializer)Activator.CreateInstance( + initializerType, addAt, addNew, setAt, removeAt); + initializer.Initialize(dictionaryAdapter, list); + } + + return list; + } + + private bool ReadCustom(XPathResult result, out object value) + { + return result.ReadObject(out value); + } + + #endregion + + #region Writing + + private void WriteProperty(XPathResult result, object value, IDictionaryAdapter dictionaryAdapter) + { + var propertyType = result.Type; + + if (WriteCustom(result, value, dictionaryAdapter)) + return; + + if (propertyType == typeof(string)) + { + WriteSimple(result, value, dictionaryAdapter); + } + else if (typeof(IXPathNavigable).IsAssignableFrom(propertyType)) + { + WriteFragment(result, (IXPathNavigable)value); + } + else if (propertyType.IsArray || typeof(IEnumerable).IsAssignableFrom(propertyType)) + { + WriteCollection(result, value, dictionaryAdapter); + } + else if (propertyType.IsInterface) + { + WriteComponent(result, value, dictionaryAdapter); + } + else + { + WriteSimple(result, value, dictionaryAdapter); + } + } + + private void WriteFragment(XPathResult result, IXPathNavigable value) + { + var node = result.GetNavigator(true); + if (node == null) + { + root.AppendChild(value.CreateNavigator()); + } + else if (value != null) + { + node.ReplaceSelf(value.CreateNavigator()); + } + else + { + node.DeleteSelf(); + } + } + + private void WriteSimple(XPathResult result, object value, IDictionaryAdapter dictionaryAdapter) + { + if (value == null) + { + result.Remove(); + if (result.Property != null) + dictionaryAdapter.This.ExtendedProperties.Remove(result.Property.PropertyName); + return; + } + + var node = result.GetNavigator(true); + + if (result.Type.IsEnum) + { + node.SetTypedValue(value.ToString()); + } + else + { + try + { + node.SetTypedValue(value); + } + catch (InvalidCastException) + { + if (DefaultXmlSerializer.Instance.WriteObject(result, node, value) && result.Property != null) + { + dictionaryAdapter.This.ExtendedProperties[result.Property.PropertyName] = value; + } + } + } + } + + private void WriteComponent(XPathResult result, object value, IDictionaryAdapter dictionaryAdapter) + { + if (result.Property != null) + { + dictionaryAdapter.This.ExtendedProperties.Remove(result.Property.PropertyName); + } + + if (value == null) + { + result.Remove(); + return; + } + + var source = value as IDictionaryAdapter; + if (source != null) + { + var node = result.RemoveChildren(); + if (result.Type != source.Meta.Type && result.OmitPolymorphism == false) + { + var xmlType = source.GetXmlMeta().XmlType; + Context.SetXmlType(xmlType.TypeName, xmlType.Namespace, node); + } + var element = (IDictionaryAdapter)ReadComponent(result, false, dictionaryAdapter); + source.CopyTo(element); + } + } + + private void WriteCollection(XPathResult result, object value, IDictionaryAdapter dictionaryAdapter) + { + result.Remove(); + + if (value != null) + { + if (result.Type.IsArray) + { + WriteArray(result, value, dictionaryAdapter); + } + else if (result.Type.IsGenericType) + { + WriteList(result, value, dictionaryAdapter); + } + } + } + + private void WriteArray(XPathResult result, object value, IDictionaryAdapter dictionaryAdapter) + { + var array = (Array)value; + var itemType = array.GetType().GetElementType(); + + foreach (var item in array) + { + var node = result.CreateNode(itemType, item, type => dictionaryAdapter.GetXmlMeta(type)); + WriteProperty(node, item, dictionaryAdapter); + } + } + + private void WriteList(XPathResult result, object value, IDictionaryAdapter dictionaryAdapter) + { + var arguments = result.Type.GetGenericArguments(); + var itemType = arguments[0]; + + foreach (var item in (IEnumerable)value) + { + var node = result.CreateNode(itemType, item, type => dictionaryAdapter.GetXmlMeta(type)); + WriteProperty(node, item, dictionaryAdapter); + } + } + + private bool WriteCustom(XPathResult result, object value, IDictionaryAdapter dictionaryAdapter) + { + if (result.WriteObject(value)) + { + if (result.Property != null) + { + dictionaryAdapter.This.ExtendedProperties[result.Property.PropertyName] = value; + } + return true; + } + return false; + } + + #endregion + + #region Helpers + + public static XPathAdapter For(object adapter) + { + if (adapter == null) + { + throw new ArgumentNullException("adapter"); + } + + var dictionaryAdapter = adapter as IDictionaryAdapter; + + if (dictionaryAdapter != null) + { + XPathAdapter xpathAdapter = null; + var getters = dictionaryAdapter.This.Descriptor.Getters; + if (getters != null) + xpathAdapter = getters.OfType().SingleOrDefault(); + if (xpathAdapter != null) return xpathAdapter; + } + + return null; + } + + private XPathResult EvaluateProperty(string key, PropertyDescriptor property, IDictionaryAdapter dictionaryAdapter) + { + object result; + XPathExpression xpath = null; + object matchingBehavior = null; + Func create = null; + + object xmlType = dictionaryAdapter.GetXmlMeta(property.Property.DeclaringType).XmlType; + var keyContext = Context.CreateChild(Enumerable.Repeat(xmlType, 1).Union(property.Behaviors)); + + foreach (var behavior in property.Behaviors) + { + string name = key, ns = null; + Func matchingCreate = null; + + if (behavior is XmlElementAttribute) + { + xpath = XPathElement; + var node = root.Clone(); + var attrib = (XmlElementAttribute)behavior; + if (string.IsNullOrEmpty(attrib.ElementName) == false) + { + name = attrib.ElementName; + } + if (string.IsNullOrEmpty(attrib.Namespace) == false) + { + ns = attrib.Namespace; + } + matchingCreate = () => keyContext.AppendElement(name, ns, node); + } + else if (behavior is XmlAttributeAttribute) + { + xpath = XPathAttribute; + var node = root.Clone(); + var attrib = (XmlAttributeAttribute)behavior; + if (string.IsNullOrEmpty(attrib.AttributeName) == false) + { + name = attrib.AttributeName; + } + if (string.IsNullOrEmpty(attrib.Namespace) == false) + { + ns = attrib.Namespace; + } + matchingCreate = () => keyContext.CreateAttribute(name, ns, node); + } + else if (behavior is XmlArrayAttribute) + { + xpath = XPathElement; + var node = root.Clone(); + var attrib = (XmlArrayAttribute)behavior; + if (string.IsNullOrEmpty(attrib.ElementName) == false) + { + name = attrib.ElementName; + } + if (string.IsNullOrEmpty(attrib.Namespace) == false) + { + ns = attrib.Namespace; + } + matchingCreate = () => keyContext.AppendElement(name, ns, node); + } + else if (behavior is XPathAttribute) + { + var attrib = (XPathAttribute)behavior; + xpath = attrib.CompiledExpression; + } + else + { + continue; + } + + if (xpath != null) + { + keyContext.Arguments.Clear(); + keyContext.Arguments.AddParam("key", "", name); + keyContext.Arguments.AddParam("ns", "", ns ?? XPathContext.IgnoreNamespace); + if (keyContext.Evaluate(xpath, Root, out result)) + { + create = matchingCreate ?? create; + return new XPathResult(property, result, keyContext, behavior, create); + } + } + + matchingBehavior = matchingBehavior ?? behavior; + create = create ?? matchingCreate; + } + + if (xpath != null) + { + return new XPathResult(property, null, keyContext, matchingBehavior, create); + } + + keyContext.Arguments.Clear(); + keyContext.Arguments.AddParam("key", "", key); + keyContext.Arguments.AddParam("ns", "", XPathContext.IgnoreNamespace); + create = create ?? (() => keyContext.AppendElement(key, null, root)); + keyContext.Evaluate(XPathElementOrAttribute, Root, out result); + return new XPathResult(property, result, keyContext, null, create); + } + + private static bool ShouldIgnoreProperty(PropertyDescriptor property) + { + return property.Behaviors.Any(behavior => behavior is XmlIgnoreAttribute); + } + + private XPathNavigator EnsureOffRoot() + { + if (root == null && createRoot != null) + { + root = createRoot().Clone(); + } + + if (root != null && MoveOffRoot(root, XPathNodeType.Element) == false) + { + string elementName; + string namespaceUri = ""; + var xmlRoot = xmlMeta.XmlRoot; + if (xmlRoot != null) + { + elementName = xmlRoot.ElementName; + namespaceUri = xmlRoot.Namespace; + } + else + { + elementName = xmlMeta.XmlType.TypeName; + } + root = Context.AppendElement(elementName, namespaceUri, root); + Context.AddStandardNamespaces(root); + } + + return root; + } + + private static bool MoveOffRoot(XPathNavigator source, XPathNodeType to) + { + if (source.NodeType == XPathNodeType.Root) + { + return source.MoveToChild(to); + } + return true; + } + + #endregion + + #region XPath + + private static readonly XPathExpression XPathElement = + XPathExpression.Compile("*[castle-da:match($key,$ns)]"); + + private static readonly XPathExpression XPathAttribute = + XPathExpression.Compile("@*[castle-da:match($key,$ns)]"); + + private static readonly XPathExpression XPathElementOrAttribute = + XPathExpression.Compile("(*|@*)[castle-da:match($key,$ns)]"); + + #endregion + } +#endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathBehavior.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathBehavior.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathBehavior.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathBehavior.cs Sun Feb 13 20:02:15 2011 @@ -0,0 +1,100 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Xml; + using System.Xml.Serialization; + + internal class XPathBehavior : DictionaryBehaviorAttribute, IDictionaryMetaInitializer + { + public static readonly XPathBehavior Instance = new XPathBehavior(); + + void IDictionaryMetaInitializer.Initialize(IDictionaryAdapterFactory factory, DictionaryAdapterMeta dictionaryMeta) + { + var type = dictionaryMeta.Type; + string defaultNamespace = null; + XmlTypeAttribute xmlType = null; + XmlRootAttribute xmlRoot = null; + List xmlIncludes = null; + + new BehaviorVisitor() + .OfType(attrib => + { + xmlType = attrib; + }) + .OfType(attrib => + { + xmlRoot = attrib; + }) + .OfType(attrib => + { + if (attrib.Default) + defaultNamespace = attrib.NamespaceUri; + }) + .OfType(attrib => + { + xmlIncludes = xmlIncludes ?? new List(); + if (type != attrib.Type && type.IsAssignableFrom(attrib.Type)) + { + xmlIncludes.Add(attrib.Type); + } + }) + .Apply(dictionaryMeta.Behaviors); + + if (xmlType == null) + { + xmlType = new XmlTypeAttribute + { + TypeName = type.Name, + Namespace = defaultNamespace + }; + if (xmlType.TypeName.StartsWith("I")) + { + xmlType.TypeName = xmlType.TypeName.Substring(1); + } + } + else if (xmlType.Namespace == null) + xmlType.Namespace = defaultNamespace; + + dictionaryMeta.SetXmlMeta(new XmlMetadata(type, xmlType, xmlRoot, xmlIncludes)); + } + } + + #region Class: XmlMetadata + + internal class XmlMetadata + { + public XmlMetadata(Type type, XmlTypeAttribute xmlType, XmlRootAttribute xmlRoot, IEnumerable xmlIncludes) + { + Type = type; + XmlType = xmlType; + XmlRoot = xmlRoot; + XmlIncludes = xmlIncludes; + } + + public Type Type { get; private set; } + + public XmlTypeAttribute XmlType { get; private set; } + + public XmlRootAttribute XmlRoot { get; private set; } + + public IEnumerable XmlIncludes { get; private set; } + } + + #endregion +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathContext.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathContext.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathContext.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathContext.cs Sun Feb 13 19:31:28 2011 @@ -0,0 +1,422 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if !SILVERLIGHT + using System; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Xml; + using System.Xml.Serialization; + using System.Xml.XPath; + using System.Xml.Xsl; + + internal class XPathContext : XsltContext + { + private readonly XPathContext parent; + private IDictionary> functions; + private List serializers; + private int prefixCount; + + public const string Prefix = "castle-da"; + public const string NamespaceUri = "urn:castleproject.org:da"; + public const string IgnoreNamespace = "_"; + private const string Xsd = "http://www.w3.org/2001/XMLSchema"; + private const string Xsi = "http://www.w3.org/2001/XMLSchema-instance"; + + public XPathContext() + : this(new NameTable()) + { + } + + public XPathContext(NameTable nameTable) + : base(nameTable) + { + Arguments = new XsltArgumentList(); + functions = new Dictionary>(); + AddNamespace("xsi", Xsi); + AddNamespace("xsd", Xsd); + AddNamespace(Prefix, NamespaceUri); + AddFunction(Prefix, "match", MatchFunction.Instance); + } + + public XPathContext(XPathContext parent) + : base((NameTable)parent.NameTable) + { + this.parent = parent; + Arguments = new XsltArgumentList(); + functions = new Dictionary>(); + } + + public override string DefaultNamespace + { + get + { + var defaultNamespace = base.DefaultNamespace; + if (string.IsNullOrEmpty(defaultNamespace) && parent != null) + defaultNamespace = parent.DefaultNamespace; + return defaultNamespace; + } + } + + public XsltArgumentList Arguments { get; private set; } + + public IEnumerable ListItemMeta { get; private set; } + + public IEnumerable Serializers + { + get + { + var mine = serializers ?? Enumerable.Empty(); + var parents = (parent != null) ? parent.Serializers : Enumerable.Empty(); + return mine.Union(parents); + } + } + + public XPathContext ApplyBehaviors(IEnumerable behaviors) + { + new BehaviorVisitor() + .OfType(attrib => + { + if (string.IsNullOrEmpty(attrib.Namespace) == false) + AddNamespace(string.Empty, attrib.Namespace); + }) + .OfType(attrib => + { + AddNamespace(attrib.Prefix, attrib.NamespaceUri); + if (attrib.Default) + AddNamespace(string.Empty, attrib.NamespaceUri); + }) + .OfType(attrib => + { + ListItemMeta = ListItemMeta ?? new List(); + ((List)ListItemMeta).Add(attrib); + }) + .OfType(attrib => + { + AddFunction(attrib.Prefix, attrib.Name, attrib.Function); + }) + .OfType(attrib => + { + AddSerializer(attrib); + }) + .Apply(behaviors); + return this; + } + + public XPathContext CreateChild(IEnumerable behaviors) + { + return new XPathContext(this).ApplyBehaviors(behaviors); + } + + public XPathContext CreateChild(params object[] behaviors) + { + return CreateChild((IEnumerable)behaviors); + } + + public override bool HasNamespace(string prefix) + { + return base.HasNamespace(prefix) || (parent != null && parent.HasNamespace(prefix)); + } + + public override string LookupNamespace(string prefix) + { + var uri = base.LookupNamespace(prefix); + if (uri == null && parent != null) + uri = parent.LookupNamespace(prefix); + return uri; + } + + public override string LookupPrefix(string uri) + { + var prefix = base.LookupPrefix(uri); + if (string.IsNullOrEmpty(prefix) && parent != null) + prefix = parent.LookupPrefix(uri); + return prefix; + } + + public string AddNamespace(string namespaceUri) + { + var prefix = LookupPrefix(namespaceUri); + if (string.IsNullOrEmpty(prefix)) + { + prefix = GetUniquePrefix(); + AddNamespace(prefix, namespaceUri); + } + return prefix; + } + + public XPathContext AddSerializer(IXPathSerializer serializer) + { + serializers = serializers ?? new List(); + serializers.Insert(0, serializer); + return this; + } + + public XPathContext AddFunction(string prefix, string name, IXsltContextFunction function) + { + functions[GetQualifiedName(prefix, name)] = () => function; + return this; + } + + public XPathContext AddFunction(string prefix, string name, Func function) + { + functions[GetQualifiedName(prefix, name)] = function; + return this; + } + + public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] argTypes) + { + Func function; + if (functions.TryGetValue(GetQualifiedName(prefix, name), out function)) + return function(); + return (parent != null) ? parent.ResolveFunction(prefix, name, argTypes) : null; + } + + public override IXsltContextVariable ResolveVariable(string prefix, string name) + { + return new XPathVariable(name); + } + + public bool Evaluate(XPathExpression xpath, XPathNavigator source, out object result) + { + xpath = (XPathExpression)xpath.Clone(); + xpath.SetContext(this); + result = source.Evaluate(xpath); + if (xpath.ReturnType == XPathResultType.NodeSet) + { + if (((XPathNodeIterator)result).Count == 0) + result = null; + } + return result != null; + } + + public XPathNavigator SelectSingleNode(XPathExpression xpath, XPathNavigator source) + { + xpath = (XPathExpression)xpath.Clone(); + xpath.SetContext(this); + return source.SelectSingleNode(xpath); + } + + public bool Matches(XPathExpression xpath, XPathNavigator source) + { + xpath = (XPathExpression)xpath.Clone(); + xpath.SetContext(this); + return source.Matches(xpath); + } + + public void AddStandardNamespaces(XPathNavigator source) + { + CreateNamespace("xsi", Xsi, source); + CreateNamespace("xsd", Xsd, source); + } + + public string CreateNamespace(string prefix, string namespaceUri, XPathNavigator source) + { + if (string.IsNullOrEmpty(namespaceUri) == false) + { + source = source.Clone(); + source.MoveToRoot(); + source.MoveToChild(XPathNodeType.Element); + + if (string.IsNullOrEmpty(prefix)) + prefix = AddNamespace(namespaceUri); + + var existing = source.GetNamespace(prefix); + if (existing == namespaceUri) return prefix; + if (string.IsNullOrEmpty(existing) == false) return null; + + source.CreateAttribute("xmlns", prefix, "", namespaceUri); + } + return prefix; + } + + public XPathNavigator CreateAttribute(string name, string namespaceUri, XPathNavigator source) + { + source.CreateAttribute(null, name, namespaceUri, ""); + source.MoveToAttribute(name, namespaceUri ?? ""); + return source; + } + + public XPathNavigator AppendElement(string name, string namespaceUri, XPathNavigator source) + { + namespaceUri = GetEffectiveNamespace(namespaceUri); + source.AppendChildElement(LookupPrefix(namespaceUri), name, namespaceUri, ""); + return source.SelectSingleNode("*[position()=last()]"); + } + + public void SetXmlType(string name, string namespaceUri, XPathNavigator source) + { + namespaceUri = GetEffectiveNamespace(namespaceUri); + var prefix = CreateNamespace(null, namespaceUri, source); + source.CreateAttribute("xsi", "type", Xsi, GetQualifiedName(prefix, name)); + } + + public XmlQualifiedName GetXmlType(XPathNavigator source) + { + var qualifiedType = source.GetAttribute("type", Xsi); + if (string.IsNullOrEmpty(qualifiedType) == false) + { + string name, namespaceUri = null; + var prefix = SplitQualifiedName(qualifiedType, out name); + if (prefix != null) + namespaceUri = source.GetNamespace(prefix); + return new XmlQualifiedName(name, namespaceUri); + } + return null; + } + + public string GetEffectiveNamespace(string namespaceUri) + { + return namespaceUri ?? DefaultNamespace; + } + + public override int CompareDocument(string baseUri, string nextbaseUri) + { + return 0; + } + + public override bool Whitespace + { + get { return true; } + } + + public override bool PreserveWhitespace(XPathNavigator node) + { + return true; + } + + private string GetUniquePrefix() + { + if (parent != null) + return parent.GetUniquePrefix(); + return "da" + ++prefixCount; + } + + private static string GetQualifiedName(string prefix, string name) + { + if (string.IsNullOrEmpty(prefix)) + return name; + return String.Format("{0}:{1}", prefix, name); + } + + private static string SplitQualifiedName(string qualifiedName, out string name) + { + var parts = qualifiedName.Split(':'); + if (parts.Length == 1) + { + name = parts[0]; + return null; + } + else if (parts.Length == 2) + { + name = parts[1]; + return parts[0]; + } + throw new ArgumentException(string.Format( + "Invalid qualified name {0}. Expected [prefix:]name format", qualifiedName)); + } + + #region Nested Type: XPathVariable + + public class XPathVariable : IXsltContextVariable + { + private readonly string name; + + public XPathVariable(string name) + { + this.name = name; + } + + public bool IsLocal + { + get { return false; } + } + + public bool IsParam + { + get { return false; } + } + + public XPathResultType VariableType + { + get { return XPathResultType.Any; } + } + + public object Evaluate(XsltContext xsltContext) + { + var args = ((XPathContext)xsltContext).Arguments; + return args.GetParam(name, null); + } + } + + #endregion + + #region Nested Type: MatchFunction + + public class MatchFunction : IXsltContextFunction + { + public static readonly MatchFunction Instance = new MatchFunction(); + + protected MatchFunction() + { + } + + public int Minargs + { + get { return 1; } + } + + public int Maxargs + { + get { return 2; } + } + + public XPathResultType[] ArgTypes + { + get { return new[] { XPathResultType.String, XPathResultType.String }; } + } + + public XPathResultType ReturnType + { + get { return XPathResultType.Boolean; } + } + + public object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + var key = (string)args[0]; + if (key.Equals(docContext.LocalName, StringComparison.OrdinalIgnoreCase) == false) + { + return false; + } + + if (args.Length > 1 && args[1].Equals(IgnoreNamespace) == false) + { + var ns = (string)args[1]; + if (ns.Equals(docContext.NamespaceURI, StringComparison.OrdinalIgnoreCase) == false) + { + return false; + } + } + + return true; + } + } + + #endregion + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathExtensions.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathExtensions.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathExtensions.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathExtensions.cs Sun Feb 13 19:31:33 2011 @@ -0,0 +1,78 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ + using System; + using System.Linq; + using System.Xml; + + internal static class XPathExtensions + { + private const string XmlMetaKey = "XmlMeta"; + + public static XmlMetadata GetXmlMeta(this IDictionaryAdapter dictionaryAdapter) + { + return GetXmlMeta(dictionaryAdapter, null); + } + + public static XmlMetadata GetXmlMeta(this IDictionaryAdapter dictionaryAdapter, Type otherType) + { + if (otherType == null || otherType.IsInterface) + { + var meta = GetDictionaryMeta(dictionaryAdapter, otherType); + return (XmlMetadata)meta.ExtendedProperties[XmlMetaKey]; + } + return null; + } + + internal static XmlMetadata GetXmlMeta(this DictionaryAdapterMeta dictionaryAdapterMeta) + { + return (XmlMetadata)dictionaryAdapterMeta.ExtendedProperties[XmlMetaKey]; + } + + internal static void SetXmlMeta(this DictionaryAdapterMeta dictionaryAdapterMeta, XmlMetadata xmlMeta) + { + dictionaryAdapterMeta.ExtendedProperties[XmlMetaKey] = xmlMeta; + } + + public static Type GetXmlSubclass(this IDictionaryAdapter dictionaryAdapter, XmlQualifiedName xmlType, Type otherType) + { + if (xmlType == null) return null; + var xmlIncludes = dictionaryAdapter.GetXmlMeta(otherType).XmlIncludes; + if (xmlIncludes != null) + { + var subClass = from xmlInclude in xmlIncludes + let xmlIncludeType = dictionaryAdapter.GetXmlMeta(xmlInclude).XmlType + where xmlIncludeType.TypeName == xmlType.Name && + xmlIncludeType.Namespace == xmlType.Namespace + select xmlInclude; + return subClass.FirstOrDefault(); + + } + return null; + } + + private static DictionaryAdapterMeta GetDictionaryMeta(IDictionaryAdapter dictionaryAdapter, Type otherType) + { + var meta = dictionaryAdapter.Meta; + if (otherType != null && otherType != meta.Type) + { + meta = dictionaryAdapter.This.Factory.GetAdapterMeta(otherType, + new DictionaryDescriptor().AddBehavior(XPathBehavior.Instance)); + } + return meta; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathResult.cs nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathResult.cs --- nmock3-62490-original\MAIN\Source\Castle\Components.DictionaryAdapter\XPathResult.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Components.DictionaryAdapter\XPathResult.cs Sun Feb 13 19:31:39 2011 @@ -0,0 +1,405 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Components.DictionaryAdapter +{ +#if !SILVERLIGHT + using System; + using System.Collections.Generic; + using System.Linq; + using System.Xml; + using System.Xml.Serialization; + using System.Xml.XPath; + + internal class XPathResult + { + public readonly bool CanWrite; + public readonly PropertyDescriptor Property; + private readonly object matchingBehavior; + private readonly Func create; + + public XPathResult(PropertyDescriptor property, object result, + XPathContext context, object matchingBehavior) + : this(property, result, context, matchingBehavior, null) + { + } + + public XPathResult(Type type, object result, XPathContext context, object matchingBehavior) + : this(null, result, context, matchingBehavior, null) + { + Type = type; + } + + public XPathResult(PropertyDescriptor property, object result, XPathContext context, + object matchingBehavior, Func create) + { + Result = result; + Property = property; + Type = (property != null) ? Property.PropertyType : null; + Context = context; + this.create = create; + this.matchingBehavior = matchingBehavior; + CanWrite = (create != null || result is XPathNavigator); + } + + public bool IsContainer + { + get { return matchingBehavior == null || matchingBehavior is XmlArrayAttribute; } + } + + public Type Type { get; private set; } + + public object Result { get; private set; } + + public XPathContext Context { get; private set; } + + public XPathNavigator Container { get; private set; } + + public XmlMetadata XmlMeta { get; private set; } + + public bool OmitPolymorphism { get; private set; } + + public XPathNavigator GetNavigator(bool demand) + { + if (Result is XPathNavigator) + { + return (XPathNavigator)Result; + } + else if (Result is XPathNodeIterator) + { + return ((XPathNodeIterator)Result).Cast().FirstOrDefault(); + } + if (demand && create != null) + { + var result = create(); + Result = result; + return result; + } + return null; + } + + public XPathResult GetNodeAt(Type type, int index) + { + var node = Container; + if (IsContainer) + { + if (node != null) + { + node = Container.SelectSingleNode(String.Format("*[position()={0}]", index + 1)); + } + } + else if (Result is XPathNodeIterator) + { + var nodes = ((XPathNodeIterator)Result).Cast().ToArray(); + node = nodes[index]; + } + return new XPathResult(type, node, Context, matchingBehavior); + } + + public IEnumerable GetNodes(Type type, Func getXmlMeta) + { + Container = null; + var nodes = Result as XPathNodeIterator; + var results = Enumerable.Empty(); + + if (nodes == null) + { + Container = Result as XPathNavigator; + if (IsContainer && Container != null) + { + if (Context.ListItemMeta != null) + { + return Context.ListItemMeta.SelectMany(item => + { + string name, namespaceUri; + var xmlMeta = GetItemQualifedName(type, item, getXmlMeta, out name, out namespaceUri); + return Container.SelectChildren(name, namespaceUri).Cast() + .Select(r => new XPathResult(item.Type ?? type, r, Context, matchingBehavior) + { + XmlMeta = xmlMeta + }); + }).OrderBy(r => (XPathNavigator)r.Result, XPathPositionComparer.Instance); + } + else + { + results = Container.SelectChildren(XPathNodeType.Element).Cast(); + } + } + } + else if (IsContainer == false) + { + results = nodes.Cast(); + } + else + { + var parents = nodes.Cast().ToList(); + Container = parents.FirstOrDefault(); + + if (Context.ListItemMeta != null) + { + return Context.ListItemMeta.SelectMany(item => + { + string name, namespaceUri; + var xmlMeta = GetItemQualifedName(type, item, getXmlMeta, out name, out namespaceUri); + return parents.SelectMany(p => p.SelectChildren(name, namespaceUri).Cast()) + .Select(r => new XPathResult(item.Type ?? type, r, Context, matchingBehavior) + { + XmlMeta = xmlMeta + }); + }).OrderBy(r => (XPathNavigator)r.Result, XPathPositionComparer.Instance); + } + else + { + results = parents.SelectMany(p => p.SelectChildren(XPathNodeType.Element) + .Cast()); + } + } + return results.Select(r => new XPathResult(type, r, Context, matchingBehavior)); + } + + public bool ReadObject(out object value) + { + var node = GetNavigator(false); + foreach (var serializer in Context.Serializers) + { + if (serializer.ReadObject(this, node, out value)) + return true; + } + value = null; + return false; + } + + public bool WriteObject(object value) + { + var node = GetNavigator(true); + foreach (var serializer in Context.Serializers) + { + if (serializer.WriteObject(this, node, value)) + return true; + } + return false; + } + + private XmlMetadata GetItemQualifedName(Type type, XmlArrayItemAttribute item, Func getXmlMeta, + out string name, out string namespaceUri) + { + name = item.ElementName; + namespaceUri = item.Namespace; + type = item.Type ?? type; + var xmlMeta = getXmlMeta(type); + + if (string.IsNullOrEmpty(name)) + { + if (xmlMeta != null) + { + name = xmlMeta.XmlType.TypeName; + } + else + { + name = GetDataType(type); + } + namespaceUri = null; + } + namespaceUri = Context.GetEffectiveNamespace(namespaceUri); + return xmlMeta; + } + + public XPathResult CreateNode(Type type, object value, Func getXmlMeta) + { + string name = null; + string namespaceUri = null; + string typeNamespaceUri = null; + bool omitPolymorphism = false; + Type baseType = type; + var xmlMeta = getXmlMeta(type); + + if (xmlMeta != null) + { + name = xmlMeta.XmlType.TypeName; + typeNamespaceUri = xmlMeta.XmlType.Namespace; + } + + if (value != null) + { + if (value is IDictionaryAdapter) + { + type = ((IDictionaryAdapter)value).Meta.Type; + } + else + { + type = value.GetType(); + } + } + + if (xmlMeta == null) + { + name = GetDataType(type); + } + + if (Context.ListItemMeta != null) + { + var actualType = type; + var listItem = Context.ListItemMeta.FirstOrDefault(li => (li.Type ?? baseType) == actualType); + + if (listItem != null) + { + type = listItem.Type ?? baseType; + + if (string.IsNullOrEmpty(listItem.ElementName)) + { + if (listItem.Type != null) + { + xmlMeta = getXmlMeta(listItem.Type); + + if (xmlMeta != null) + { + name = xmlMeta.XmlType.TypeName; + typeNamespaceUri = xmlMeta.XmlType.Namespace; + } + else + { + name = GetDataType(listItem.Type); + } + } + } + else + { + name = listItem.ElementName; + namespaceUri = listItem.Namespace; + } + omitPolymorphism = true; + } + } + + XPathNavigator item = null; + + if (IsContainer) + { + if (Container == null && create != null) + { + Container = create(); + } + + if (Container != null) + { + item = Context.AppendElement(name, namespaceUri, Container); + } + } + else if (create != null) + { + item = create(); + } + + if (string.IsNullOrEmpty(typeNamespaceUri) == false) + { + Context.CreateNamespace(null, typeNamespaceUri, item); + } + + return new XPathResult(type, item, Context, matchingBehavior) + { + XmlMeta = xmlMeta, + OmitPolymorphism = omitPolymorphism + }; + } + + public void RemoveAt(int index) + { + GetNodeAt(null, index).Remove(); + } + + public void Remove() + { + if (Result is XPathNavigator) + { + ((XPathNavigator)Result).DeleteSelf(); + } + else if (Result is XPathNodeIterator) + { + var nodes = ((XPathNodeIterator)Result).Cast().ToArray(); + for (int i = 0; i < nodes.Length; ++i) + { + nodes[i].DeleteSelf(); + } + } + Result = null; + } + + public XPathNavigator RemoveChildren() + { + var node = GetNavigator(true); + if (node != null) + { + var children = node.SelectChildren(XPathNodeType.All).Cast(); + foreach (var child in children.ToArray()) child.DeleteSelf(); + } + return node; + } + + #region Xml Primitive Data Types + + private static string GetDataType(Type type) + { + string dataType; + if (XmlDataTypes.TryGetValue(type, out dataType) == false) + { + dataType = type.Name.ToLower(); + } + return dataType; + } + + private static readonly Dictionary XmlDataTypes = new Dictionary() + { + { typeof(int), "int" }, + { typeof(long), "long" }, + { typeof(short), "short" }, + { typeof(float), "float" }, + { typeof(double), "double" }, + { typeof(bool), "boolean" }, + { typeof(DateTime), "dateTime" }, + { typeof(byte), "byte" }, + { typeof(uint), "uint" }, + { typeof(ulong), "ulong" }, + { typeof(ushort), "ushort" } + }; + + #endregion + } + + #region Class: XPathPositionComparer + + class XPathPositionComparer : IComparer + { + public static readonly XPathPositionComparer Instance = new XPathPositionComparer(); + + private XPathPositionComparer() + { + } + + public int Compare(XPathNavigator x, XPathNavigator y) + { + switch (x.ComparePosition(y)) + { + case XmlNodeOrder.Before: + return -1; + case XmlNodeOrder.After: + return 1; + default: + return 0; + } + } + } + + #endregion +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\CollectionExtensions.cs nmock3-62490\MAIN\Source\Castle\Core\CollectionExtensions.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\CollectionExtensions.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\CollectionExtensions.cs Sun Feb 13 20:24:59 2011 @@ -0,0 +1,32 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + using System; + using System.Collections.Generic; + + internal static class CollectionExtensions + { + public static void ForEach(this IEnumerable items, Action action) + { + if (items == null) return; + + foreach(var item in items) + { + action(item); + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\AbstractConfiguration.cs nmock3-62490\MAIN\Source\Castle\Core\Configuration\AbstractConfiguration.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\AbstractConfiguration.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Configuration\AbstractConfiguration.cs Sun Feb 13 20:18:54 2011 @@ -0,0 +1,108 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Configuration +{ + using System; + + /// + /// This is an abstract implementation + /// that deals with methods that can be abstracted away + /// from underlying implementations. + /// + /// + /// AbstractConfiguration makes easier to implementers + /// to create a new version of + /// +#if !SILVERLIGHT + [Serializable] +#endif + internal abstract class AbstractConfiguration : IConfiguration + { + private readonly ConfigurationAttributeCollection attributes = new ConfigurationAttributeCollection(); + private readonly ConfigurationCollection children = new ConfigurationCollection(); + private string internalName; + private string internalValue; + + /// + /// Gets the name of the . + /// + /// + /// The Name of the . + /// + public string Name + { + get { return internalName; } + protected set { internalName = value; } + } + + /// + /// Gets the value of . + /// + /// + /// The Value of the . + /// + public string Value + { + get { return internalValue; } + protected set { internalValue = value; } + } + + /// + /// Gets all child nodes. + /// + /// The of child nodes. + public virtual ConfigurationCollection Children + { + get { return children; } + } + + /// + /// Gets node attributes. + /// + /// + /// All attributes of the node. + /// + public virtual ConfigurationAttributeCollection Attributes + { + get { return attributes; } + } + + /// + /// Gets the value of the node and converts it + /// into specified . + /// + /// The + /// + /// The Default value returned if the convertion fails. + /// + /// The Value converted into the specified type. + public virtual object GetValue(Type type, object defaultValue) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + try + { + return Convert.ChangeType(Value, type, System.Threading.Thread.CurrentThread.CurrentCulture); + } + catch(InvalidCastException) + { + return defaultValue; + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\ConfigurationAttributeCollection.cs nmock3-62490\MAIN\Source\Castle\Core\Configuration\ConfigurationAttributeCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\ConfigurationAttributeCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Configuration\ConfigurationAttributeCollection.cs Sun Feb 13 20:18:58 2011 @@ -0,0 +1,59 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Configuration +{ +#if !SILVERLIGHT + + using System; + using System.Collections.Specialized; + using System.Runtime.Serialization; + + [Serializable] + internal class ConfigurationAttributeCollection : NameValueCollection + { + public ConfigurationAttributeCollection() + { + } + + protected ConfigurationAttributeCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +#else + + using System.Collections.Generic; + + public class ConfigurationAttributeCollection : Dictionary + { + public ConfigurationAttributeCollection() + { + } + + public new string this[string key] + { + get + { + string result; + TryGetValue(key, out result); + return result; + } + set + { + base[key] = value; + } + } + } +#endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\ConfigurationCollection.cs nmock3-62490\MAIN\Source\Castle\Core\Configuration\ConfigurationCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\ConfigurationCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Configuration\ConfigurationCollection.cs Sun Feb 13 20:19:05 2011 @@ -0,0 +1,70 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Configuration +{ + using System; + using System.Collections.Generic; + + /// + /// A collection of objects. + /// +#if !SILVERLIGHT + [Serializable] +#endif + internal class ConfigurationCollection : List + { + /// + /// Creates a new instance of ConfigurationCollection. + /// + public ConfigurationCollection() + { + } + + /// + /// Creates a new instance of ConfigurationCollection. + /// + public ConfigurationCollection(IEnumerable value) : base(value) + { + } + + public IConfiguration this[String name] + { + get + { + foreach(IConfiguration config in this) + { + if (name.Equals(config.Name)) + { + return config; + } + } + + return null; + } + } + +// /// +// /// Adds an array of . +// /// +// /// The Array of to add. +// public void AddRange(IEnumerable value) +// { +// foreach(IConfiguration configuration in value) +// { +// Add(configuration); +// } +// } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\IConfiguration.cs nmock3-62490\MAIN\Source\Castle\Core\Configuration\IConfiguration.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\IConfiguration.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Configuration\IConfiguration.cs Sun Feb 13 20:19:10 2011 @@ -0,0 +1,65 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Configuration +{ + using System; + using System.Collections; + + /// + /// is a interface encapsulating a configuration node + /// used to retrieve configuration values. + /// + internal interface IConfiguration + { + /// + /// Gets the name of the node. + /// + /// + /// The Name of the node. + /// + String Name { get; } + + /// + /// Gets the value of the node. + /// + /// + /// The Value of the node. + /// + String Value { get; } + + /// + /// Gets an of + /// elements containing all node children. + /// + /// The Collection of child nodes. + ConfigurationCollection Children { get; } + + /// + /// Gets an of the configuration attributes. + /// + ConfigurationAttributeCollection Attributes { get; } + + /// + /// Gets the value of the node and converts it + /// into specified . + /// + /// The + /// + /// The Default value returned if the conversion fails. + /// + /// The Value converted into the specified type. + object GetValue(Type type, object defaultValue); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\MutableConfiguration.cs nmock3-62490\MAIN\Source\Castle\Core\Configuration\MutableConfiguration.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\MutableConfiguration.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Configuration\MutableConfiguration.cs Sun Feb 13 20:19:16 2011 @@ -0,0 +1,78 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Configuration +{ + using System; + + /// + /// Summary description for MutableConfiguration. + /// +#if !SILVERLIGHT + [Serializable] +#endif + internal class MutableConfiguration : AbstractConfiguration + { + /// + /// Initializes a new instance of the class. + /// + /// The name. + public MutableConfiguration(String name) : this(name, null) + { + } + + public MutableConfiguration(String name, String value) + { + Name = name; + Value = value; + } + + /// + /// Gets the value of . + /// + /// + /// The Value of the . + /// + public new string Value + { + get { return base.Value; } + set { base.Value = value; } + } + + public static MutableConfiguration Create(string name) + { + return new MutableConfiguration(name); + } + + public MutableConfiguration Attribute(string name, string value) + { + Attributes[name] = value; + return this; + } + + public MutableConfiguration CreateChild(string name) + { + MutableConfiguration child = new MutableConfiguration(name); + Children.Add(child); + return child; + } + + public MutableConfiguration CreateChild(string name, string value) + { + MutableConfiguration child = new MutableConfiguration(name, value); + Children.Add(child); + return child; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\Xml\XmlConfigurationDeserializer.cs nmock3-62490\MAIN\Source\Castle\Core\Configuration\Xml\XmlConfigurationDeserializer.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Configuration\Xml\XmlConfigurationDeserializer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Configuration\Xml\XmlConfigurationDeserializer.cs Sun Feb 13 20:19:21 2011 @@ -0,0 +1,86 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT + +namespace Castle.Core.Configuration.Xml +{ + using System.Text; + using System.Xml; + + /// + /// Pendent + /// + internal class XmlConfigurationDeserializer + { + /// + /// Deserializes the specified node into an abstract representation of configuration. + /// + /// The node. + /// + public IConfiguration Deserialize(XmlNode node) + { + return Deserialize(node); + } + + public static IConfiguration GetDeserializedNode(XmlNode node) + { + ConfigurationCollection configChilds = new ConfigurationCollection(); + + StringBuilder configValue = new StringBuilder(); + + if (node.HasChildNodes) + { + foreach(XmlNode child in node.ChildNodes) + { + if (IsTextNode(child)) + { + configValue.Append(child.Value); + } + else if (child.NodeType == XmlNodeType.Element) + { + configChilds.Add(GetDeserializedNode(child)); + } + } + } + + MutableConfiguration config = new MutableConfiguration(node.Name, GetConfigValue(configValue.ToString())); + + foreach(XmlAttribute attribute in node.Attributes) + { + config.Attributes.Add(attribute.Name, attribute.Value); + } + + config.Children.AddRange(configChilds); + + return config; + } + + /// + /// If a config value is an empty string we return null, this is to keep + /// backward compability with old code + /// + public static string GetConfigValue(string value) + { + return string.IsNullOrEmpty(value) ? null : value.Trim(); + } + + public static bool IsTextNode(XmlNode node) + { + return node.NodeType == XmlNodeType.Text || node.NodeType == XmlNodeType.CDATA; + } + } +} + +#endif \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Extensions\SilverlightExtensions.cs nmock3-62490\MAIN\Source\Castle\Core\Extensions\SilverlightExtensions.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Extensions\SilverlightExtensions.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Extensions\SilverlightExtensions.cs Sun Feb 13 18:56:54 2011 @@ -0,0 +1,252 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if SILVERLIGHT + +namespace Castle.Core.Extensions +{ + using System; + using System.Collections.Generic; + + public static class SilverlightExtensions + { + public static T[] FindAll(this T[] array, Predicate match) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + if (match == null) + { + throw new ArgumentNullException("match"); + } + List list = new List(); + for (int i = 0; i < array.Length; i++) + { + if (match(array[i])) + { + list.Add(array[i]); + } + } + return list.ToArray(); + } + } +} +namespace Castle.DynamicProxy.SilverlightExtensions +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + + public class SilverlightAssertException : Exception + { + public SilverlightAssertException(string message) : base(message) + { + } + + public SilverlightAssertException() + { + } + } + + public static class Extensions + { + public static Type[] FindInterfaces(this Type type, TypeFilter filter, object filterCriteria) + { + if (filter == null) + throw new ArgumentNullException("filter"); + + List ifaces = new List(); + foreach (Type iface in type.GetInterfaces()) + { + if (filter(iface, filterCriteria)) + ifaces.Add(iface); + } + + return ifaces.ToArray(); + } + + /// + /// The silverlight System.Type is missing the IsNested property so this exposes similar functionality. + /// + /// + /// + public static bool IsNested(this Type type) + { + return type.DeclaringType != null; + } + + public static T Find(this T[] array, Predicate match) + { + if (array == null) + throw new ArgumentNullException("array"); + + if (match == null) + throw new ArgumentNullException("match"); + + for (int i = 0; i < array.Length; i++) + { + if (match(array[i])) + return array[i]; + } + + return default(T); + } + } + + /// + /// http://www.dolittle.com/blogs/einar/archive/2008/01/13/missing-enum-getvalues-when-doing-silverlight-for-instance.aspx + /// + public static class EnumHelper + { + public static T[] GetValues() + { + Type enumType = typeof(T); + + if (!enumType.IsEnum) + { + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); + } + + List values = new List(); + + var fields = from field in enumType.GetFields() + where field.IsLiteral + select field; + + foreach (FieldInfo field in fields) + { + object value = field.GetValue(enumType); + values.Add((T)value); + } + + return values.ToArray(); + } + + public static object[] GetValues(Type enumType) + { + if (!enumType.IsEnum) + { + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); + } + + List values = new List(); + + var fields = from field in enumType.GetFields() + where field.IsLiteral + select field; + + foreach (FieldInfo field in fields) + { + object value = field.GetValue(enumType); + values.Add(value); + } + + return values.ToArray(); + } + } +} + +namespace System.Reflection +{ + public delegate bool TypeFilter(Type m, object filterCriteria); +} + +namespace System.Diagnostics +{ + public sealed class Trace + { + public static void WriteLine(string message) + { + //TODO:??? + } + + public static void Write(Exception e, string message) + { + //TODO:??? + } + + public static void Assert(bool condition) + { + if (!condition) + { + //TODO:??? + throw new Castle.DynamicProxy.SilverlightExtensions.SilverlightAssertException(); + } + } + + public static void Assert(bool condition, string message) + { + if (!condition) + { + //TODO:??? + throw new Castle.DynamicProxy.SilverlightExtensions.SilverlightAssertException(message); + } + } + } +} +namespace System.ComponentModel +{ + public delegate void PropertyChangingEventHandler(object sender, PropertyChangingEventArgs e); + public class PropertyChangingEventArgs : EventArgs + { + + public PropertyChangingEventArgs(string propertyName) + { + PropertyName = propertyName; + } + + public virtual string PropertyName { get; private set; } + } +} +namespace System.ComponentModel +{ + using System.Collections.Generic; + + using Castle.Core.Extensions; + + public static class TypeDescriptor + { + private static readonly IDictionary converters = new Dictionary(); + + static TypeDescriptor() + { + SimpleConverter.Register(); + } + + public static TypeConverter GetConverter(Type type) + { + TypeConverter converter; + converters.TryGetValue(type, out converter); + return converter; + } + + public static void RegisterConverter(Type forType, TypeConverter converter) + { + converters[forType] = converter; + } + } +} +#endif +#if SL3 && SILVERLIGHT +namespace System.ComponentModel +{ + public interface IDataErrorInfo + { + string this[string columnName] { get; } + string Error { get; } + } +} +#endif \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Extensions\SimpleConverter.cs nmock3-62490\MAIN\Source\Castle\Core\Extensions\SimpleConverter.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Extensions\SimpleConverter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Extensions\SimpleConverter.cs Sun Feb 13 18:56:54 2011 @@ -0,0 +1,95 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Extensions +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Globalization; + +#if SILVERLIGHT + + public class SimpleConverter : TypeConverter + { + private static readonly Dictionary> converters = new Dictionary> + { + {typeof (int), i => int.Parse(i)}, + {typeof (short), s => short.Parse(s)}, + {typeof (long), l => long.Parse(l)}, + {typeof (float), f => float.Parse(f)}, + {typeof (double), d => double.Parse(d)}, + {typeof (decimal), d => decimal.Parse(d)}, + {typeof (Guid), g => new Guid(g)}, + { + typeof (TimeSpan), + s => TimeSpan.Parse(s) + }, + { + typeof (DateTime), + t => DateTime.Parse(t) + } + }; + + private readonly Func conversionFunction; + private readonly Type type; + + public SimpleConverter(Type type, Func conversionFunction) + { + this.type = type; + this.conversionFunction = conversionFunction; + } + + public static void Register() + { + foreach (var key in converters) + { + var converter = new SimpleConverter(key.Key, key.Value); + TypeDescriptor.RegisterConverter(key.Key, converter); + TypeDescriptor.RegisterConverter(typeof (Nullable<>).MakeGenericType(key.Key), converter); + } + } + + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof (string); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType.IsAssignableFrom(type); + } + + private object Convert(string sourceString) + { + if (sourceString == null) + { + return null; + } + return conversionFunction.Invoke(sourceString); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + return Convert(value as string); + } + + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, + Type destinationType) + { + return Convert(value as string); + } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\AttributesUtil.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\AttributesUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\AttributesUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\AttributesUtil.cs Sun Feb 13 20:17:26 2011 @@ -0,0 +1,126 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System; + using System.ComponentModel; + using System.Linq; + using System.Reflection; + + /// + /// Helper class for retrieving attributes. + /// + internal static class AttributesUtil + { + /// + /// Gets the attribute. + /// + /// The member. + /// The member attribute. + public static T GetAttribute(this ICustomAttributeProvider member) where T : class + { + return GetAttributes(member).FirstOrDefault(); + } + + /// + /// Gets the attributes. Does not consider inherited attributes! + /// + /// The member. + /// The member attributes. + public static T[] GetAttributes(this ICustomAttributeProvider member) where T : class + { + if (typeof(T) != typeof(object)) + { + return (T[])member.GetCustomAttributes(typeof(T), false); + } + return (T[])member.GetCustomAttributes(false); + } + + /// + /// Gets the type attribute. + /// + /// The type. + /// The type attribute. + public static T GetTypeAttribute(this Type type) where T : class + { + var attribute = GetAttribute(type); + + if (attribute == null) + { + foreach (var baseInterface in type.GetInterfaces()) + { + attribute = GetTypeAttribute(baseInterface); + if (attribute != null) + { + break; + } + } + } + + return attribute; + } + + /// + /// Gets the type attributes. + /// + /// The type. + /// The type attributes. + public static T[] GetTypeAttributes(Type type) where T : class + { + var attributes = GetAttributes(type); + + if (attributes.Length == 0) + { + foreach (var baseInterface in type.GetInterfaces()) + { + attributes = GetTypeAttributes(baseInterface); + if (attributes.Length > 0) + { + break; + } + } + } + + return attributes; + } + + /// + /// Gets the type converter. + /// + /// The member. + /// + public static Type GetTypeConverter(MemberInfo member) + { + var attrib = GetAttribute(member); + + if (attrib != null) + { + return Type.GetType(attrib.ConverterTypeName); + } + + return null; + } + + /// + /// Gets the attribute. + /// + /// The member. + /// The member attribute. + public static bool HasAttribute(this ICustomAttributeProvider member) where T : class + { + return GetAttributes(member).FirstOrDefault() != null; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\ILockHolder.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\ILockHolder.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\ILockHolder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\ILockHolder.cs Sun Feb 13 20:17:34 2011 @@ -0,0 +1,23 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System; + + internal interface ILockHolder:IDisposable + { + bool LockAcquired { get; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\InternalsVisible.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\InternalsVisible.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\InternalsVisible.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\InternalsVisible.cs Sun Feb 13 22:28:48 2011 @@ -0,0 +1,39 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + internal class InternalsVisible + { + /// + /// Constant to use when making assembly internals visible to Castle.Core + /// [assembly: InternalsVisibleTo(CoreInternalsVisible.ToCastleCore)] + /// + public const string ToCastleCore = + "NMock3, PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001000b09e431bbf2a7" + + "2b9fa2762be9bb5c578786d01e66f739ce978c17237d6157a8ab82c0587d1bafebb116bc4509c4" + + "44ac46067d1f156747be6885e35b9dd4d6be4fab7af4034964d38ab34cc7e39fbf4348ec856af3" + + "fd97ef55b7e28f321ff11ef7dec0e8fb1f262ec57f7ca2b35ff5ad91246a119de227061fa47561" + + "6feee7f7"; + //"Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB"; + + /// + /// Constant to use when making assembly internals visible to proxy types generated by DynamicProxy. Required when proxying internal types. + /// [assembly: InternalsVisibleTo(CoreInternalsVisible.ToDynamicProxyGenAssembly2)] + /// + public const string ToDynamicProxyGenAssembly2 = + "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\IUpgradeableLockHolder.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\IUpgradeableLockHolder.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\IUpgradeableLockHolder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\IUpgradeableLockHolder.cs Sun Feb 13 20:17:45 2011 @@ -0,0 +1,22 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + internal interface IUpgradeableLockHolder : ILockHolder + { + ILockHolder Upgrade(); + ILockHolder Upgrade(bool waitForLock); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\Lock.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\Lock.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\Lock.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\Lock.cs Sun Feb 13 20:17:51 2011 @@ -0,0 +1,40 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + internal abstract class Lock + { + public abstract IUpgradeableLockHolder ForReadingUpgradeable(); + public abstract ILockHolder ForReading(); + public abstract ILockHolder ForWriting(); + + public abstract IUpgradeableLockHolder ForReadingUpgradeable(bool waitForLock); + public abstract ILockHolder ForReading(bool waitForLock); + public abstract ILockHolder ForWriting(bool waitForLock); + + /// + /// Creates a new lock. + /// + /// + public static Lock Create() + { +#if SILVERLIGHT + return new MonitorLock(); +#else + return new SlimReadWriteLock(); +#endif + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\MonitorLock.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\MonitorLock.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\MonitorLock.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\MonitorLock.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,53 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ +#if SILVERLIGHT + internal class MonitorLock : Lock + { + private readonly object locker = new object(); + + public override IUpgradeableLockHolder ForReadingUpgradeable() + { + return ForReadingUpgradeable(true); + } + + public override ILockHolder ForReading() + { + return ForReading(true); + } + + public override ILockHolder ForWriting() + { + return ForWriting(true); + } + + public override IUpgradeableLockHolder ForReadingUpgradeable(bool waitForLock) + { + return new MonitorUpgradeableLockHolder(locker, waitForLock); + } + + public override ILockHolder ForReading(bool waitForLock) + { + return new MonitorLockHolder(locker, waitForLock); + } + + public override ILockHolder ForWriting(bool waitForLock) + { + return new MonitorLockHolder(locker, waitForLock); + } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\MonitorLockHolder.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\MonitorLockHolder.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\MonitorLockHolder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\MonitorLockHolder.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,49 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System.Threading; + + internal class MonitorLockHolder : ILockHolder + { + private readonly object locker; + private bool lockAcquired; + + public MonitorLockHolder(object locker, bool waitForLock) + { + this.locker = locker; + if(waitForLock) + { + Monitor.Enter(locker); + lockAcquired = true; + return; + } + + lockAcquired = Monitor.TryEnter(locker, 0); + } + + public void Dispose() + { + if (!LockAcquired) return; + Monitor.Exit(locker); + lockAcquired = false; + } + + public bool LockAcquired + { + get { return lockAcquired; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\MonitorUpgradeableLockHolder.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\MonitorUpgradeableLockHolder.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\MonitorUpgradeableLockHolder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\MonitorUpgradeableLockHolder.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,58 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System.Threading; + + internal class MonitorUpgradeableLockHolder : IUpgradeableLockHolder + { + private readonly object locker; + private bool lockAcquired; + + public MonitorUpgradeableLockHolder(object locker, bool waitForLock) + { + this.locker = locker; + if(waitForLock) + { + Monitor.Enter(locker); + lockAcquired = true; + return; + } + lockAcquired = Monitor.TryEnter(locker, 0); + } + + public void Dispose() + { + if (!LockAcquired) return; + Monitor.Exit(locker); + lockAcquired = false; + } + + public ILockHolder Upgrade() + { + return NoOpLock.Lock; + } + + public ILockHolder Upgrade(bool waitForLock) + { + return NoOpLock.Lock; + } + + public bool LockAcquired + { + get { return lockAcquired; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\NoOpLock.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\NoOpLock.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\NoOpLock.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\NoOpLock.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,31 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + internal class NoOpLock : ILockHolder + { + public static readonly ILockHolder Lock = new NoOpLock(); + + public void Dispose() + { + + } + + public bool LockAcquired + { + get { return true; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\NoOpUpgradeableLock.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\NoOpUpgradeableLock.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\NoOpUpgradeableLock.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\NoOpUpgradeableLock.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,41 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + internal class NoOpUpgradeableLock : IUpgradeableLockHolder + { + public static readonly IUpgradeableLockHolder Lock = new NoOpUpgradeableLock(); + + public void Dispose() + { + + } + + public bool LockAcquired + { + get { return true; } + } + + public ILockHolder Upgrade() + { + return NoOpLock.Lock; + } + + public ILockHolder Upgrade(bool waitForLock) + { + return NoOpLock.Lock; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\PermissionUtil.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\PermissionUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\PermissionUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\PermissionUtil.cs Sun Feb 13 20:18:06 2011 @@ -0,0 +1,40 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System; + using System.Security; + using System.Security.Permissions; + +#if !SILVERLIGHT + internal static class PermissionUtil + { +#if DOTNET + [SecuritySafeCritical] +#endif + public static bool IsGranted(this IPermission permission) + { +#if DOTNET35 || MONO26 + return SecurityManager.IsGranted(permission); +#else + var permissionSet = new PermissionSet(PermissionState.None); + permissionSet.AddPermission(permission); + + return permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet); +#endif + } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimReadLockHolder.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimReadLockHolder.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimReadLockHolder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimReadLockHolder.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,51 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System.Threading; + +#if !SILVERLIGHT + + internal class SlimReadLockHolder : ILockHolder + { + private readonly ReaderWriterLockSlim locker; + private bool lockAcquired; + + public SlimReadLockHolder(ReaderWriterLockSlim locker, bool waitForLock) + { + this.locker = locker; + if(waitForLock) + { + locker.EnterReadLock(); + lockAcquired = true; + return; + } + lockAcquired = locker.TryEnterReadLock(0); + } + + public void Dispose() + { + if (!LockAcquired) return; + locker.ExitReadLock(); + lockAcquired = false; + } + + public bool LockAcquired + { + get { return lockAcquired; } + } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimReadWriteLock.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimReadWriteLock.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimReadWriteLock.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimReadWriteLock.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,82 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System.Threading; + +#if !SILVERLIGHT + + internal class SlimReadWriteLock : Lock + { + private readonly ReaderWriterLockSlim locker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); + + public override IUpgradeableLockHolder ForReadingUpgradeable() + { + return ForReadingUpgradeable(true); + } + + public override ILockHolder ForReading() + { + return ForReading(true); + } + + public override ILockHolder ForWriting() + { + return ForWriting(true); + } + + public override IUpgradeableLockHolder ForReadingUpgradeable(bool waitForLock) + { + return new SlimUpgradeableReadLockHolder(locker, waitForLock, locker.IsUpgradeableReadLockHeld || locker.IsWriteLockHeld); + } + + public override ILockHolder ForReading(bool waitForLock) + { + if (locker.IsReadLockHeld || locker.IsUpgradeableReadLockHeld || locker.IsWriteLockHeld) + { + return NoOpLock.Lock; + } + + return new SlimReadLockHolder(locker, waitForLock); + } + + public override ILockHolder ForWriting(bool waitForLock) + { + if (locker.IsWriteLockHeld) + { + return NoOpLock.Lock; + } + + return new SlimWriteLockHolder(locker, waitForLock); + } + + public bool IsReadLockHeld + { + get { return locker.IsReadLockHeld; } + } + + public bool IsUpgradeableReadLockHeld + { + get { return locker.IsUpgradeableReadLockHeld; } + } + + public bool IsWriteLockHeld + { + get { return locker.IsWriteLockHeld; } + } + } + +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimUpgradeableReadLockHolder.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimUpgradeableReadLockHolder.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimUpgradeableReadLockHolder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimUpgradeableReadLockHolder.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,86 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System.Threading; + +#if !SILVERLIGHT + + internal class SlimUpgradeableReadLockHolder : IUpgradeableLockHolder + { + private readonly ReaderWriterLockSlim locker; + private bool lockAcquired; + private SlimWriteLockHolder writerLock; + private bool wasLockAlreadyHeld; + + public SlimUpgradeableReadLockHolder(ReaderWriterLockSlim locker, bool waitForLock, bool wasLockAlreadyHelf) + { + this.locker = locker; + if (wasLockAlreadyHelf) + { + lockAcquired = true; + wasLockAlreadyHeld = true; + return; + } + + if(waitForLock) + { + locker.EnterUpgradeableReadLock(); + lockAcquired = true; + return; + } + + lockAcquired = locker.TryEnterUpgradeableReadLock(0); + } + + public void Dispose() + { + if (writerLock != null && writerLock.LockAcquired) + { + writerLock.Dispose(); + writerLock = null; + } + if (!LockAcquired) return; + if (!wasLockAlreadyHeld) + { + locker.ExitUpgradeableReadLock(); + } + lockAcquired = false; + + } + + public ILockHolder Upgrade() + { + return Upgrade(true); + } + + public ILockHolder Upgrade(bool waitForLock) + { + if(locker.IsWriteLockHeld) + { + return NoOpLock.Lock; + } + + writerLock = new SlimWriteLockHolder(locker, waitForLock); + return writerLock; + } + + public bool LockAcquired + { + get { return lockAcquired; } + } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimWriteLockHolder.cs nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimWriteLockHolder.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Internal\SlimWriteLockHolder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Internal\SlimWriteLockHolder.cs Sun Feb 13 18:56:55 2011 @@ -0,0 +1,51 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Internal +{ + using System.Threading; + +#if !SILVERLIGHT + internal class SlimWriteLockHolder : ILockHolder + { + private readonly ReaderWriterLockSlim locker; + + private bool lockAcquired; + + public SlimWriteLockHolder(ReaderWriterLockSlim locker, bool waitForLock) + { + this.locker = locker; + if(waitForLock) + { + locker.EnterWriteLock(); + lockAcquired = true; + return; + } + lockAcquired = locker.TryEnterWriteLock(0); + } + + public void Dispose() + { + if(!LockAcquired) return; + locker.ExitWriteLock(); + lockAcquired = false; + } + + public bool LockAcquired + { + get { return lockAcquired; } + } + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\IServiceEnabledComponent.cs nmock3-62490\MAIN\Source\Castle\Core\IServiceEnabledComponent.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\IServiceEnabledComponent.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\IServiceEnabledComponent.cs Sun Feb 13 20:41:31 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + using System; + + /// + /// Defines that the implementation wants a + /// in order to + /// access other components. The creator must be aware + /// that the component might (or might not) implement + /// the interface. + /// + /// + /// Used by Castle Project components to, for example, + /// gather logging factories + /// + internal interface IServiceEnabledComponent + { + void Service(IServiceProvider provider); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\IServiceProviderEx.cs nmock3-62490\MAIN\Source\Castle\Core\IServiceProviderEx.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\IServiceProviderEx.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\IServiceProviderEx.cs Sun Feb 13 20:41:37 2011 @@ -0,0 +1,26 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + using System; + + /// + /// Increments IServiceProvider with a generic service resolution operation. + /// + internal interface IServiceProviderEx : IServiceProvider + { + T GetService() where T : class; + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\IServiceProviderExAccessor.cs nmock3-62490\MAIN\Source\Castle\Core\IServiceProviderExAccessor.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\IServiceProviderExAccessor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\IServiceProviderExAccessor.cs Sun Feb 13 20:41:42 2011 @@ -0,0 +1,31 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + /// + /// This interface should be implemented by classes + /// that are available in a bigger context, exposing + /// the container to different areas in the same application. + /// + /// For example, in Web application, the (global) HttpApplication + /// subclasses should implement this interface to expose + /// the configured container + /// + /// + internal interface IServiceProviderExAccessor + { + IServiceProviderEx ServiceProvider { get; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\AbstractExtendedLoggerFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\AbstractExtendedLoggerFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\AbstractExtendedLoggerFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\AbstractExtendedLoggerFactory.cs Sun Feb 13 20:20:12 2011 @@ -0,0 +1,113 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + using System.IO; + +#if SILVERLIGHT + internal abstract class AbstractExtendedLoggerFactory : IExtendedLoggerFactory +#else + internal abstract class AbstractExtendedLoggerFactory : MarshalByRefObject, IExtendedLoggerFactory +#endif + { + /// + /// Creates a new extended logger, getting the logger name from the specified type. + /// + public virtual IExtendedLogger Create(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return Create(type.FullName); + } + + /// + /// Creates a new extended logger. + /// + public abstract IExtendedLogger Create(string name); + + /// + /// Creates a new extended logger, getting the logger name from the specified type. + /// + public virtual IExtendedLogger Create(Type type, LoggerLevel level) + { + if (type == null) throw new ArgumentNullException("type"); + + return Create(type.FullName, level); + } + + /// + /// Creates a new extended logger. + /// + public abstract IExtendedLogger Create(string name, LoggerLevel level); + + /// + /// Creates a new logger, getting the logger name from the specified type. + /// + ILogger ILoggerFactory.Create(Type type) + { + return Create(type); + } + + /// + /// Creates a new logger. + /// + ILogger ILoggerFactory.Create(string name) + { + return Create(name); + } + + /// + /// Creates a new logger, getting the logger name from the specified type. + /// + ILogger ILoggerFactory.Create(Type type, LoggerLevel level) + { + return Create(type, level); + } + + /// + /// Creates a new logger. + /// + ILogger ILoggerFactory.Create(string name, LoggerLevel level) + { + return Create(name, level); + } + + /// + /// Gets the configuration file. + /// + /// i.e. log4net.config + /// + protected static FileInfo GetConfigFile(string fileName) + { +#if !SILVERLIGHT + FileInfo result; + + if (Path.IsPathRooted(fileName)) + { + result = new FileInfo(fileName); + } + else + { + result = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName)); + } + + return result; +#else + return new FileInfo(fileName); +#endif + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\AbstractLoggerFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\AbstractLoggerFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\AbstractLoggerFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\AbstractLoggerFactory.cs Sun Feb 13 20:20:20 2011 @@ -0,0 +1,70 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + using System.IO; + +#if SILVERLIGHT + internal abstract class AbstractLoggerFactory : ILoggerFactory +#else + [Serializable] + internal abstract class AbstractLoggerFactory : MarshalByRefObject, ILoggerFactory +#endif + { + public virtual ILogger Create(Type type) + { + if (type == null) throw new ArgumentNullException("type"); + + return Create(type.FullName); + } + + public virtual ILogger Create(Type type, LoggerLevel level) + { + if (type == null) throw new ArgumentNullException("type"); + + return Create(type.FullName, level); + } + + public abstract ILogger Create(String name); + + public abstract ILogger Create(String name, LoggerLevel level); + + /// + /// Gets the configuration file. + /// + /// i.e. log4net.config + /// + protected static FileInfo GetConfigFile(string fileName) + { +#if !SILVERLIGHT + FileInfo result; + + if (Path.IsPathRooted(fileName)) + { + result = new FileInfo(fileName); + } + else + { + result = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName)); + } + + return result; +#else + return new FileInfo(fileName); +#endif + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ConsoleFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\ConsoleFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ConsoleFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\ConsoleFactory.cs Sun Feb 13 20:20:30 2011 @@ -0,0 +1,46 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + +#if SILVERLIGHT + internal class ConsoleFactory : ILoggerFactory +#else + [Serializable] + internal class ConsoleFactory : MarshalByRefObject, ILoggerFactory +#endif + { + public ILogger Create(Type type) + { + return new ConsoleLogger(type.FullName); + } + + public ILogger Create(String name) + { + return new ConsoleLogger(name); + } + + public ILogger Create(Type type, LoggerLevel level) + { + return new ConsoleLogger(type.Name, level); + } + + public ILogger Create(String name, LoggerLevel level) + { + return new ConsoleLogger(name, level); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ConsoleLogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\ConsoleLogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ConsoleLogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\ConsoleLogger.cs Sun Feb 13 20:20:38 2011 @@ -0,0 +1,100 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + using System.Globalization; + + /// + /// The Logger sending everything to the standard output streams. + /// This is mainly for the cases when you have a utility that + /// does not have a logger to supply. + /// +#if !SILVERLIGHT + [Serializable] +#endif + internal class ConsoleLogger : LevelFilteredLogger + { + /// + /// Creates a new ConsoleLogger with the Level + /// set to LoggerLevel.Debug and the Name + /// set to String.Empty. + /// + public ConsoleLogger() : this(String.Empty, LoggerLevel.Debug) + { + } + + /// + /// Creates a new ConsoleLogger with the Name + /// set to String.Empty. + /// + /// The logs Level. + public ConsoleLogger(LoggerLevel logLevel) : this(String.Empty, logLevel) + { + } + + /// + /// Creates a new ConsoleLogger with the Level + /// set to LoggerLevel.Debug. + /// + /// The logs Name. + public ConsoleLogger(String name) : this(name, LoggerLevel.Debug) + { + } + + /// + /// Creates a new ConsoleLogger. + /// + /// The logs Name. + /// The logs Level. + public ConsoleLogger(String name, LoggerLevel logLevel) : base(name, logLevel) + { + } + + /// + /// A Common method to log. + /// + /// The level of logging + /// The name of the logger + /// The Message + /// The Exception + protected override void Log(LoggerLevel loggerLevel, String loggerName, String message, Exception exception) + { + Console.Out.WriteLine("[{0}] '{1}' {2}", loggerLevel, loggerName, message); + + if (exception != null) + { + Console.Out.WriteLine("[{0}] '{1}' {2}: {3} {4}", loggerLevel.ToString(), loggerName, exception.GetType().FullName, + exception.Message, exception.StackTrace); + } + } + + /// + /// Returns a new ConsoleLogger with the name + /// added after this loggers name, with a dot in between. + /// + /// The added hierarchical name. + /// A new ConsoleLogger. + public override ILogger CreateChildLogger(string loggerName) + { + if (loggerName == null) + { + throw new ArgumentNullException("loggerName", "To create a child logger you must supply a non null name"); + } + + return new ConsoleLogger(String.Format(CultureInfo.CurrentCulture, "{0}.{1}", Name, loggerName), Level); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\DiagnosticsLogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\DiagnosticsLogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\DiagnosticsLogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\DiagnosticsLogger.cs Sun Feb 13 20:20:43 2011 @@ -0,0 +1,144 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + #if !SILVERLIGHT + using System; + using System.Diagnostics; + using System.Globalization; + + /// + /// The Logger using standart Diagnostics namespace. + /// + [Serializable] + internal class DiagnosticsLogger : LevelFilteredLogger, IDisposable + { + [NonSerialized] + private EventLog eventLog; + + /// + /// Creates a logger based on . + /// + /// + public DiagnosticsLogger(string logName) : this(logName, "default") + { + } + + /// + /// Creates a logger based on . + /// + /// + /// + public DiagnosticsLogger(string logName, string source) : base(LoggerLevel.Debug) + { + // Create the source, if it does not already exist. + if (!EventLog.SourceExists(source)) + { + EventLog.CreateEventSource(source, logName); + } + + eventLog = new EventLog(logName); + eventLog.Source = source; + } + + /// + /// Creates a logger based on . + /// + /// + /// + /// + public DiagnosticsLogger(string logName, string machineName, string source) + { + // Create the source, if it does not already exist. + if (!EventLog.SourceExists(source, machineName)) + { + var eventSourceCreationData = new EventSourceCreationData(source, logName); + eventSourceCreationData.MachineName = machineName; + EventLog.CreateEventSource(eventSourceCreationData); + } + + eventLog = new EventLog(logName, machineName, source); + } + + ~DiagnosticsLogger() + { + Dispose(false); + } + + #region IDisposable Members + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + + protected virtual void Dispose(bool disposing) + { + if( disposing ) + { + if (eventLog != null) + { + eventLog.Close(); + eventLog = null; + } + } + } + + public override ILogger CreateChildLogger(string loggerName) + { + return new DiagnosticsLogger(eventLog.Log, eventLog.MachineName, eventLog.Source); + } + + protected override void Log(LoggerLevel loggerLevel, string loggerName, string message, Exception exception) + { + if (eventLog == null) return; // just in case it was disposed + + EventLogEntryType type = TranslateLevel(loggerLevel); + + String contentToLog; + + if (exception == null) + { + contentToLog = string.Format(CultureInfo.CurrentCulture, "[{0}] '{1}' message: {2}", loggerLevel.ToString(), loggerName, message); + } + else + { + contentToLog = string.Format(CultureInfo.CurrentCulture, "[{0}] '{1}' message: {2} exception: {3} {4} {5}", + loggerLevel.ToString(), loggerName, message, exception.GetType(), exception.Message, + exception.StackTrace); + } + + eventLog.WriteEntry(contentToLog, type); + } + + private static EventLogEntryType TranslateLevel(LoggerLevel level) + { + switch(level) + { + case LoggerLevel.Error: + case LoggerLevel.Fatal: + return EventLogEntryType.Error; + case LoggerLevel.Warn: + return EventLogEntryType.Warning; + default: + return EventLogEntryType.Information; + } + } + } + #endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\DiagnosticsLoggerFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\DiagnosticsLoggerFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\DiagnosticsLoggerFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\DiagnosticsLoggerFactory.cs Sun Feb 13 20:20:48 2011 @@ -0,0 +1,39 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + #if !SILVERLIGHT + using System; + + [Serializable] + internal class DiagnosticsLoggerFactory : AbstractLoggerFactory + { + private const string DefaultLogName = "CastleDefaultLogger"; + + public override ILogger Create(string name) + { + return new DiagnosticsLogger(DefaultLogName, name); + } + + public override ILogger Create(string name, LoggerLevel level) + { + DiagnosticsLogger logger = new DiagnosticsLogger(DefaultLogName, name); + logger.Level = level; + return logger; + } + } + + #endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IContextProperties.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\IContextProperties.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IContextProperties.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\IContextProperties.cs Sun Feb 13 20:20:54 2011 @@ -0,0 +1,43 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + /// + /// Interface for Context Properties implementations + /// + /// + /// + /// This interface defines a basic property get set accessor. + /// + /// + /// Based on the ContextPropertiesBase of log4net, by Nicko Cadell. + /// + /// + internal interface IContextProperties + { + /// + /// Gets or sets the value of a property + /// + /// + /// The value for the property with the specified key + /// + /// + /// + /// Gets or sets the value of a property + /// + /// + object this[string key] { get; set; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IContextStack.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\IContextStack.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IContextStack.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\IContextStack.cs Sun Feb 13 20:21:03 2011 @@ -0,0 +1,26 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + + internal interface IContextStack + { + int Count { get; } + void Clear(); + string Pop(); + IDisposable Push(string message); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IContextStacks.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\IContextStacks.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IContextStacks.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\IContextStacks.cs Sun Feb 13 20:21:09 2011 @@ -0,0 +1,21 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + internal interface IContextStacks + { + IContextStack this[string key] { get; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IExtendedLogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\IExtendedLogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IExtendedLogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\IExtendedLogger.cs Sun Feb 13 20:21:14 2011 @@ -0,0 +1,39 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + /// + /// Provides an interface that supports and + /// allows the storage and retrieval of Contexts. These are supported in + /// both log4net and NLog. + /// + internal interface IExtendedLogger : ILogger + { + /// + /// Exposes the Global Context of the extended logger. + /// + IContextProperties GlobalProperties { get; } + + /// + /// Exposes the Thread Context of the extended logger. + /// + IContextProperties ThreadProperties { get; } + + /// + /// Exposes the Thread Stack of the extended logger. + /// + IContextStacks ThreadStacks { get; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IExtendedLoggerFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\IExtendedLoggerFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\IExtendedLoggerFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\IExtendedLoggerFactory.cs Sun Feb 13 20:21:18 2011 @@ -0,0 +1,45 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + + /// + /// Provides a factory that can produce either or + /// classes. + /// + internal interface IExtendedLoggerFactory : ILoggerFactory + { + /// + /// Creates a new extended logger, getting the logger name from the specified type. + /// + new IExtendedLogger Create(Type type); + + /// + /// Creates a new extended logger. + /// + new IExtendedLogger Create(String name); + + /// + /// Creates a new extended logger, getting the logger name from the specified type. + /// + new IExtendedLogger Create(Type type, LoggerLevel level); + + /// + /// Creates a new extended logger. + /// + new IExtendedLogger Create(String name, LoggerLevel level); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ILogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\ILogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ILogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\ILogger.cs Sun Feb 13 20:22:54 2011 @@ -0,0 +1,418 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + + /// + /// Supporting Logger levels. + /// + internal enum LoggerLevel + { + /// + /// Logging will be off + /// + Off = 0, + /// + /// Fatal logging level + /// + Fatal = 1, + /// + /// Error logging level + /// + Error = 2, + /// + /// Warn logging level + /// + Warn = 3, + /// + /// Info logging level + /// + Info = 4, + /// + /// Debug logging level + /// + Debug = 5, + } + + /// + /// Manages logging. + /// + /// + /// This is a facade for the different logging subsystems. + /// It offers a simplified interface that follows IOC patterns + /// and a simplified priority/level/severity abstraction. + /// + internal interface ILogger + { + #region Debug + + /// + /// Logs a debug message. + /// + /// The message to log + void Debug(String message); + + /// + /// Logs a debug message. + /// + /// The exception to log + /// The message to log + void Debug(String message, Exception exception); + + /// + /// Logs a debug message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void Debug(String format, params Object[] args); + + /// + /// Logs a debug message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void DebugFormat(String format, params Object[] args); + + /// + /// Logs a debug message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + void DebugFormat(Exception exception, String format, params Object[] args); + + /// + /// Logs a debug message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void DebugFormat(IFormatProvider formatProvider, String format, params Object[] args); + + /// + /// Logs a debug message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void DebugFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args); + + + /// + /// Determines if messages of priority "debug" will be logged. + /// + /// True if "debug" messages will be logged. + bool IsDebugEnabled { get; } + + #endregion + + #region Info + + /// + /// Logs an info message. + /// + /// The message to log + void Info(String message); + + /// + /// Logs an info message. + /// + /// The exception to log + /// The message to log + void Info(String message, Exception exception); + + /// + /// Logs an info message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void Info(String format, params Object[] args); + + /// + /// Logs an info message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void InfoFormat(String format, params Object[] args); + + /// + /// Logs an info message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + void InfoFormat(Exception exception, String format, params Object[] args); + + /// + /// Logs an info message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void InfoFormat(IFormatProvider formatProvider, String format, params Object[] args); + + /// + /// Logs an info message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void InfoFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args); + + + /// + /// Determines if messages of priority "info" will be logged. + /// + /// True if "info" messages will be logged. + bool IsInfoEnabled { get; } + + #endregion + + #region Warn + + /// + /// Logs a warn message. + /// + /// The message to log + void Warn(String message); + + /// + /// Logs a warn message. + /// + /// The exception to log + /// The message to log + void Warn(String message, Exception exception); + + /// + /// Logs a warn message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void Warn(String format, params Object[] args); + + /// + /// Logs a warn message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void WarnFormat(String format, params Object[] args); + + /// + /// Logs a warn message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + void WarnFormat(Exception exception, String format, params Object[] args); + + /// + /// Logs a warn message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void WarnFormat(IFormatProvider formatProvider, String format, params Object[] args); + + /// + /// Logs a warn message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void WarnFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args); + + + /// + /// Determines if messages of priority "warn" will be logged. + /// + /// True if "warn" messages will be logged. + bool IsWarnEnabled { get; } + + #endregion + + #region Error + + /// + /// Logs an error message. + /// + /// The message to log + void Error(String message); + + /// + /// Logs an error message. + /// + /// The exception to log + /// The message to log + void Error(String message, Exception exception); + + /// + /// Logs an error message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void Error(String format, params Object[] args); + + /// + /// Logs an error message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void ErrorFormat(String format, params Object[] args); + + /// + /// Logs an error message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + void ErrorFormat(Exception exception, String format, params Object[] args); + + /// + /// Logs an error message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void ErrorFormat(IFormatProvider formatProvider, String format, params Object[] args); + + /// + /// Logs an error message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void ErrorFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args); + + + /// + /// Determines if messages of priority "error" will be logged. + /// + /// True if "error" messages will be logged. + bool IsErrorEnabled { get; } + + #endregion + + #region Fatal + + /// + /// Logs a fatal message. + /// + /// The message to log + void Fatal(String message); + + /// + /// Logs a fatal message. + /// + /// The exception to log + /// The message to log + void Fatal(String message, Exception exception); + + /// + /// Logs a fatal message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void Fatal(String format, params Object[] args); + + /// + /// Logs a fatal message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + void FatalFormat(String format, params Object[] args); + + /// + /// Logs a fatal message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + void FatalFormat(Exception exception, String format, params Object[] args); + + /// + /// Logs a fatal message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void FatalFormat(IFormatProvider formatProvider, String format, params Object[] args); + + /// + /// Logs a fatal message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + void FatalFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args); + + + /// + /// Determines if messages of priority "fatal" will be logged. + /// + /// True if "fatal" messages will be logged. + bool IsFatalEnabled { get; } + + #endregion + + #region FatalError (obsolete) + + /// + /// Logs a fatal error message. + /// + /// The Message + [Obsolete("Use Fatal instead")] + void FatalError(String message); + + /// + /// Logs a fatal error message. + /// + /// The Message + /// The Exception + [Obsolete("Use Fatal instead")] + void FatalError(String message, Exception exception); + + /// + /// Logs a fatal error message. + /// + /// Message format + /// Array of objects to write using format + [Obsolete("Use Fatal or FatalFormat instead")] + void FatalError(String format, params Object[] args); + + /// + /// Determines if messages of priority "fatalError" will be logged. + /// + /// True if "fatalError" messages will be logged. + [Obsolete("Use IsFatalEnabled instead")] + bool IsFatalErrorEnabled { get; } + + #endregion + + /// + /// Create a new child logger. + /// The name of the child logger is [current-loggers-name].[passed-in-name] + /// + /// The Subname of this logger. + /// The New ILogger instance. + /// If the name has an empty element name. + ILogger CreateChildLogger(String loggerName); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ILoggerFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\ILoggerFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\ILoggerFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\ILoggerFactory.cs Sun Feb 13 20:21:29 2011 @@ -0,0 +1,44 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + + /// + /// Manages the instantiation of s. + /// + internal interface ILoggerFactory + { + /// + /// Creates a new logger, getting the logger name from the specified type. + /// + ILogger Create(Type type); + + /// + /// Creates a new logger. + /// + ILogger Create(String name); + + /// + /// Creates a new logger, getting the logger name from the specified type. + /// + ILogger Create(Type type, LoggerLevel level); + + /// + /// Creates a new logger. + /// + ILogger Create(String name, LoggerLevel level); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\LevelFilteredLogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\LevelFilteredLogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\LevelFilteredLogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\LevelFilteredLogger.cs Sun Feb 13 20:21:39 2011 @@ -0,0 +1,679 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + using System.Globalization; +#if DOTNET40 + using System.Security; +#endif + using System.Security.Permissions; + + /// + /// The Level Filtered Logger class. This is a base clase which + /// provides a LogLevel attribute and reroutes all functions into + /// one Log method. + /// +#if SILVERLIGHT + internal abstract class LevelFilteredLogger : ILogger +#else + [Serializable] + internal abstract class LevelFilteredLogger : MarshalByRefObject, ILogger +#endif + { + private LoggerLevel level = LoggerLevel.Off; + private String name = "unnamed"; + + /// + /// Creates a new LevelFilteredLogger. + /// + protected LevelFilteredLogger() + { + } + + protected LevelFilteredLogger(String name) + { + ChangeName(name); + } + + protected LevelFilteredLogger(LoggerLevel loggerLevel) + { + level = loggerLevel; + } + + protected LevelFilteredLogger(String loggerName, LoggerLevel loggerLevel) : this(loggerLevel) + { + ChangeName(loggerName); + } + +#if !SILVERLIGHT + /// + /// Keep the instance alive in a remoting scenario + /// + /// +#if DOTNET40 + [SecurityCritical] +#else + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] +#endif + public override object InitializeLifetimeService() + { + return null; + } +#endif + + public abstract ILogger CreateChildLogger(string loggerName); + + /// + /// The LoggerLevel that this logger + /// will be using. Defaults to LoggerLevel.Off + /// + public LoggerLevel Level + { + get { return level; } + set { level = value; } + } + + /// + /// The name that this logger will be using. + /// Defaults to String.Empty + /// + public String Name + { + get { return name; } + } + + #region ILogger implementation + + #region Debug + + /// + /// Logs a debug message. + /// + /// The message to log + public void Debug(string message) + { + if (!IsDebugEnabled) return; + + Log(LoggerLevel.Debug, message, null); + } + + /// + /// Logs a debug message. + /// + /// The exception to log + /// The message to log + public void Debug(string message, Exception exception) + { + if (!IsDebugEnabled) return; + + Log(LoggerLevel.Debug, message, exception); + } + + /// + /// Logs a debug message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + public void DebugFormat(string format, params object[] args) + { + if (!IsDebugEnabled) return; + + Log(LoggerLevel.Debug, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + /// + /// Logs a debug message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + public void DebugFormat(Exception exception, string format, params object[] args) + { + if (!IsDebugEnabled) return; + + Log(LoggerLevel.Debug, String.Format(CultureInfo.CurrentCulture, format, args), exception); + } + + /// + /// Logs a debug message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void DebugFormat(IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsDebugEnabled) return; + + Log(LoggerLevel.Debug, String.Format(formatProvider, format, args), null); + } + + /// + /// Logs a debug message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void DebugFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsDebugEnabled) return; + + Log(LoggerLevel.Debug, String.Format(formatProvider, format, args), exception); + } + + /// + /// Logs a debug message. + /// + /// Message format + /// Array of objects to write using format + public void Debug(string format, params Object[] args) + { + if (!IsDebugEnabled) return; + + Log(LoggerLevel.Debug, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + #endregion + + #region Info + + /// + /// Logs an info message. + /// + /// The message to log + public void Info(string message) + { + if (!IsInfoEnabled) return; + + Log(LoggerLevel.Info, message, null); + } + + /// + /// Logs an info message. + /// + /// The exception to log + /// The message to log + public void Info(string message, Exception exception) + { + if (!IsInfoEnabled) return; + + Log(LoggerLevel.Info, message, exception); + } + + /// + /// Logs an info message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + public void InfoFormat(string format, params object[] args) + { + if (!IsInfoEnabled) return; + + Log(LoggerLevel.Info, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + /// + /// Logs an info message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + public void InfoFormat(Exception exception, string format, params object[] args) + { + if (!IsInfoEnabled) return; + + Log(LoggerLevel.Info, String.Format(CultureInfo.CurrentCulture, format, args), exception); + } + + /// + /// Logs an info message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void InfoFormat(IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsInfoEnabled) return; + + Log(LoggerLevel.Info, String.Format(formatProvider, format, args), null); + } + + /// + /// Logs an info message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void InfoFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsInfoEnabled) return; + + Log(LoggerLevel.Info, String.Format(formatProvider, format, args), exception); + } + + /// + /// Logs an info message. + /// + /// Message format + /// Array of objects to write using format + public void Info(string format, params Object[] args) + { + if (!IsInfoEnabled) return; + + Log(LoggerLevel.Info, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + #endregion + + #region Warn + + /// + /// Logs a warn message. + /// + /// The message to log + public void Warn(string message) + { + if (!IsWarnEnabled) return; + + Log(LoggerLevel.Warn, message, null); + } + + /// + /// Logs a warn message. + /// + /// The exception to log + /// The message to log + public void Warn(string message, Exception exception) + { + if (!IsWarnEnabled) return; + + Log(LoggerLevel.Warn, message, exception); + } + + /// + /// Logs a warn message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + public void WarnFormat(string format, params object[] args) + { + if (!IsWarnEnabled) return; + + Log(LoggerLevel.Warn, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + /// + /// Logs a warn message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + public void WarnFormat(Exception exception, string format, params object[] args) + { + if (!IsWarnEnabled) return; + + Log(LoggerLevel.Warn, String.Format(CultureInfo.CurrentCulture, format, args), exception); + } + + /// + /// Logs a warn message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void WarnFormat(IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsWarnEnabled) return; + + Log(LoggerLevel.Warn, String.Format(formatProvider, format, args), null); + } + + /// + /// Logs a warn message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void WarnFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsWarnEnabled) return; + + Log(LoggerLevel.Warn, String.Format(formatProvider, format, args), exception); + } + + /// + /// Logs a warn message. + /// + /// Message format + /// Array of objects to write using format + public void Warn(string format, params Object[] args) + { + if (!IsWarnEnabled) return; + + Log(LoggerLevel.Warn, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + #endregion + + #region Error + + /// + /// Logs an error message. + /// + /// The message to log + public void Error(string message) + { + if (!IsErrorEnabled) return; + + Log(LoggerLevel.Error, message, null); + } + + /// + /// Logs an error message. + /// + /// The exception to log + /// The message to log + public void Error(string message, Exception exception) + { + if (!IsErrorEnabled) return; + + Log(LoggerLevel.Error, message, exception); + } + + /// + /// Logs an error message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + public void ErrorFormat(string format, params object[] args) + { + if (!IsErrorEnabled) return; + + Log(LoggerLevel.Error, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + /// + /// Logs an error message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + public void ErrorFormat(Exception exception, string format, params object[] args) + { + if (!IsErrorEnabled) return; + + Log(LoggerLevel.Error, String.Format(CultureInfo.CurrentCulture, format, args), exception); + } + + /// + /// Logs an error message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void ErrorFormat(IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsErrorEnabled) return; + + Log(LoggerLevel.Error, String.Format(formatProvider, format, args), null); + } + + /// + /// Logs an error message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void ErrorFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsErrorEnabled) return; + + Log(LoggerLevel.Error, String.Format(formatProvider, format, args), exception); + } + + /// + /// Logs an error message. + /// + /// Message format + /// Array of objects to write using format + public void Error(string format, params Object[] args) + { + if (!IsErrorEnabled) return; + + Log(LoggerLevel.Error, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + #endregion + + #region Fatal + + /// + /// Logs a fatal message. + /// + /// The message to log + public void Fatal(string message) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, message, null); + } + + /// + /// Logs a fatal message. + /// + /// The exception to log + /// The message to log + public void Fatal(string message, Exception exception) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, message, exception); + } + + /// + /// Logs a fatal message. + /// + /// Format string for the message to log + /// Format arguments for the message to log + public void FatalFormat(string format, params object[] args) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + /// + /// Logs a fatal message. + /// + /// The exception to log + /// Format string for the message to log + /// Format arguments for the message to log + public void FatalFormat(Exception exception, string format, params object[] args) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, String.Format(CultureInfo.CurrentCulture, format, args), exception); + } + + /// + /// Logs a fatal message. + /// + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void FatalFormat(IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, String.Format(formatProvider, format, args), null); + } + + /// + /// Logs a fatal message. + /// + /// The exception to log + /// The format provider to use + /// Format string for the message to log + /// Format arguments for the message to log + public void FatalFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, String.Format(formatProvider, format, args), exception); + } + + /// + /// Logs a fatal message. + /// + /// Message format + /// Array of objects to write using format + public void Fatal(string format, params Object[] args) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + #endregion + + #region FatalError (obsolete) + + /// + /// Logs a fatal error message. + /// + /// The Message + [Obsolete("Use Fatal instead")] + public void FatalError(string message) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, message, null); + } + + /// + /// Logs a fatal error message. + /// + /// The Message + /// The Exception + [Obsolete("Use Fatal instead")] + public void FatalError(string message, Exception exception) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, message, exception); + } + + /// + /// Logs a fatal error message. + /// + /// Message format + /// Array of objects to write using format + [Obsolete("Use Fatal or FatalFormat instead")] + public void FatalError(string format, params Object[] args) + { + if (!IsFatalEnabled) return; + + Log(LoggerLevel.Fatal, String.Format(CultureInfo.CurrentCulture, format, args), null); + } + + #endregion + + /// + /// Determines if messages of priority "debug" will be logged. + /// + /// true if log level flags include the bit + public bool IsDebugEnabled + { + get { return (Level >= LoggerLevel.Debug); } + } + + /// + /// Determines if messages of priority "info" will be logged. + /// + /// true if log level flags include the bit + public bool IsInfoEnabled + { + get { return (Level >= LoggerLevel.Info); } + } + + /// + /// Determines if messages of priority "warn" will be logged. + /// + /// true if log level flags include the bit + public bool IsWarnEnabled + { + get { return (Level >= LoggerLevel.Warn); } + } + + /// + /// Determines if messages of priority "error" will be logged. + /// + /// true if log level flags include the bit + public bool IsErrorEnabled + { + get { return (Level >= LoggerLevel.Error); } + } + + /// + /// Determines if messages of priority "fatal" will be logged. + /// + /// true if log level flags include the bit + public bool IsFatalEnabled + { + get { return (Level >= LoggerLevel.Fatal); } + } + + /// + /// Determines if messages of priority "fatal" will be logged. + /// + /// true if log level flags include the bit + [Obsolete("Use IsFatalEnabled instead")] + public bool IsFatalErrorEnabled + { + get { return (Level >= LoggerLevel.Fatal); } + } + + #endregion + + /// + /// Implementors output the log content by implementing this method only. + /// Note that exception can be null + /// + /// + /// + /// + /// + protected abstract void Log(LoggerLevel loggerLevel, String loggerName, String message, Exception exception); + + protected void ChangeName(String newName) + { + if (newName == null) + { + throw new ArgumentNullException("newName"); + } + + name = newName; + } + + private void Log(LoggerLevel loggerLevel, String message, Exception exception) + { + Log(loggerLevel, Name, message, exception); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\LoggerException.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\LoggerException.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\LoggerException.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\LoggerException.cs Sun Feb 13 20:21:45 2011 @@ -0,0 +1,43 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + using System.Runtime.Serialization; + +#if !SILVERLIGHT + [Serializable] +#endif + internal class LoggerException : Exception + { + public LoggerException() + { + } + + public LoggerException(String message) : base(message) + { + } + + public LoggerException(String message, Exception innerException) : base(message, innerException) + { + } + +#if !SILVERLIGHT + protected LoggerException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +#endif + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\NullLogFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\NullLogFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\NullLogFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\NullLogFactory.cs Sun Feb 13 20:21:52 2011 @@ -0,0 +1,48 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + + /// + /// NullLogFactory used when logging is turned off. + /// +#if !SILVERLIGHT + [Serializable] +#endif + internal class NullLogFactory : AbstractLoggerFactory + { + /// + /// Creates an instance of ILogger with the specified name. + /// + /// Name. + /// + public override ILogger Create(String name) + { + return NullLogger.Instance; + } + + /// + /// Creates an instance of ILogger with the specified name and LoggerLevel. + /// + /// Name. + /// Level. + /// + public override ILogger Create(String name, LoggerLevel level) + { + return NullLogger.Instance; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\NullLogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\NullLogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\NullLogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\NullLogger.cs Sun Feb 13 20:21:59 2011 @@ -0,0 +1,570 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + + /// + /// The Null Logger class. This is useful for implementations where you need + /// to provide a logger to a utility class, but do not want any output from it. + /// It also helps when you have a utility that does not have a logger to supply. + /// + internal class NullLogger : IExtendedLogger + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] + public static readonly NullLogger Instance = new NullLogger(); + + /// + /// Creates a new NullLogger. + /// + public NullLogger() + { + } + + #region Debug + + /// + /// No-op. + /// + /// Ignored + public void Debug(string message) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Debug(string message, Exception exception) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Debug(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void DebugFormat(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void DebugFormat(Exception exception, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void DebugFormat(IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + /// Ignored + public void DebugFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// false + public bool IsDebugEnabled + { + get { return false; } + } + + #endregion + + #region Info + + /// + /// No-op. + /// + /// Ignored + public void Info(string message) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Info(string message, Exception exception) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Info(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void InfoFormat(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void InfoFormat(Exception exception, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void InfoFormat(IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + /// Ignored + public void InfoFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// false + public bool IsInfoEnabled + { + get { return false; } + } + + #endregion + + #region Warn + + /// + /// No-op. + /// + /// Ignored + public void Warn(string message) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Warn(string message, Exception exception) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Warn(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void WarnFormat(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void WarnFormat(Exception exception, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void WarnFormat(IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + /// Ignored + public void WarnFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// false + public bool IsWarnEnabled + { + get { return false; } + } + + #endregion + + #region Error + + /// + /// No-op. + /// + /// Ignored + public void Error(string message) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Error(string message, Exception exception) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Error(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void ErrorFormat(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void ErrorFormat(Exception exception, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void ErrorFormat(IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + /// Ignored + public void ErrorFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// false + public bool IsErrorEnabled + { + get { return false; } + } + + #endregion + + #region Fatal + + /// + /// No-op. + /// + /// Ignored + public void Fatal(string message) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Fatal(string message, Exception exception) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void Fatal(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + public void FatalFormat(string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void FatalFormat(Exception exception, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + public void FatalFormat(IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + /// Ignored + /// Ignored + public void FatalFormat(Exception exception, IFormatProvider formatProvider, string format, params object[] args) + { + } + + /// + /// No-op. + /// + /// false + public bool IsFatalEnabled + { + get { return false; } + } + + #endregion + + #region FatalError (obsolete) + + /// + /// No-op. + /// + /// Ignored + [Obsolete("Use Fatal instead")] + public void FatalError(string message) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + [Obsolete("Use Fatal instead")] + public void FatalError(string message, Exception exception) + { + } + + /// + /// No-op. + /// + /// Ignored + /// Ignored + [Obsolete("Use Fatal or FatalFormat instead")] + public void FatalError(string format, params Object[] args) + { + } + + /// + /// No-op. + /// + /// false + [Obsolete("Use IsFatalEnabled instead")] + public bool IsFatalErrorEnabled + { + get { return false; } + } + + #endregion + + /// + /// Returns this NullLogger. + /// + /// Ignored + /// This ILogger instance. + public ILogger CreateChildLogger(string loggerName) + { + return this; + } + + /// + /// Returns empty context properties. + /// + public IContextProperties GlobalProperties + { + get { return NullContextProperties.Instance; } + } + + /// + /// Returns empty context properties. + /// + public IContextProperties ThreadProperties + { + get { return NullContextProperties.Instance; } + } + + /// + /// Returns empty context stacks. + /// + public IContextStacks ThreadStacks + { + get { return NullContextStacks.Instance; } + } + + #region NullContextProperties + + private class NullContextProperties : IContextProperties + { + public static readonly NullContextProperties Instance = new NullContextProperties(); + + public object this[string key] + { + get { return null; } + set { } + } + } + + #endregion + + #region NullContextStack + + private class NullContextStack : IContextStack, IDisposable + { + public static readonly NullContextStack Instance = new NullContextStack(); + + public int Count + { + get { return 0; } + } + + public void Clear() + { + } + + public string Pop() + { + return null; + } + + public IDisposable Push(string message) + { + return this; + } + + public void Dispose() + { + GC.SuppressFinalize(this); + } + } + + #endregion + + #region NullContextStacks + + private class NullContextStacks : IContextStacks + { + public static readonly NullContextStacks Instance = new NullContextStacks(); + + public IContextStack this[string key] + { + get { return NullContextStack.Instance; } + } + } + + #endregion + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\StreamLogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\StreamLogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\StreamLogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\StreamLogger.cs Sun Feb 13 20:22:05 2011 @@ -0,0 +1,157 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + using System; + using System.IO; + using System.Text; + + /// + /// The Stream Logger class. This class can stream log information + /// to any stream, it is suitable for storing a log file to disk, + /// or to a MemoryStream for testing your components. + /// + /// + /// This logger is not thread safe. + /// +#if !SILVERLIGHT + [Serializable] +#endif + internal class StreamLogger : LevelFilteredLogger, IDisposable + { + private StreamWriter writer; + + /// + /// Creates a new StreamLogger with default encoding + /// and buffer size. Initial Level is set to Debug. + /// + /// + /// The name of the log. + /// + /// + /// The stream that will be used for logging, + /// seeking while the logger is alive + /// + public StreamLogger(String name, Stream stream) : this(name, new StreamWriter(stream)) + { + } + + /// + /// Creates a new StreamLogger with default buffer size. + /// Initial Level is set to Debug. + /// + /// + /// The name of the log. + /// + /// + /// The stream that will be used for logging, + /// seeking while the logger is alive + /// + /// + /// The encoding that will be used for this stream. + /// + /// + public StreamLogger(String name, Stream stream, Encoding encoding) : this(name, new StreamWriter(stream, encoding)) + { + } + + /// + /// Creates a new StreamLogger. + /// Initial Level is set to Debug. + /// + /// + /// The name of the log. + /// + /// + /// The stream that will be used for logging, + /// seeking while the logger is alive + /// + /// + /// The encoding that will be used for this stream. + /// + /// + /// + /// The buffer size that will be used for this stream. + /// + /// + public StreamLogger(String name, Stream stream, Encoding encoding, int bufferSize) + : this(name, new StreamWriter(stream, encoding, bufferSize)) + { + } + + ~StreamLogger() + { + Dispose(false); + } + + #region IDisposable Members + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (writer != null) + { + writer.Close(); + writer = null; + } + } + } + + /// + /// Creates a new StreamLogger with + /// Debug as default Level. + /// + /// The name of the log. + /// The StreamWriter the log will write to. + protected StreamLogger(String name, StreamWriter writer) : base(name, LoggerLevel.Debug) + { + this.writer = writer; + writer.AutoFlush = true; + } + + protected override void Log(LoggerLevel loggerLevel, String loggerName, String message, Exception exception) + { + if (writer == null) return; // just in case it's been disposed + + writer.WriteLine("[{0}] '{1}' {2}", loggerLevel.ToString(), loggerName, message); + + if (exception != null) + { + writer.WriteLine("[{0}] '{1}' {2}: {3} {4}", + loggerLevel.ToString(), + loggerName, + exception.GetType().FullName, + exception.Message, + exception.StackTrace); + } + } + + public override ILogger CreateChildLogger(string loggerName) + { + // TODO: We could create a ChildStreamLogger that didn't take ownership of the stream + + throw new NotSupportedException("A streamlogger does not support child loggers"); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\StreamLoggerFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\StreamLoggerFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\StreamLoggerFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\StreamLoggerFactory.cs Sun Feb 13 20:22:10 2011 @@ -0,0 +1,45 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + #if !SILVERLIGHT + using System; + using System.IO; + using System.Text; + + /// + /// Creates outputing + /// to files. The name of the file is derived from the log name + /// plus the 'log' extension. + /// + [Serializable] + internal class StreamLoggerFactory : AbstractLoggerFactory + { + public override ILogger Create(string name) + { + return new StreamLogger(name, new FileStream(name + ".log", FileMode.Append, FileAccess.Write), Encoding.Default); + } + + public override ILogger Create(string name, LoggerLevel level) + { + StreamLogger logger = + new StreamLogger(name, new FileStream(name + ".log", FileMode.Append, FileAccess.Write), Encoding.Default); + logger.Level = level; + return logger; + } + } + + #endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\TraceLogger.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\TraceLogger.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\TraceLogger.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\TraceLogger.cs Sun Feb 13 20:22:16 2011 @@ -0,0 +1,247 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ + #if !SILVERLIGHT + using System; + using System.Diagnostics; + using System.Collections.Generic; +#if DOTNET40 + using System.Security; +#endif + + /// + /// The TraceLogger sends all logging to the System.Diagnostics.TraceSource + /// built into the .net framework. + /// + /// + /// Logging can be configured in the system.diagnostics configuration + /// section. + /// + /// If logger doesn't find a source name with a full match it will + /// use source names which match the namespace partially. For example you can + /// configure from all castle components by adding a source name with the + /// name "Castle". + /// + /// If no portion of the namespace matches the source named "Default" will + /// be used. + /// + internal class TraceLogger : LevelFilteredLogger + { + private static readonly Dictionary cache = new Dictionary(); + + TraceSource traceSource; + + /// + /// Build a new trace logger based on the named TraceSource + /// + /// The name used to locate the best TraceSource. In most cases comes from the using type's fullname. +#if DOTNET40 + [SecuritySafeCritical] +#endif + public TraceLogger(string name) + : base(name) + { + Initialize(); + Level = MapLoggerLevel(traceSource.Switch.Level); + } + + /// + /// Build a new trace logger based on the named TraceSource + /// + /// The name used to locate the best TraceSource. In most cases comes from the using type's fullname. + /// The default logging level at which this source should write messages. In almost all cases this + /// default value will be overridden in the config file. +#if DOTNET40 + [SecuritySafeCritical] +#endif + public TraceLogger(string name, LoggerLevel level) + : base(name, level) + { + Initialize(); + Level = MapLoggerLevel(traceSource.Switch.Level); + } + + /// + /// Create a new child logger. + /// The name of the child logger is [current-loggers-name].[passed-in-name] + /// + /// The Subname of this logger. + /// The New ILogger instance. +#if DOTNET40 + [SecuritySafeCritical] +#endif + public override ILogger CreateChildLogger(string loggerName) + { + return InternalCreateChildLogger(loggerName); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private ILogger InternalCreateChildLogger(string loggerName) + { + return new TraceLogger(string.Concat(Name, ".", loggerName), Level); + } + + protected override void Log(LoggerLevel loggerLevel, string loggerName, string message, Exception exception) + { + if (exception == null) + { + traceSource.TraceEvent(MapTraceEventType(loggerLevel), 0, message); + } + else + { + traceSource.TraceData(MapTraceEventType(loggerLevel), 0, message, exception); + } + } + +#if DOTNET40 + [SecurityCritical] +#endif + void Initialize() + { + lock (cache) + { + // because TraceSource is meant to be used as a static member, and because + // building up the configuraion inheritance is non-trivial, the instances + // themselves are cached for so multiple TraceLogger instances will reuse + // the named TraceSources which have been created + + if (cache.TryGetValue(Name, out traceSource)) + return; + + + SourceLevels defaultLevel = MapSourceLevels(Level); + traceSource = new TraceSource(Name, defaultLevel); + + // no further action necessary when the named source is configured + if (IsSourceConfigured(traceSource)) + { + cache.Add(Name, traceSource); + return; + } + + // otherwise hunt for a shorter source that been configured + TraceSource foundSource = new TraceSource("Default", defaultLevel); + + string searchName = ShortenName(Name); + while (!string.IsNullOrEmpty(searchName)) + { + TraceSource searchSource = new TraceSource(searchName, defaultLevel); + if (IsSourceConfigured(searchSource)) + { + foundSource = searchSource; + break; + } + + searchName = ShortenName(searchName); + } + + // reconfigure the created source to act like the found source + traceSource.Switch = foundSource.Switch; + traceSource.Listeners.Clear(); + foreach (TraceListener listener in foundSource.Listeners) + traceSource.Listeners.Add(listener); + + cache.Add(Name, traceSource); + } + } + + static string ShortenName(string name) + { + int lastDot = name.LastIndexOf('.'); + if (lastDot != -1) + { + return name.Substring(0, lastDot); + } + return null; + } + + +#if DOTNET40 + [SecuritySafeCritical] +#endif + static bool IsSourceConfigured(TraceSource source) + { + if (source.Listeners.Count == 1 && + source.Listeners[0] is DefaultTraceListener && + source.Listeners[0].Name == "Default") + { + return false; + } + return true; + } + + + static LoggerLevel MapLoggerLevel(SourceLevels level) + { + switch (level) + { + case SourceLevels.All: + return LoggerLevel.Debug; + case SourceLevels.Verbose: + return LoggerLevel.Debug; + case SourceLevels.Information: + return LoggerLevel.Info; + case SourceLevels.Warning: + return LoggerLevel.Warn; + case SourceLevels.Error: + return LoggerLevel.Error; + case SourceLevels.Critical: + return LoggerLevel.Fatal; + } + return LoggerLevel.Off; + } + + static SourceLevels MapSourceLevels(LoggerLevel level) + { + switch (level) + { + case LoggerLevel.Debug: + return SourceLevels.Verbose; + case LoggerLevel.Info: + return SourceLevels.Information; + case LoggerLevel.Warn: + return SourceLevels.Warning; + case LoggerLevel.Error: + return SourceLevels.Error; + case LoggerLevel.Fatal: + return SourceLevels.Critical; + } + return SourceLevels.Off; + } + + static TraceEventType MapTraceEventType(LoggerLevel level) + { + switch (level) + { + case LoggerLevel.Debug: + return TraceEventType.Verbose; + case LoggerLevel.Info: + return TraceEventType.Information; + case LoggerLevel.Warn: + return TraceEventType.Warning; + case LoggerLevel.Error: + return TraceEventType.Error; + case LoggerLevel.Fatal: + return TraceEventType.Critical; + } + return TraceEventType.Verbose; + } + } + + #endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Logging\TraceLoggerFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Logging\TraceLoggerFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Logging\TraceLoggerFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Logging\TraceLoggerFactory.cs Sun Feb 13 20:22:22 2011 @@ -0,0 +1,62 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Logging +{ +#if DOTNET40 + using System.Security; +#endif + +#if !SILVERLIGHT + + /// + /// Used to create the TraceLogger implementation of ILogger interface. See . + /// + internal class TraceLoggerFactory : AbstractLoggerFactory + { +#if DOTNET40 + [SecuritySafeCritical] +#endif + public override ILogger Create(string name) + { + return InternalCreate(name); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private ILogger InternalCreate(string name) + { + return new TraceLogger(name); + } + +#if DOTNET40 + [SecuritySafeCritical] +#endif + public override ILogger Create(string name, LoggerLevel level) + { + return InternalCreate(name, level); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private ILogger InternalCreate(string name, LoggerLevel level) + { + return new TraceLogger(name, level); + } + } + + #endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Pair.cs nmock3-62490\MAIN\Source\Castle\Core\Pair.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Pair.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Pair.cs Sun Feb 13 20:41:48 2011 @@ -0,0 +1,78 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + using System; + + /// + /// General purpose class to represent a standard pair of values. + /// + /// Type of the first value + /// Type of the second value + internal class Pair : IEquatable> + { + private readonly TFirst first; + private readonly TSecond second; + + /// + /// Constructs a pair with its values + /// + /// + /// + public Pair(TFirst first, TSecond second) + { + this.first = first; + this.second = second; + } + + public TFirst First + { + get { return first; } + } + + public TSecond Second + { + get { return second; } + } + + public override string ToString() + { + return first + " " + second; + } + + public bool Equals(Pair other) + { + if (other == null) + { + return false; + } + return Equals(first, other.first) && Equals(second, other.second); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) + { + return true; + } + return Equals(obj as Pair); + } + + public override int GetHashCode() + { + return first.GetHashCode() + 29 * second.GetHashCode(); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\ProxyServices.cs nmock3-62490\MAIN\Source\Castle\Core\ProxyServices.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\ProxyServices.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\ProxyServices.cs Sun Feb 13 20:25:08 2011 @@ -0,0 +1,38 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + using System; + + /// + /// List of utility methods related to dynamic proxy operations + /// + internal static class ProxyServices + { + /// + /// Determines whether the specified type is a proxy generated by + /// DynamicProxy (1 or 2). + /// + /// The type. + /// + /// true if it is a proxy; otherwise, false. + /// + public static bool IsDynamicProxy(Type type) + { + return (type.Assembly.FullName.StartsWith("DynamicAssemblyProxyGen", StringComparison.Ordinal) || + type.Assembly.FullName.StartsWith("DynamicProxyGenAssembly2", StringComparison.Ordinal)); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\ReflectionBasedDictionaryAdapter.cs nmock3-62490\MAIN\Source\Castle\Core\ReflectionBasedDictionaryAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\ReflectionBasedDictionaryAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\ReflectionBasedDictionaryAdapter.cs Sun Feb 13 20:25:13 2011 @@ -0,0 +1,303 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + using System; + using System.Collections; + using System.Reflection; + using System.Collections.Generic; + + /// + /// Pendent + /// + internal sealed class ReflectionBasedDictionaryAdapter : IDictionary + { + private readonly Dictionary properties = + new Dictionary(StringComparer.OrdinalIgnoreCase); + + /// + /// Initializes a new instance of the class. + /// + /// The target. + public ReflectionBasedDictionaryAdapter(object target) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + var targetType = target.GetType(); + foreach (PropertyInfo property in targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + if (!property.CanRead || property.GetIndexParameters().Length > 0) continue; + var value = GetPropertyValue(target, property); + + properties[property.Name] = value; + } + } + + #region IDictionary Members + + /// + /// Determines whether the object contains an element with the specified key. + /// + /// The key to locate in the object. + /// + /// true if the contains an element with the key; otherwise, false. + /// + /// + /// is null. + public bool Contains(object key) + { + return properties.ContainsKey(key.ToString()); + } + + /// + /// Gets or sets the with the specified key. + /// + /// + public object this[object key] + { + get + { + object value; + properties.TryGetValue(key.ToString(), out value); + return value; + } + set { throw new NotImplementedException(); } + } + + /// + /// Adds an element with the provided key and value to the object. + /// + /// The to use as the key of the element to add. + /// The to use as the value of the element to add. + /// + /// is null. + /// An element with the same key already exists in the object. + /// The is read-only.-or- The has a fixed size. + public void Add(object key, object value) + { + throw new NotImplementedException(); + } + + /// + /// Removes all elements from the object. + /// + /// The object is read-only. + public void Clear() + { + throw new NotImplementedException(); + } + + /// + /// Returns an object for the object. + /// + /// + /// An object for the object. + /// + IDictionaryEnumerator IDictionary.GetEnumerator() + { + return new DictionaryEntryEnumeratorAdapter(properties.GetEnumerator()); + } + + /// + /// Removes the element with the specified key from the object. + /// + /// The key of the element to remove. + /// + /// is null. + /// The object is read-only.-or- The has a fixed size. + public void Remove(object key) + { + } + + /// + /// Gets an object containing the keys of the object. + /// + /// + /// An object containing the keys of the object. + public ICollection Keys + { + get { return properties.Keys; } + } + + /// + /// Gets an object containing the values in the object. + /// + /// + /// An object containing the values in the object. + public ICollection Values + { + get { return properties.Values; } + } + + /// + /// Gets a value indicating whether the object is read-only. + /// + /// + /// true if the object is read-only; otherwise, false. + public bool IsReadOnly + { + get { return true; } + } + + /// + /// Gets a value indicating whether the object has a fixed size. + /// + /// + /// true if the object has a fixed size; otherwise, false. + bool IDictionary.IsFixedSize + { + get { throw new NotImplementedException(); } + } + + /// + /// Copies the elements of the to an , starting at a particular index. + /// + /// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + /// The zero-based index in at which copying begins. + /// + /// is null. + /// + /// is less than zero. + /// + /// is multidimensional.-or- is equal to or greater than the length of .-or- The number of elements in the source is greater than the available space from to the end of the destination . + /// The type of the source cannot be cast automatically to the type of the destination . + void ICollection.CopyTo(Array array, int index) + { + throw new NotImplementedException(); + } + + /// + /// Gets the number of elements contained in the . + /// + /// + /// The number of elements contained in the . + public int Count + { + get { return properties.Count; } + } + + /// + /// Gets an object that can be used to synchronize access to the . + /// + /// + /// An object that can be used to synchronize access to the . + public object SyncRoot + { + get { return properties; } + } + + /// + /// Gets a value indicating whether access to the is synchronized (thread safe). + /// + /// + /// true if access to the is synchronized (thread safe); otherwise, false. + public bool IsSynchronized + { + get { return false; } + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// + /// An object that can be used to iterate through the collection. + /// + public IEnumerator GetEnumerator() + { + return new DictionaryEntryEnumeratorAdapter(properties.GetEnumerator()); + } + + #endregion + + private object GetPropertyValue(object target, PropertyInfo property) + { + try + { + return property.GetValue(target, null); + } + catch (MethodAccessException +#if SILVERLIGHT + e) + { + string message = "Could not read properties of anonymous object due to restrictive behavior of Silverlight. Make your assembly internal types visible to Castle.Core by adding the following attribute: [assembly: InternalsVisibleTo(InternalsVisible.ToCastleCore)]"; + throw new InvalidOperationException(message,e); +#else +) + { + throw; +#endif + } + } + + #region Nested type: DictionaryEntryEnumeratorAdapter + + private class DictionaryEntryEnumeratorAdapter : IDictionaryEnumerator + { + private readonly IDictionaryEnumerator enumerator; + private KeyValuePair current; + + public DictionaryEntryEnumeratorAdapter(IDictionaryEnumerator enumerator) + { + this.enumerator = enumerator; + } + + #region IDictionaryEnumerator Members + + public object Key + { + get { return current.Key; } + } + + public object Value + { + get { return current.Value; } + } + + public DictionaryEntry Entry + { + get { return new DictionaryEntry(Key, Value); } + } + + public bool MoveNext() + { + var moved = enumerator.MoveNext(); + + if (moved) + { + current = (KeyValuePair) enumerator.Current; + } + + return moved; + } + + public void Reset() + { + enumerator.Reset(); + } + + public object Current + { + get { return new DictionaryEntry(Key, Value); } + } + + #endregion + } + + #endregion + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AbstractResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\AbstractResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AbstractResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\AbstractResource.cs Sun Feb 13 20:33:07 2011 @@ -0,0 +1,49 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.IO; + using System.Text; + + internal abstract class AbstractResource : IResource + { +#if SILVERLIGHT + protected static readonly String DefaultBasePath = String.Empty; +#else + protected static readonly String DefaultBasePath = AppDomain.CurrentDomain.BaseDirectory; +#endif + + public virtual String FileBasePath + { + get { return DefaultBasePath; } + } + + public abstract TextReader GetStreamReader(); + + public abstract TextReader GetStreamReader(Encoding encoding); + + public abstract IResource CreateRelative(String relativePath); + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + {} + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AbstractStreamResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\AbstractStreamResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AbstractStreamResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\AbstractStreamResource.cs Sun Feb 13 20:33:15 2011 @@ -0,0 +1,54 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System.IO; + using System.Text; + + internal delegate Stream StreamFactory(); + + /// + /// + /// + internal abstract class AbstractStreamResource : AbstractResource + { + /// + /// This returns a new stream instance each time it is called. + /// It is the responsability of the caller to dispose of this stream + /// + private StreamFactory createStream; + + ~AbstractStreamResource() + { + Dispose(false); + } + + public StreamFactory CreateStream + { + get { return createStream; } + set { createStream = value; } + } + + public override TextReader GetStreamReader() + { + return new StreamReader(CreateStream()); + } + + public override TextReader GetStreamReader(Encoding encoding) + { + return new StreamReader(CreateStream(), encoding); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AssemblyBundleResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\AssemblyBundleResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AssemblyBundleResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\AssemblyBundleResource.cs Sun Feb 13 20:33:22 2011 @@ -0,0 +1,72 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.Globalization; + using System.IO; + using System.Reflection; + using System.Resources; + using System.Text; + + internal class AssemblyBundleResource : AbstractResource + { + private readonly CustomUri resource; + + public AssemblyBundleResource(CustomUri resource) + { + this.resource = resource; + } + + public override TextReader GetStreamReader() + { + var assembly = ObtainAssembly(resource.Host); + + var paths = resource.Path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries); + if (paths.Length != 2) + { + throw new ResourceException("AssemblyBundleResource does not support paths with more than 2 levels in depth. See " + + resource.Path); + } + + var rm = new ResourceManager(paths[0], assembly); + + return new StringReader(rm.GetString(paths[1])); + } + + public override TextReader GetStreamReader(Encoding encoding) + { + return GetStreamReader(); + } + + public override IResource CreateRelative(string relativePath) + { + throw new NotImplementedException(); + } + + private static Assembly ObtainAssembly(string assemblyName) + { + try + { + return Assembly.Load(assemblyName); + } + catch (Exception ex) + { + var message = String.Format(CultureInfo.InvariantCulture, "The assembly {0} could not be loaded", assemblyName); + throw new ResourceException(message, ex); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AssemblyResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\AssemblyResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AssemblyResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\AssemblyResource.cs Sun Feb 13 20:33:28 2011 @@ -0,0 +1,156 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.Globalization; + using System.IO; + using System.Reflection; + + internal class AssemblyResource : AbstractStreamResource + { + private string assemblyName; + private string resourcePath; + private String basePath; + + public AssemblyResource(CustomUri resource) + { + CreateStream = delegate + { + return CreateResourceFromUri(resource, null); + }; + } + + public AssemblyResource(CustomUri resource, String basePath) + { + CreateStream = delegate + { + return CreateResourceFromUri(resource, basePath); + }; + } + + public AssemblyResource(String resource) + { + CreateStream = delegate + { + return CreateResourceFromPath(resource, basePath); + }; + } + + public override IResource CreateRelative(String relativePath) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return String.Format(CultureInfo.CurrentCulture, "AssemblyResource: [{0}] [{1}]", assemblyName, resourcePath); + } + + private Stream CreateResourceFromPath(String resource, String path) + { + if (!resource.StartsWith("assembly" + CustomUri.SchemeDelimiter, StringComparison.CurrentCulture)) + { + resource = "assembly" + CustomUri.SchemeDelimiter + resource; + } + + return CreateResourceFromUri(new CustomUri(resource), path); + } + + private Stream CreateResourceFromUri(CustomUri resourcex, String path) + { + if (resourcex == null) throw new ArgumentNullException("resourcex"); + + assemblyName = resourcex.Host; + resourcePath = ConvertToResourceName(assemblyName, resourcex.Path); + + Assembly assembly = ObtainAssembly(assemblyName); + + String[] names = assembly.GetManifestResourceNames(); + + String nameFound = GetNameFound(names); + + if (nameFound == null) + { + resourcePath = resourcex.Path.Replace('/', '.').Substring(1); + nameFound = GetNameFound(names); + } + + if (nameFound == null) + { + String message = String.Format(CultureInfo.InvariantCulture, "The assembly resource {0} could not be located", resourcePath); + throw new ResourceException(message); + } + + basePath = ConvertToPath(resourcePath); + + return assembly.GetManifestResourceStream(nameFound); + } + + private string GetNameFound(string[] names) + { + string nameFound = null; + foreach(String name in names) + { + if (String.Compare(resourcePath, name, StringComparison.OrdinalIgnoreCase) == 0) + { + nameFound = name; + break; + } + } + return nameFound; + } + + private string ConvertToResourceName(String assembly, String resource) + { + assembly = GetSimpleName(assembly); + // TODO: use path for relative name construction + return String.Format(CultureInfo.CurrentCulture, "{0}{1}", assembly, resource.Replace('/', '.')); + } + + private string GetSimpleName(string assembly) + { + int indexOfComma = assembly.IndexOf(','); + if(indexOfComma<0) + { + return assembly; + } + return assembly.Substring(0, indexOfComma); + } + + private string ConvertToPath(String resource) + { + string path = resource.Replace('.', '/'); + if (path[0] != '/') + { + path = string.Format(CultureInfo.CurrentCulture, "/{0}", path); + } + return path; + } + + private static Assembly ObtainAssembly(String assemblyName) + { + try + { + return Assembly.Load(assemblyName); + } + catch(Exception ex) + { + String message = String.Format(CultureInfo.InvariantCulture, "The assembly {0} could not be loaded", assemblyName); + throw new ResourceException(message, ex); + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AssemblyResourceFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\AssemblyResourceFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\AssemblyResourceFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\AssemblyResourceFactory.cs Sun Feb 13 20:33:34 2011 @@ -0,0 +1,41 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + + internal class AssemblyResourceFactory : IResourceFactory + { + public bool Accept(CustomUri uri) + { + return "assembly".Equals(uri.Scheme); + } + + public IResource Create(CustomUri uri) + { + return Create(uri, null); + } + + public IResource Create(CustomUri uri, String basePath) + { + if (basePath == null) + { + return new AssemblyResource(uri); + } + + return new AssemblyResource(uri, basePath); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\ConfigResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\ConfigResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\ConfigResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\ConfigResource.cs Sun Feb 13 20:33:39 2011 @@ -0,0 +1,79 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT + +namespace Castle.Core.Resource +{ + using System; + using System.Configuration; + using System.Globalization; + using System.IO; + using System.Text; + using System.Xml; + + + internal class ConfigResource : AbstractResource + { + private readonly XmlNode configSectionNode; + private readonly string sectionName; + + public ConfigResource() : this("castle") + { + } + + public ConfigResource(CustomUri uri) : this(uri.Host) + { + } + + public ConfigResource(String sectionName) + { + this.sectionName = sectionName; + + XmlNode node = (XmlNode) ConfigurationManager.GetSection(sectionName); + + if (node == null) + { + String message = String.Format(CultureInfo.InvariantCulture, + "Could not find section '{0}' in the configuration file associated with this domain.", sectionName); + throw new ConfigurationErrorsException(message); + } + + // TODO: Check whether it's CData section + configSectionNode = node; + } + + public override TextReader GetStreamReader() + { + return new StringReader(configSectionNode.OuterXml); + } + + public override TextReader GetStreamReader(Encoding encoding) + { + throw new NotSupportedException("Encoding is not supported"); + } + + public override IResource CreateRelative(String relativePath) + { + return new ConfigResource(relativePath); + } + + public override string ToString() + { + return String.Format(CultureInfo.CurrentCulture, "ConfigResource: [{0}]", sectionName); + } + } +} + +#endif diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\ConfigResourceFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\ConfigResourceFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\ConfigResourceFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\ConfigResourceFactory.cs Sun Feb 13 20:33:45 2011 @@ -0,0 +1,44 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + #if !SILVERLIGHT + + using System; + + internal class ConfigResourceFactory : IResourceFactory + { + public ConfigResourceFactory() + { + } + + public bool Accept(CustomUri uri) + { + return "config".Equals(uri.Scheme); + } + + public IResource Create(CustomUri uri) + { + return new ConfigResource(uri); + } + + public IResource Create(CustomUri uri, String basePath) + { + return Create(uri); + } + } + + #endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\CustomUri.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\CustomUri.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\CustomUri.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\CustomUri.cs Sun Feb 13 20:33:51 2011 @@ -0,0 +1,144 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.Text; + +#if !SILVERLIGHT + [Serializable] +#endif + internal sealed class CustomUri + { + public static readonly String SchemeDelimiter = "://"; + public static readonly String UriSchemeFile = "file"; + public static readonly String UriSchemeAssembly = "assembly"; + + private String scheme; + private String host; + private String path; + private bool isUnc; + private bool isFile; + private bool isAssembly; + + public CustomUri(String resourceIdentifier) + { + if (resourceIdentifier == null) + { + throw new ArgumentNullException("resourceIdentifier"); + } + if (resourceIdentifier == String.Empty) + { + throw new ArgumentException("Empty resource identifier is not allowed", "resourceIdentifier"); + } + + ParseIdentifier(resourceIdentifier); + } + + public bool IsUnc + { + get { return isUnc; } + } + + public bool IsFile + { + get { return isFile; } + } + + public bool IsAssembly + { + get { return isAssembly; } + } + + public string Scheme + { + get { return scheme; } + } + + public string Host + { + get { return host; } + } + + public String Path + { + get { return path; } + } + + private void ParseIdentifier(String identifier) + { + int comma = identifier.IndexOf(':'); + + if (comma == -1 && !(identifier[0] == '\\' && identifier[1] == '\\') && identifier[0] != '/') + { + throw new ArgumentException("Invalid Uri: no scheme delimiter found on " + identifier); + } + + bool translateSlashes = true; + + if (identifier[0] == '\\' && identifier[1] == '\\') + { + // Unc + + isUnc = true; + isFile = true; + scheme = UriSchemeFile; + translateSlashes = false; + } + else if (identifier[comma + 1] == '/' && identifier[comma + 2] == '/') + { + // Extract scheme + + scheme = identifier.Substring(0, comma); + + isFile = (scheme == UriSchemeFile); + isAssembly = (scheme == UriSchemeAssembly); + + identifier = identifier.Substring(comma + SchemeDelimiter.Length); + } + else + { + isFile = true; + scheme = UriSchemeFile; + } + + var sb = new StringBuilder(); + foreach(char ch in identifier.ToCharArray()) + { + if (translateSlashes && (ch == '\\' || ch == '/')) + { + if (host == null && !IsFile) + { + host = sb.ToString(); + sb.Length = 0; + } + + sb.Append('/'); + } + else + { + sb.Append(ch); + } + } + +#if !SILVERLIGHT + path = Environment.ExpandEnvironmentVariables(sb.ToString()); +#endif +#if SILVERLIGHT + path = sb.ToString(); +#endif + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\FileResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\FileResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\FileResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\FileResource.cs Sun Feb 13 20:33:58 2011 @@ -0,0 +1,119 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.Globalization; + using System.IO; + + /// + /// + /// + internal class FileResource : AbstractStreamResource + { + private string filePath; + private String basePath; + + public FileResource(CustomUri resource) + { + CreateStream = delegate + { + return CreateStreamFromUri(resource, DefaultBasePath); + }; + } + + public FileResource(CustomUri resource, String basePath) + { + CreateStream = delegate + { + return CreateStreamFromUri(resource, basePath); + }; + } + + public FileResource(String resourceName) + { + CreateStream = delegate + { + return CreateStreamFromPath(resourceName, DefaultBasePath); + }; + } + + public FileResource(String resourceName, String basePath) + { + CreateStream = delegate + { + return CreateStreamFromPath(resourceName, basePath); + }; + } + + public override string ToString() + { + return String.Format(CultureInfo.CurrentCulture, "FileResource: [{0}] [{1}]", filePath, basePath); + } + + public override String FileBasePath + { + get { return basePath; } + } + + public override IResource CreateRelative(String relativePath) + { + return new FileResource(relativePath, basePath); + } + + private Stream CreateStreamFromUri(CustomUri resource, String rootPath) + { + if (resource == null) throw new ArgumentNullException("resource"); + if (rootPath == null) throw new ArgumentNullException("rootPath"); + + if (!resource.IsFile) + throw new ArgumentException("The specified resource is not a file", "resource"); + + return CreateStreamFromPath(resource.Path, rootPath); + } + + private Stream CreateStreamFromPath(String resourcePath, String rootPath) + { + if (resourcePath == null) + throw new ArgumentNullException("resourcePath"); + if (rootPath == null) + throw new ArgumentNullException("rootPath"); + + if (!Path.IsPathRooted(resourcePath) || !File.Exists(resourcePath)) + { + // For a relative path, we use the basePath to + // resolve the full path + + resourcePath = Path.Combine(rootPath, resourcePath); + } + + CheckFileExists(resourcePath); + + this.filePath = Path.GetFileName(resourcePath); + this.basePath = Path.GetDirectoryName(resourcePath); + + return File.OpenRead(resourcePath); + } + + private static void CheckFileExists(String path) + { + if (!File.Exists(path)) + { + String message = String.Format(CultureInfo.InvariantCulture, "File {0} could not be found", new FileInfo(path).FullName); + throw new ResourceException(message); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\FileResourceFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\FileResourceFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\FileResourceFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\FileResourceFactory.cs Sun Feb 13 20:34:02 2011 @@ -0,0 +1,48 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT +namespace Castle.Core.Resource +{ + using System; + + /// + /// + /// + internal class FileResourceFactory : IResourceFactory + { + public FileResourceFactory() + { + } + + public bool Accept(CustomUri uri) + { + return "file".Equals(uri.Scheme); + } + + public IResource Create(CustomUri uri) + { + return Create(uri, null); + } + + public IResource Create(CustomUri uri, String basePath) + { + if (basePath != null) + return new FileResource(uri, basePath); + else + return new FileResource(uri); + } + } +} +#endif diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\IResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\IResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\IResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\IResource.cs Sun Feb 13 20:34:08 2011 @@ -0,0 +1,64 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.IO; + using System.Text; + + /// + /// Represents a 'streamable' resource. Can + /// be a file, a resource in an assembly. + /// + internal interface IResource : IDisposable + { + /// + /// + /// + /// + /// Only valid for resources that + /// can be obtained through relative paths + /// + String FileBasePath { get; } + + /// + /// Returns a reader for the stream + /// + /// + /// It's up to the caller to dispose the reader. + /// + /// + TextReader GetStreamReader(); + + /// + /// Returns a reader for the stream + /// + /// + /// It's up to the caller to dispose the reader. + /// + /// + /// + TextReader GetStreamReader(Encoding encoding); + + /// + /// Returns an instance of + /// created according to the relativePath + /// using itself as the root. + /// + /// + /// + IResource CreateRelative(String relativePath); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\IResourceFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\IResourceFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\IResourceFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\IResourceFactory.cs Sun Feb 13 20:34:19 2011 @@ -0,0 +1,55 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + + /// + /// Depicts the contract for resource factories. + /// + internal interface IResourceFactory + { + /// + /// Used to check whether the resource factory + /// is able to deal with the given resource + /// identifier. + /// + /// + /// Implementors should return true + /// only if the given identifier is supported + /// by the resource factory + /// + /// + /// + bool Accept(CustomUri uri); + + /// + /// Creates an instance + /// for the given resource identifier + /// + /// + /// + IResource Create(CustomUri uri); + + /// + /// Creates an instance + /// for the given resource identifier + /// + /// + /// + /// + IResource Create(CustomUri uri, String basePath); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\ResourceException.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\ResourceException.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\ResourceException.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\ResourceException.cs Sun Feb 13 20:34:26 2011 @@ -0,0 +1,42 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.Runtime.Serialization; + +#if !SILVERLIGHT + [Serializable] +#endif + internal class ResourceException : Exception + { + public ResourceException() + { + } + + public ResourceException(string message) : base(message) + { + } + + public ResourceException(string message, Exception innerException) : base(message, innerException) + { + } +#if !SILVERLIGHT + protected ResourceException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +#endif + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\StaticContentResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\StaticContentResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\StaticContentResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\StaticContentResource.cs Sun Feb 13 20:34:31 2011 @@ -0,0 +1,48 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.IO; + using System.Text; + + /// + /// Adapts a static string content as an + /// + internal class StaticContentResource : AbstractResource + { + private readonly string contents; + + public StaticContentResource(String contents) + { + this.contents = contents; + } + + public override TextReader GetStreamReader() + { + return new StringReader(contents); + } + + public override TextReader GetStreamReader(Encoding encoding) + { + throw new NotImplementedException(); + } + + public override IResource CreateRelative(String relativePath) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\UncResource.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\UncResource.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\UncResource.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\UncResource.cs Sun Feb 13 20:34:37 2011 @@ -0,0 +1,102 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + using System.Globalization; + using System.IO; + + /// + /// Enable access to files on network shares + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Unc")] + internal class UncResource : AbstractStreamResource + { + private String basePath; + private string filePath; + + public UncResource(CustomUri resource) + { + CreateStream = delegate + { + return CreateStreamFromUri(resource, DefaultBasePath); + }; + } + + public UncResource(CustomUri resource, String basePath) + { + CreateStream = delegate + { + return CreateStreamFromUri(resource, basePath); + }; + } + + public UncResource(String resourceName) : this(new CustomUri(resourceName)) + { + } + + public UncResource(String resourceName, String basePath) : this(new CustomUri(resourceName), basePath) + { + } + + public override String FileBasePath + { + get { return basePath; } + } + + public override IResource CreateRelative(String relativePath) + { + return new UncResource(Path.Combine(basePath, relativePath)); + } + + public override string ToString() + { + return String.Format(CultureInfo.CurrentCulture, "UncResource: [{0}] [{1}]", filePath, basePath); + } + + private Stream CreateStreamFromUri(CustomUri resource, String rootPath) + { + if (resource == null) + throw new ArgumentNullException("resource"); + if (!resource.IsUnc) + throw new ArgumentException("Resource must be an Unc", "resource"); + if (!resource.IsFile) + throw new ArgumentException("The specified resource is not a file", "resource"); + + String resourcePath = resource.Path; + + if (!File.Exists(resourcePath) && rootPath != null) + { + resourcePath = Path.Combine(rootPath, resourcePath); + } + + filePath = Path.GetFileName(resourcePath); + basePath = Path.GetDirectoryName(resourcePath); + + CheckFileExists(resourcePath); + + return File.OpenRead(resourcePath); + } + + private static void CheckFileExists(String path) + { + if (!File.Exists(path)) + { + String message = String.Format(CultureInfo.InvariantCulture, "File {0} could not be found", path); + throw new ResourceException(message); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Resource\UncResourceFactory.cs nmock3-62490\MAIN\Source\Castle\Core\Resource\UncResourceFactory.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Resource\UncResourceFactory.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Resource\UncResourceFactory.cs Sun Feb 13 20:34:42 2011 @@ -0,0 +1,40 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Resource +{ + using System; + + internal class UncResourceFactory : IResourceFactory + { + public UncResourceFactory() + { + } + + public bool Accept(CustomUri uri) + { + return uri.IsUnc; + } + + public IResource Create(CustomUri uri) + { + return new UncResource(uri); + } + + public IResource Create(CustomUri uri, String basePath) + { + return new UncResource(uri, basePath); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Smtp\DefaultSmtpSender.cs nmock3-62490\MAIN\Source\Castle\Core\Smtp\DefaultSmtpSender.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Smtp\DefaultSmtpSender.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Smtp\DefaultSmtpSender.cs Sun Feb 13 20:26:12 2011 @@ -0,0 +1,283 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Smtp +{ + #if !SILVERLIGHT + + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Net; + using System.Net.Mail; +#if DOTNET40 + using System.Security; +#endif + using System.Security.Permissions; + using Castle.Core.Internal; + + /// + /// Default implementation. + /// + internal class DefaultSmtpSender : IEmailSender + { + private bool asyncSend; + private readonly string hostname; + private int port = 25; + private int? timeout; + private bool useSsl; + private readonly NetworkCredential credentials = new NetworkCredential(); + + /// + /// Initializes a new instance of the class based on the configuration provided in the application configuration file. + /// + /// + /// This constructor is based on the default configuration in the application configuration file. + /// + public DefaultSmtpSender() { } + + /// + /// This service implementation + /// requires a host name in order to work + /// + /// The smtp server name + public DefaultSmtpSender(string hostname) + { + this.hostname = hostname; + } + + /// + /// Gets or sets the port used to + /// access the SMTP server + /// + public int Port + { + get { return port; } + set { port = value; } + } + + /// + /// Gets the hostname. + /// + /// The hostname. + public string Hostname + { + get { return hostname; } + } + + /// + /// Gets or sets a value which is used to + /// configure if emails are going to be sent asyncrhonously or not. + /// + public bool AsyncSend + { + get { return asyncSend; } + set { asyncSend = value; } + } + + /// + /// Gets or sets a value that specifies + /// the amount of time after which a synchronous Send call times out. + /// + public int Timeout + { + get { return timeout.HasValue ? timeout.Value : 0; } + set { timeout = value; } + } + + /// + /// Gets or sets a value indicating whether the email should be sent using + /// a secure communication channel. + /// + /// true if should use SSL; otherwise, false. + public bool UseSsl + { + get { return useSsl; } + set { useSsl = value; } + } + + /// + /// Sends a message. + /// + /// If any of the parameters is null + /// From field + /// To field + /// e-mail's subject + /// message's body +#if DOTNET40 + [SecuritySafeCritical] +#endif + public void Send(String from, String to, String subject, String messageText) + { + if (from == null) throw new ArgumentNullException("from"); + if (to == null) throw new ArgumentNullException("to"); + if (subject == null) throw new ArgumentNullException("subject"); + if (messageText == null) throw new ArgumentNullException("messageText"); + + Send(new MailMessage(from, to, subject, messageText)); + } + + /// + /// Sends a message. + /// + /// If the message is null + /// Message instance +#if DOTNET40 + [SecuritySafeCritical] +#endif + public void Send(MailMessage message) + { + InternalSend(message); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private void InternalSend(MailMessage message) + { + if (message == null) throw new ArgumentNullException("message"); + + if (asyncSend) + { + // The MailMessage must be diposed after sending the email. + // The code creates a delegate for deleting the mail and adds + // it to the smtpClient. + // After the mail is sent, the message is disposed and the + // eventHandler removed from the smtpClient. + SmtpClient smtpClient; + + if (string.IsNullOrEmpty(hostname)) + { + // No hostname configured, use the settings provided in system.net.smtp (SmtpClient default behavior) + smtpClient = new SmtpClient(); + } + else + { + // A hostname is provided - init and configure using configured settings + smtpClient = new SmtpClient(hostname, port); + Configure(smtpClient); + } + + Guid msgGuid = new Guid(); + SendCompletedEventHandler sceh = null; + sceh = delegate(object sender, AsyncCompletedEventArgs e) + { + if (msgGuid == (Guid)e.UserState) + message.Dispose(); + // The handler itself, cannot be null, test omitted + smtpClient.SendCompleted -= sceh; + }; + smtpClient.SendCompleted += sceh; + smtpClient.SendAsync(message, msgGuid); + } + else + { + using (message) + { + SmtpClient smtpClient = new SmtpClient(hostname, port); + Configure(smtpClient); + + smtpClient.Send(message); + } + } + } + +#if DOTNET40 + [SecuritySafeCritical] +#endif + public void Send(IEnumerable messages) + { + foreach (MailMessage message in messages) + { + Send(message); + } + } + + /// + /// Gets or sets the domain. + /// + /// The domain. + public String Domain + { + get { return credentials.Domain; } + set { credentials.Domain = value; } + } + + /// + /// Gets or sets the name of the user. + /// + /// The name of the user. + public String UserName + { + get { return credentials.UserName; } + set { credentials.UserName = value; } + } + + /// + /// Gets or sets the password. + /// + /// The password. + public String Password + { + get { return credentials.Password; } + set { credentials.Password = value; } + } + + /// + /// Configures the sender + /// with port information and eventual credential + /// informed + /// + /// Message instance +#if DOTNET40 + [SecurityCritical] +#endif + protected virtual void Configure(SmtpClient smtpClient) + { + smtpClient.Credentials = null; + + if (CanAccessCredentials() && HasCredentials) + { + smtpClient.Credentials = credentials; + } + + if (timeout.HasValue) + { + smtpClient.Timeout = timeout.Value; + } + + if (useSsl) + { + smtpClient.EnableSsl = useSsl; + } + } + + /// + /// Gets a value indicating whether credentials were informed. + /// + /// + /// if this instance has credentials; otherwise, . + /// + private bool HasCredentials + { + get { return !string.IsNullOrEmpty(credentials.UserName); } + } + + private static bool CanAccessCredentials() + { + return new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).IsGranted(); + } + } + #endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\Smtp\IEmailSender.cs nmock3-62490\MAIN\Source\Castle\Core\Smtp\IEmailSender.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\Smtp\IEmailSender.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\Smtp\IEmailSender.cs Sun Feb 13 20:26:17 2011 @@ -0,0 +1,49 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core.Smtp +{ + #if !SILVERLIGHT + + using System.Collections.Generic; + using System.Net.Mail; + + /// + /// Email sender abstraction. + /// + internal interface IEmailSender + { + /// + /// Sends a mail message. + /// + /// From field + /// To field + /// E-mail's subject + /// message's body + void Send(string from, string to, string subject, string messageText); + + /// + /// Sends a message. + /// + /// Message instance + void Send(MailMessage message); + + /// + /// Sends multiple messages. + /// + /// List of messages + void Send(IEnumerable messages); + } + #endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Core\StringObjectDictionaryAdapter.cs nmock3-62490\MAIN\Source\Castle\Core\StringObjectDictionaryAdapter.cs --- nmock3-62490-original\MAIN\Source\Castle\Core\StringObjectDictionaryAdapter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Core\StringObjectDictionaryAdapter.cs Sun Feb 13 20:25:21 2011 @@ -0,0 +1,227 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Core +{ + using System; + using System.Collections; + using System.Collections.Generic; + + internal sealed class StringObjectDictionaryAdapter : IDictionary + { + private readonly IDictionary dictionary; + + public StringObjectDictionaryAdapter(IDictionary dictionary) + { + this.dictionary = dictionary; + } + + bool IDictionary.ContainsKey(string key) + { + return dictionary.Contains(key); + } + + void IDictionary.Add(string key, object value) + { + throw new NotImplementedException(); + } + + bool IDictionary.Remove(string key) + { + throw new NotImplementedException(); + } + + bool IDictionary.TryGetValue(string key, out object value) + { + value = null; + if (dictionary.Contains(key)) + { + value = dictionary[key]; + return true; + } + else + { + return false; + } + } + + object IDictionary.this[string key] + { + get { return dictionary[key]; } + set { throw new NotImplementedException(); } + } + + ICollection IDictionary.Keys + { + get + { + string[] keys = new string[Count]; + dictionary.Keys.CopyTo(keys, 0); + return keys; + } + } + + ICollection IDictionary.Values + { + get + { + object[] values = new object[Count]; + dictionary.Values.CopyTo(values, 0); + return values; + } + } + + void ICollection>.Add(KeyValuePair item) + { + throw new NotImplementedException(); + } + + bool ICollection>.Contains(KeyValuePair item) + { + throw new NotImplementedException(); + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + bool ICollection>.Remove(KeyValuePair item) + { + throw new NotImplementedException(); + } + + IEnumerator> IEnumerable>.GetEnumerator() + { + return new EnumeratorAdapter(this); + } + + public bool Contains(object key) + { + return dictionary.Contains(key); + } + + public void Add(object key, object value) + { + dictionary.Add(key, value); + } + + public void Clear() + { + dictionary.Clear(); + } + + public void Remove(object key) + { + dictionary.Remove(key); + } + + public object this[object key] + { + get { return dictionary[key]; } + set { dictionary[key] = value; } + } + + public ICollection Keys + { + get { return dictionary.Keys; } + } + + public ICollection Values + { + get { return dictionary.Values; } + } + + public bool IsReadOnly + { + get { return dictionary.IsReadOnly; } + } + + public bool IsFixedSize + { + get { return dictionary.IsFixedSize; } + } + + public void CopyTo(Array array, int index) + { + dictionary.CopyTo(array, index); + } + + public int Count + { + get { return dictionary.Count; } + } + + public object SyncRoot + { + get { return dictionary.SyncRoot; } + } + + public bool IsSynchronized + { + get { return dictionary.IsSynchronized; } + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable) dictionary).GetEnumerator(); + } + + internal class EnumeratorAdapter : IEnumerator> + { + private readonly StringObjectDictionaryAdapter adapter; + private IEnumerator keyEnumerator; + private string currentKey; + private object currentValue; + + public EnumeratorAdapter(StringObjectDictionaryAdapter adapter) + { + this.adapter = adapter; + keyEnumerator = ((IDictionary) adapter).Keys.GetEnumerator(); + } + + public bool MoveNext() + { + if (keyEnumerator.MoveNext()) + { + currentKey = keyEnumerator.Current; + currentValue = adapter[currentKey]; + return true; + } + + return false; + } + + public void Reset() + { + keyEnumerator.Reset(); + } + + public object Current + { + get { return new KeyValuePair(currentKey, currentValue); } + } + + KeyValuePair IEnumerator>.Current + { + get { return new KeyValuePair(currentKey, currentValue); } + } + + public void Dispose() + { + GC.SuppressFinalize(this); + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\AbstractInvocation.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\AbstractInvocation.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\AbstractInvocation.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\AbstractInvocation.cs Mon Feb 14 13:25:03 2011 @@ -0,0 +1,229 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +namespace Castle.DynamicProxy +{ + using System; + using System.Diagnostics; + using System.Reflection; + using System.Runtime.Serialization; +#if DOTNET40 + using System.Security; +#endif + +#if SILVERLIGHT + public abstract class AbstractInvocation : IInvocation +#else + [Serializable] + // [ILMergeExclude] + internal abstract class AbstractInvocation : IInvocation, ISerializable +#endif + { + private readonly IInterceptor[] interceptors; + private readonly object[] arguments; + private int execIndex = -1; + private Type[] genericMethodArguments; + private readonly MethodInfo proxiedMethod; + protected readonly object proxyObject; + + protected AbstractInvocation( + object proxy, + IInterceptor[] interceptors, + MethodInfo proxiedMethod, + object[] arguments) + { + Debug.Assert(proxiedMethod != null); + proxyObject = proxy; + this.interceptors = interceptors; + this.proxiedMethod = proxiedMethod; + this.arguments = arguments; + } + + protected AbstractInvocation( + object proxy, + Type targetType, + IInterceptor[] interceptors, + MethodInfo proxiedMethod, + object[] arguments, + IInterceptorSelector selector, + ref IInterceptor[] methodInterceptors) + : this(proxy, interceptors, proxiedMethod, arguments) + { + methodInterceptors = SelectMethodInterceptors(selector, methodInterceptors, targetType); + this.interceptors = methodInterceptors; + } + + private IInterceptor[] SelectMethodInterceptors(IInterceptorSelector selector, + IInterceptor[] methodInterceptors, + Type targetType) + { + return methodInterceptors ?? + selector.SelectInterceptors(targetType, Method, interceptors) ?? + new IInterceptor[0]; + } + + public void SetGenericMethodArguments(Type[] arguments) + { + genericMethodArguments = arguments; + } + + public abstract object InvocationTarget { get; } + + public abstract Type TargetType { get; } + + public abstract MethodInfo MethodInvocationTarget { get; } + + public Type[] GenericArguments + { + get { return genericMethodArguments; } + } + + public object Proxy + { + get { return proxyObject; } + } + + public MethodInfo Method + { + get { return proxiedMethod; } + } + + public MethodInfo GetConcreteMethod() + { + return EnsureClosedMethod(Method); + } + + public MethodInfo GetConcreteMethodInvocationTarget() + { + // it is ensured by the InvocationHelper that method will be closed + var method = MethodInvocationTarget; + Debug.Assert(method == null || method.IsGenericMethodDefinition == false, + "method == null || method.IsGenericMethodDefinition == false"); + return method; + } + + public object ReturnValue { get; set; } + + public object[] Arguments + { + get { return arguments; } + } + + public void SetArgumentValue(int index, object value) + { + arguments[index] = value; + } + + public object GetArgumentValue(int index) + { + return arguments[index]; + } + + public void Proceed() + { + if (interceptors == null) + // not yet fully initialized? probably, an intercepted method is called while we are being deserialized + { + InvokeMethodOnTarget(); + return; + } + + execIndex++; + + if (execIndex == interceptors.Length) + { + InvokeMethodOnTarget(); + } + else if (execIndex > interceptors.Length) + { + string interceptorsCount; + if (interceptors.Length > 1) + { + interceptorsCount = " each one of " + interceptors.Length + " interceptors"; + } + else + { + interceptorsCount = " interceptor"; + } + + var message = "This is a DynamicProxy2 error: invocation.Proceed() has been called more times than expected." + + "This usually signifies a bug in the calling code. Make sure that" + interceptorsCount + + " selected for the method '" + Method + "'" + + "calls invocation.Proceed() at most once."; + throw new InvalidOperationException(message); + } + else + { + interceptors[execIndex].Intercept(this); + } + } + +#if !SILVERLIGHT +#if DOTNET40 + [SecurityCritical] +#endif + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof(RemotableInvocation)); + info.AddValue("invocation", new RemotableInvocation(this)); + } +#endif + + protected abstract void InvokeMethodOnTarget(); + + protected void ThrowOnNoTarget() + { + // let's try to build as friendly message as we can + string interceptorsMessage; + if (interceptors.Length == 0) + { + interceptorsMessage = "There are no interceptors specified"; + } + else + { + interceptorsMessage = "The interceptor attempted to 'Proceed'"; + } + + string methodKindIs; + string methodKindDescription; + if (Method.DeclaringType.IsClass && Method.IsAbstract) + { + methodKindIs = "is abstract"; + methodKindDescription = "an abstract method"; + } + else + { + methodKindIs = "has no target"; + methodKindDescription = "method without target"; + } + + string message = string.Format("This is a DynamicProxy2 error: {0} for method '{1}' which {2}. " + + "When calling {3} there is no implementation to 'proceed' to and " + + "it is the responsibility of the interceptor to mimic the implementation " + + "(set return value, out arguments etc)", + interceptorsMessage, Method, methodKindIs, methodKindDescription); + + throw new NotImplementedException(message); + } + + private MethodInfo EnsureClosedMethod(MethodInfo method) + { + if (method.ContainsGenericParameters) + { + Debug.Assert(genericMethodArguments != null); + return method.GetGenericMethodDefinition().MakeGenericMethod(genericMethodArguments); + } + return method; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\AllMethodsHook.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\AllMethodsHook.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\AllMethodsHook.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\AllMethodsHook.cs Sun Feb 13 21:04:27 2011 @@ -0,0 +1,63 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + using System.Reflection; + +#if !SILVERLIGHT + [Serializable] +#endif + internal class AllMethodsHook : IProxyGenerationHook + { + protected static readonly ICollection SkippedTypes = new[] + { + typeof (object), +#if !SILVERLIGHT + typeof (MarshalByRefObject), + typeof (ContextBoundObject) +#endif + }; + + public virtual bool ShouldInterceptMethod(Type type, MethodInfo methodInfo) + { + return SkippedTypes.Contains(methodInfo.DeclaringType) == false && IsFinalizer(methodInfo) == false; + } + + protected bool IsFinalizer(MethodInfo methodInfo) + { + return methodInfo.Name == "Finalize" && methodInfo.GetBaseDefinition().DeclaringType == typeof(object); + } + + public virtual void NonProxyableMemberNotification(Type type, MemberInfo memberInfo) + { + } + + public virtual void MethodsInspected() + { + } + + public override bool Equals(object obj) + { + return obj != null && obj.GetType() == GetType(); + } + + public override int GetHashCode() + { + return GetType().GetHashCode(); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\AttributeUtil.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\AttributeUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\AttributeUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\AttributeUtil.cs Sun Feb 13 21:03:34 2011 @@ -0,0 +1,274 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + + using Castle.DynamicProxy.Generators; + + internal static class AttributeUtil + { + private static readonly IDictionary disassemblers = new Dictionary(); + private static IAttributeDisassembler fallbackDisassembler = new AttributeDisassembler(); + + public static IAttributeDisassembler FallbackDisassembler + { + get { return fallbackDisassembler; } + set { fallbackDisassembler = value; } + } + + /// + /// Registers custom disassembler to handle disassembly of specified type of attributes. + /// + /// Type of attributes to handle + /// Disassembler converting existing instances of Attributes to CustomAttributeBuilders + /// + /// When disassembling an attribute Dynamic Proxy will first check if an custom disassembler has been registered to handle attributes of that type, + /// and if none is found, it'll use the . + /// + public static void AddDisassembler(IAttributeDisassembler disassembler) where TAttribute : Attribute + { + if (disassembler == null) throw new ArgumentNullException("disassembler"); + + disassemblers[typeof (TAttribute)] = disassembler; + } + +#if !SILVERLIGHT + public static CustomAttributeBuilder CreateBuilder(CustomAttributeData attribute) + { + Debug.Assert(attribute != null, "attribute != null"); + + PropertyInfo[] properties; + object[] propertyValues; + FieldInfo[] fields; + object[] fieldValues; + GetSettersAndFields(attribute.NamedArguments, out properties, out propertyValues, out fields, out fieldValues); + + return new CustomAttributeBuilder(attribute.Constructor, + GetCtorArguments(attribute.ConstructorArguments), + properties, + propertyValues, + fields, + fieldValues); + + } + + private static object[] GetCtorArguments(IList constructorArguments) + { + var arguments = new object[constructorArguments.Count]; + for (int i = 0; i < constructorArguments.Count; i++) + { + arguments[i] = constructorArguments[i].Value; + } + + return arguments; + } + + + private static void GetSettersAndFields(IEnumerable namedArguments, + out PropertyInfo[] properties, out object[] propertyValues, + out FieldInfo[] fields, out object[] fieldValues) + { + var propertyList = new List(); + var propertyValuesList = new List(); + var fieldList = new List(); + var fieldValuesList = new List(); + foreach (var argument in namedArguments) + { + switch (argument.MemberInfo.MemberType) + { + case MemberTypes.Property: + propertyList.Add(argument.MemberInfo as PropertyInfo); + propertyValuesList.Add(argument.TypedValue.Value); + break; + case MemberTypes.Field: + fieldList.Add(argument.MemberInfo as FieldInfo); + fieldValuesList.Add(argument.TypedValue.Value); + break; + default: + // NOTE: can this ever happen? + throw new ArgumentException(string.Format("Unexpected member type {0} in custom attribute.", + argument.MemberInfo.MemberType)); + } + } + + properties = propertyList.ToArray(); + propertyValues = propertyValuesList.ToArray(); + fields = fieldList.ToArray(); + fieldValues = fieldValuesList.ToArray(); + } +#else +// CustomAttributeData is internal in Silverlight +#endif + + public static IEnumerable GetNonInheritableAttributes(this MemberInfo member) + { + Debug.Assert(member != null, "member != null"); + var attributes = +#if SILVERLIGHT + member.GetCustomAttributes(false); +#else + CustomAttributeData.GetCustomAttributes(member); +#endif + + foreach (var attribute in attributes) + { + var attributeType = +#if SILVERLIGHT + attribute.GetType(); +#else + attribute.Constructor.DeclaringType; +#endif + if (ShouldSkipAttributeReplication(attributeType)) continue; + + CustomAttributeBuilder builder; + try + { + builder = CreateBuilder(attribute +#if SILVERLIGHT + as Attribute +#endif + ); + } + catch (ArgumentException e) + { + string message = + string.Format( + "Due to limitations in CLR, DynamicProxy was unable to successfully replicate non-inheritable attribute {0} on {1}{2}. To avoid this error you can chose not to replicate this attribute type by calling '{3}.Add(typeof({0}))'.", + attributeType.FullName, (member.ReflectedType == null) ? "" : member.ReflectedType.FullName, (member is Type) ? "" : ("." + member.Name), typeof(AttributesToAvoidReplicating).FullName); + throw new ProxyGenerationException(message, e); + + } + if (builder != null) + { + yield return builder; + } + } + } + + public static IEnumerable GetNonInheritableAttributes(this ParameterInfo parameter) + { + Debug.Assert(parameter != null, "parameter != null"); + var attributes = +#if SILVERLIGHT + parameter.GetCustomAttributes(false); +#else + CustomAttributeData.GetCustomAttributes(parameter); +#endif + + foreach (var attribute in attributes) + { + var attributeType = +#if SILVERLIGHT + attribute.GetType(); +#else + attribute.Constructor.DeclaringType; +#endif + if (ShouldSkipAttributeReplication(attributeType)) continue; + + var builder = CreateBuilder(attribute +#if SILVERLIGHT + as Attribute +#endif +); + if (builder != null) + { + yield return builder; + } + } + } + + /// + /// Attributes should be replicated if they are non-inheritable, + /// but there are some special cases where the attributes means + /// something to the CLR, where they should be skipped. + /// + private static bool ShouldSkipAttributeReplication(Type attribute) + { + if(attribute.IsPublic == false) + { + return true; + } + + if (SpecialCaseAttributThatShouldNotBeReplicated(attribute)) + return true; + + object[] attrs = attribute.GetCustomAttributes(typeof(AttributeUsageAttribute), true); + + if (attrs.Length != 0) + { + var usage = (AttributeUsageAttribute)attrs[0]; + + return usage.Inherited; + } + + return true; + } + + private static bool SpecialCaseAttributThatShouldNotBeReplicated(Type attribute) + { + return AttributesToAvoidReplicating.Contains(attribute); + } + + public static CustomAttributeBuilder CreateBuilder() where TAttribute : Attribute, new() + { + ConstructorInfo constructor = typeof (TAttribute).GetConstructor(Type.EmptyTypes); + Debug.Assert(constructor != null, "constructor != null"); + + return new CustomAttributeBuilder(constructor, new object[0]); + } + + public static CustomAttributeBuilder CreateBuilder(Type attribute, object[] constructorArguments) + { + Debug.Assert(attribute != null, "attribute != null"); + Debug.Assert(typeof (Attribute).IsAssignableFrom(attribute), "typeof(Attribute).IsAssignableFrom(attribute)"); + Debug.Assert(constructorArguments != null, "constructorArguments != null"); + + ConstructorInfo constructor = attribute.GetConstructor(GetTypes(constructorArguments)); + Debug.Assert(constructor != null, "constructor != null"); + + return new CustomAttributeBuilder(constructor, constructorArguments); + } + + // NOTE: Use other overloads if possible. This method is here to support Silverlight and legacy scenarios. + internal static CustomAttributeBuilder CreateBuilder(Attribute attribute) + { + var type = attribute.GetType(); + + IAttributeDisassembler disassembler; + if(disassemblers.TryGetValue(type,out disassembler)) + { + return disassembler.Disassemble(attribute); + } + return FallbackDisassembler.Disassemble(attribute); + } + + private static Type[] GetTypes(object[] objects) + { + var types = new Type[objects.Length]; + for (int i = 0; i < types.Length; i++) + { + types[i] = objects[i].GetType(); + } + return types; + } + + } + +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\CacheMappingsAttribute.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\CacheMappingsAttribute.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\CacheMappingsAttribute.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\CacheMappingsAttribute.cs Sun Feb 13 20:09:21 2011 @@ -0,0 +1,70 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Reflection; + using System.Reflection.Emit; + using System.Runtime.Serialization.Formatters.Binary; + using Castle.DynamicProxy.Generators; + + /// + /// Applied to the assemblies saved by in order to persist the cache data included in the persisted assembly. + /// + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] + [CLSCompliant(false)] + internal class CacheMappingsAttribute : Attribute + { + private static readonly ConstructorInfo constructor = + typeof (CacheMappingsAttribute).GetConstructor(new Type[] {typeof (byte[])}); + + public static void ApplyTo(AssemblyBuilder assemblyBuilder, Dictionary mappings) + { + using (MemoryStream stream = new MemoryStream()) + { + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(stream, mappings); + byte[] bytes = stream.ToArray(); + CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(constructor, new object[] {bytes}); + assemblyBuilder.SetCustomAttribute(attributeBuilder); + } + } + + private readonly byte[] _serializedCacheMappings; + + public CacheMappingsAttribute(byte[] serializedCacheMappings) + { + _serializedCacheMappings = serializedCacheMappings; + } + + public byte[] SerializedCacheMappings + { + get { return _serializedCacheMappings; } + } + + public Dictionary GetDeserializedMappings() + { + using (MemoryStream stream = new MemoryStream(SerializedCacheMappings)) + { + BinaryFormatter formatter = new BinaryFormatter(); + return (Dictionary) formatter.Deserialize(stream); + } + } + } +} +#endif diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\CompositionInvocation.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\CompositionInvocation.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\CompositionInvocation.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\CompositionInvocation.cs Mon Feb 14 13:24:57 2011 @@ -0,0 +1,113 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Reflection; + + // [ILMergeExclude] + internal abstract class CompositionInvocation : AbstractInvocation + { + protected object target; + + protected CompositionInvocation( + object target, + object proxy, + IInterceptor[] interceptors, + MethodInfo proxiedMethod, + object[] arguments) + : base(proxy, interceptors, proxiedMethod, arguments) + { + this.target = target; + } + + protected CompositionInvocation( + object target, + object proxy, + IInterceptor[] interceptors, + MethodInfo proxiedMethod, + object[] arguments, + IInterceptorSelector selector, + ref IInterceptor[] methodInterceptors) + : base(proxy, GetTargetType(target), interceptors, proxiedMethod, arguments, selector, ref methodInterceptors) + { + this.target = target; + } + + private static Type GetTargetType(object targetObject) + { + if (targetObject == null) + { + return null; + } + + return targetObject.GetType(); + } + + protected void EnsureValidTarget() + { + if (target == null) + { + ThrowOnNoTarget(); + } + + if (!ReferenceEquals(target, proxyObject)) + { + return; + } + + string message = "This is a DynamicProxy2 error: target of invocation has been set to the proxy itself. " + + "This may result in recursively calling the method over and over again until stack overflow, which may destabilize your program." + + "This usually signifies a bug in the calling code. Make sure no interceptor sets proxy as its invocation target."; + throw new InvalidOperationException(message); + } + + protected void EnsureValidProxyTarget(object newTarget) + { + if (newTarget == null) + { + throw new ArgumentNullException("newTarget"); + } + + if (!ReferenceEquals(newTarget, proxyObject)) + { + return; + } + + var message = "This is a DynamicProxy2 error: target of proxy has been set to the proxy itself. " + + "This would result in recursively calling proxy methods over and over again until stack overflow, which may destabilize your program." + + "This usually signifies a bug in the calling code. Make sure no interceptor sets proxy as its own target."; + throw new InvalidOperationException(message); + } + + public override object InvocationTarget + { + get { return target; } + } + + public override Type TargetType + { + get + { + return GetTargetType(target); + } + } + + public override MethodInfo MethodInvocationTarget + { + get { return InvocationHelper.GetMethodOnObject(target, Method); } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassMembersCollector.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassMembersCollector.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassMembersCollector.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassMembersCollector.cs Sun Feb 13 20:14:01 2011 @@ -0,0 +1,46 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Reflection; + + using Generators; + + internal class ClassMembersCollector : MembersCollector + { + public ClassMembersCollector(Type targetType) + : base(targetType) + { + } + + protected override MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone) + { + if (!IsAccessible(method)) + { + return null; + } + + var accepted = AcceptMethod(method, true, hook); + if (!accepted && !method.IsAbstract) + { + //we don't need to do anything... + return null; + } + + return new MetaMethod(method, method, isStandalone, accepted, !method.IsAbstract); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyInstanceContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyInstanceContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyInstanceContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyInstanceContributor.cs Sun Feb 13 20:09:58 2011 @@ -0,0 +1,238 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + using System.Runtime.Serialization; + + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.CodeBuilders; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class ClassProxyInstanceContributor : ProxyInstanceContributor + { +#if !SILVERLIGHT + private readonly bool delegateToBaseGetObjectData; + private readonly bool implementISerializable; + private ConstructorInfo serializationConstructor; + private readonly IList serializedFields = new List(); +#endif + + public ClassProxyInstanceContributor(Type targetType, IList methodsToSkip, Type[] interfaces, string typeId) + : base(targetType, interfaces, typeId) + { +#if !SILVERLIGHT + if (targetType.IsSerializable) + { + implementISerializable = true; + delegateToBaseGetObjectData = VerifyIfBaseImplementsGetObjectData(targetType, methodsToSkip); + } +#endif + } + + protected override Expression GetTargetReferenceExpression(ClassEmitter emitter) + { + return SelfReference.Self.ToExpression(); + } + + public override void Generate(ClassEmitter @class, ProxyGenerationOptions options) + { + var interceptors = @class.GetField("__interceptors"); +#if !SILVERLIGHT + if (implementISerializable) + { + ImplementGetObjectData(@class); + Constructor(@class); + } +#endif + ImplementProxyTargetAccessor(@class, interceptors); + foreach (var attribute in targetType.GetNonInheritableAttributes()) + { + @class.DefineCustomAttribute(attribute); + } + } + +#if !SILVERLIGHT + + protected override void AddAddValueInvocation(ArgumentReference serializationInfo, MethodEmitter getObjectData, + FieldReference field) + { + serializedFields.Add(field); + base.AddAddValueInvocation(serializationInfo, getObjectData, field); + } + + protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo, + ArgumentReference streamingContext, ClassEmitter emitter) + { + codebuilder.AddStatement(new ExpressionStatement( + new MethodInvocationExpression( + serializationInfo, + SerializationInfoMethods.AddValue_Bool, + new ConstReference("__delegateToBase").ToExpression(), + new ConstReference(delegateToBaseGetObjectData). + ToExpression()))); + + if (delegateToBaseGetObjectData == false) + { + EmitCustomGetObjectData(codebuilder, serializationInfo); + return; + } + + EmitCallToBaseGetObjectData(codebuilder, serializationInfo, streamingContext); + } + + private void EmitCustomGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo) + { + var members = codebuilder.DeclareLocal(typeof(MemberInfo[])); + var data = codebuilder.DeclareLocal(typeof(object[])); + + var getSerializableMembers = new MethodInvocationExpression( + null, + FormatterServicesMethods.GetSerializableMembers, + new TypeTokenExpression(targetType)); + codebuilder.AddStatement(new AssignStatement(members, getSerializableMembers)); + + // Sort to keep order on both serialize and deserialize side the same, c.f DYNPROXY-ISSUE-127 + var callSort = new MethodInvocationExpression( + null, + TypeUtilMethods.Sort, + members.ToExpression()); + codebuilder.AddStatement(new AssignStatement(members, callSort)); + + var getObjectData = new MethodInvocationExpression( + null, + FormatterServicesMethods.GetObjectData, + SelfReference.Self.ToExpression(), + members.ToExpression()); + codebuilder.AddStatement(new AssignStatement(data, getObjectData)); + + var addValue = new MethodInvocationExpression( + serializationInfo, + SerializationInfoMethods.AddValue_Object, + new ConstReference("__data").ToExpression(), + data.ToExpression()); + codebuilder.AddStatement(new ExpressionStatement(addValue)); + } + + private void EmitCallToBaseGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo, + ArgumentReference streamingContext) + { + MethodInfo baseGetObjectData = targetType.GetMethod("GetObjectData", + new[] { typeof(SerializationInfo), typeof(StreamingContext) }); + + codebuilder.AddStatement(new ExpressionStatement( + new MethodInvocationExpression(baseGetObjectData, + serializationInfo.ToExpression(), + streamingContext.ToExpression()))); + } + + private void Constructor(ClassEmitter emitter) + { + if (!delegateToBaseGetObjectData) + { + return; + } + GenerateSerializationConstructor(emitter); + } + + private void GenerateSerializationConstructor(ClassEmitter emitter) + { + var serializationInfo = new ArgumentReference(typeof(SerializationInfo)); + var streamingContext = new ArgumentReference(typeof(StreamingContext)); + + var ctor = emitter.CreateConstructor(serializationInfo, streamingContext); + + ctor.CodeBuilder.AddStatement( + new ConstructorInvocationStatement(serializationConstructor, + serializationInfo.ToExpression(), + streamingContext.ToExpression())); + + foreach (var field in serializedFields) + { + var getValue = new MethodInvocationExpression(serializationInfo, + SerializationInfoMethods.GetValue, + new ConstReference(field.Reference.Name).ToExpression(), + new TypeTokenExpression(field.Reference.FieldType)); + ctor.CodeBuilder.AddStatement(new AssignStatement( + field, + new ConvertExpression(field.Reference.FieldType, + typeof(object), + getValue))); + } + ctor.CodeBuilder.AddStatement(new ReturnStatement()); + } + + private bool VerifyIfBaseImplementsGetObjectData(Type baseType, IList methodsToSkip) + { + if (!typeof(ISerializable).IsAssignableFrom(baseType)) + { + return false; + } + + if(IsDelegate(baseType)) + { + //working around bug in CLR which returns true for "does this type implement ISerializable" for delegates + return false; + } + + + // If base type implements ISerializable, we have to make sure + // the GetObjectData is marked as virtual + var getObjectDataMethod = baseType.GetInterfaceMap(typeof(ISerializable)).TargetMethods[0]; + if (getObjectDataMethod.IsPrivate) //explicit interface implementation + { + return false; + } + + if (!getObjectDataMethod.IsVirtual || getObjectDataMethod.IsFinal) + { + var message = String.Format("The type {0} implements ISerializable, but GetObjectData is not marked as virtual. " + + "Dynamic Proxy needs types implementing ISerializable to mark GetObjectData as virtual " + + "to ensure correct serialization process.", + baseType.FullName); + throw new ArgumentException(message); + } + + methodsToSkip.Add(getObjectDataMethod); + + serializationConstructor = baseType.GetConstructor( + BindingFlags.Instance | BindingFlags.Public | + BindingFlags.NonPublic, + null, + new[] { typeof(SerializationInfo), typeof(StreamingContext) }, + null); + + if (serializationConstructor == null) + { + String message = String.Format("The type {0} implements ISerializable, " + + "but failed to provide a deserialization constructor", + baseType.FullName); + throw new ArgumentException(message); + } + + return true; + } + + private bool IsDelegate(Type baseType) + { + return baseType.BaseType==typeof(MulticastDelegate); + } +#endif + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyTargetContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyTargetContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyTargetContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyTargetContributor.cs Sun Feb 13 20:11:08 2011 @@ -0,0 +1,198 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Reflection; + using System.Reflection.Emit; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class ClassProxyTargetContributor : CompositeTypeContributor + { + private readonly IList methodsToSkip; + private readonly Type targetType; + + public ClassProxyTargetContributor(Type targetType, IList methodsToSkip, INamingScope namingScope) + : base(namingScope) + { + this.targetType = targetType; + this.methodsToSkip = methodsToSkip; + } + + protected override IEnumerable CollectElementsToProxyInternal(IProxyGenerationHook hook) + { + Debug.Assert(hook != null, "hook != null"); + + var targetItem = new ClassMembersCollector(targetType) { Logger = Logger }; + targetItem.CollectMembersToProxy(hook); + yield return targetItem; + + foreach (var @interface in interfaces) + { + var item = new InterfaceMembersOnClassCollector(@interface, + true, + targetType.GetInterfaceMap(@interface)) { Logger = Logger }; + item.CollectMembersToProxy(hook); + yield return item; + } + } + + protected override MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, + ProxyGenerationOptions options, + OverrideMethodDelegate overrideMethod) + { + if (methodsToSkip.Contains(method.Method)) + return null; + + if (!method.Proxyable) + { + return new MinimialisticMethodGenerator(method, + overrideMethod); + } + + if (ExplicitlyImplementedInterfaceMethod(method)) + { +#if SILVERLIGHT + return null; +#else + return ExplicitlyImplementedInterfaceMethodGenerator(method, @class, options, overrideMethod); +#endif + } + + var invocation = GetInvocationType(method, @class, options); + + return new MethodWithInvocationGenerator(method, + @class.GetField("__interceptors"), + invocation, + (c, m) => new TypeTokenExpression(targetType), + overrideMethod, + null); + } + + private Type BuildInvocationType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options) + { + var methodInfo = method.Method; + if (!method.HasTarget) + { + return new InheritanceInvocationTypeGenerator(targetType, + method, + null, null) + .Generate(@class, options, namingScope) + .BuildType(); + } + var callback = CreateCallbackMethod(@class, methodInfo, method.MethodOnTarget); + return new InheritanceInvocationTypeGenerator(callback.DeclaringType, + method, + callback, null) + .Generate(@class, options, namingScope) + .BuildType(); + } + + private MethodBuilder CreateCallbackMethod(ClassEmitter emitter, MethodInfo methodInfo, MethodInfo methodOnTarget) + { + var targetMethod = methodOnTarget ?? methodInfo; + var callBackMethod = emitter.CreateMethod(namingScope.GetUniqueName(methodInfo.Name + "_callback"), targetMethod); + + if (targetMethod.IsGenericMethod) + targetMethod = targetMethod.MakeGenericMethod(callBackMethod.GenericTypeParams); + + var exps = new Expression[callBackMethod.Arguments.Length]; + for (var i = 0; i < callBackMethod.Arguments.Length; i++) + { + exps[i] = callBackMethod.Arguments[i].ToExpression(); + } + + // invocation on base class + + callBackMethod.CodeBuilder.AddStatement( + new ReturnStatement( + new MethodInvocationExpression(SelfReference.Self, + targetMethod, + exps))); + + return callBackMethod.MethodBuilder; + } + + private bool ExplicitlyImplementedInterfaceMethod(MetaMethod method) + { + return method.MethodOnTarget.IsPrivate; + } + + private MethodGenerator ExplicitlyImplementedInterfaceMethodGenerator(MetaMethod method, ClassEmitter @class, + ProxyGenerationOptions options, + OverrideMethodDelegate overrideMethod) + { + var @delegate = GetDelegateType(method, @class, options); + var contributor = GetContributor(@delegate, method); + var invocation = new InheritanceInvocationTypeGenerator(targetType, method, null, contributor) + .Generate(@class, options, namingScope) + .BuildType(); + return new MethodWithInvocationGenerator(method, + @class.GetField("__interceptors"), + invocation, + (c, m) => new TypeTokenExpression(targetType), + overrideMethod, + contributor); + } + + private IInvocationCreationContributor GetContributor(Type @delegate, MetaMethod method) + { + if (@delegate.IsGenericType == false) + { + return new InvocationWithDelegateContributor(@delegate, targetType, method, namingScope); + } + return new InvocationWithGenericDelegateContributor(@delegate, + method, + new FieldReference(InvocationMethods.ProxyObject)); + } + + private Type GetDelegateType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options) + { + var scope = @class.ModuleScope; + var key = new CacheKey( + typeof(Delegate), + targetType, + new[] { method.MethodOnTarget.ReturnType } + .Concat(ArgumentsUtil.GetTypes(method.MethodOnTarget.GetParameters())). + ToArray(), + null); + + var type = scope.GetFromCache(key); + if (type != null) + return type; + + type = new DelegateTypeGenerator(method, targetType) + .Generate(@class, options, namingScope) + .BuildType(); + + scope.RegisterInCache(key, type); + + return type; + } + + private Type GetInvocationType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options) + { + // NOTE: No caching since invocation is tied to this specific proxy type via its invocation method + return BuildInvocationType(method, @class, options); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyWithTargetTargetContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyWithTargetTargetContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyWithTargetTargetContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ClassProxyWithTargetTargetContributor.cs Sun Feb 13 20:10:55 2011 @@ -0,0 +1,177 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Reflection; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class ClassProxyWithTargetTargetContributor : CompositeTypeContributor + { + private readonly Type targetType; + private readonly IList methodsToSkip; + + public ClassProxyWithTargetTargetContributor(Type targetType, IList methodsToSkip, INamingScope namingScope) + : base(namingScope) + { + this.targetType = targetType; + this.methodsToSkip = methodsToSkip; + } + + protected override IEnumerable CollectElementsToProxyInternal(IProxyGenerationHook hook) + { + Debug.Assert(hook != null, "hook != null"); + + var targetItem = new WrappedClassMembersCollector(targetType) { Logger = Logger }; + targetItem.CollectMembersToProxy(hook); + yield return targetItem; + + foreach (var @interface in interfaces) + { + var item = new InterfaceMembersOnClassCollector(@interface, + true, + targetType.GetInterfaceMap(@interface)) { Logger = Logger }; + item.CollectMembersToProxy(hook); + yield return item; + } + } + + protected override MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod) + { + if (methodsToSkip.Contains(method.Method)) return null; + + if (!method.Proxyable) + { + return new MinimialisticMethodGenerator(method, + overrideMethod); + } + + if (IsDirectlyAccessible(method) == false) + { + return IndirectlyCalledMethodGenerator(method, @class, options, overrideMethod); + } + + var invocation = GetInvocationType(method, @class, options); + + return new MethodWithInvocationGenerator(method, + @class.GetField("__interceptors"), + invocation, + (c, m) => c.GetField("__target").ToExpression(), + overrideMethod, + null); + } + private IInvocationCreationContributor GetContributor(Type @delegate, MetaMethod method) + { + if (@delegate.IsGenericType == false) + { + return new InvocationWithDelegateContributor(@delegate, targetType, method, namingScope); + } + return new InvocationWithGenericDelegateContributor(@delegate, + method, + new FieldReference(InvocationMethods.ProxyObject)); + } + + private MethodGenerator IndirectlyCalledMethodGenerator(MetaMethod method, ClassEmitter proxy, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod) + { + var @delegate = GetDelegateType(method, proxy, options); + var contributor = GetContributor(@delegate, method); + var invocation = new CompositionInvocationTypeGenerator(targetType, method, null, false, contributor) + .Generate(proxy, options, namingScope) + .BuildType(); + return new MethodWithInvocationGenerator(method, + proxy.GetField("__interceptors"), + invocation, + (c, m) => c.GetField("__target").ToExpression(), + overrideMethod, + contributor); + } + + private Type GetDelegateType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options) + { + var scope = @class.ModuleScope; + var key = new CacheKey( + typeof(Delegate), + targetType, + new[] { method.MethodOnTarget.ReturnType } + .Concat(ArgumentsUtil.GetTypes(method.MethodOnTarget.GetParameters())). + ToArray(), + null); + + var type = scope.GetFromCache(key); + if (type != null) + return type; + + type = new DelegateTypeGenerator(method, targetType) + .Generate(@class, options, namingScope) + .BuildType(); + + scope.RegisterInCache(key, type); + + return type; + } + + private bool IsDirectlyAccessible(MetaMethod method) + { + return method.MethodOnTarget.IsPublic; + } + + private Type GetInvocationType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options) + { + var scope = @class.ModuleScope; + var invocationInterfaces = new[] { typeof(IInvocation) }; + + var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, invocationInterfaces, null); + + // no locking required as we're already within a lock + + var invocation = scope.GetFromCache(key); + if (invocation != null) + { + return invocation; + } + invocation = BuildInvocationType(method, @class, options); + + scope.RegisterInCache(key, invocation); + + return invocation; + } + + private Type BuildInvocationType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options) + { + if (!method.HasTarget) + { + return new InheritanceInvocationTypeGenerator(targetType, + method, + null, null) + .Generate(@class, options, namingScope) + .BuildType(); + } + return new CompositionInvocationTypeGenerator(method.Method.DeclaringType, + method, + method.Method, + false, + null) + .Generate(@class, options, namingScope) + .BuildType(); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\CompositeTypeContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\CompositeTypeContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\CompositeTypeContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\CompositeTypeContributor.cs Sun Feb 13 20:11:42 2011 @@ -0,0 +1,150 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + + using Castle.Core.Logging; + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + + internal abstract class CompositeTypeContributor: ITypeContributor + { + protected readonly INamingScope namingScope; + protected readonly ICollection interfaces = +#if SL3 + new List(); +#else + new HashSet(); +#endif + private ILogger logger = NullLogger.Instance; + private readonly ICollection properties = new TypeElementCollection(); + private readonly ICollection events = new TypeElementCollection(); + private readonly ICollection methods = new TypeElementCollection(); + + protected CompositeTypeContributor(INamingScope namingScope) + { + this.namingScope = namingScope; + } + + public ILogger Logger + { + get { return logger; } + set { logger = value; } + } + + public void CollectElementsToProxy(IProxyGenerationHook hook, MetaType model) + { + foreach (var collector in CollectElementsToProxyInternal(hook)) + { + foreach (var method in collector.Methods) + { + model.AddMethod(method); + methods.Add(method); + } + foreach (var @event in collector.Events) + { + model.AddEvent(@event); + events.Add(@event); + } + foreach (var property in collector.Properties) + { + model.AddProperty(property); + properties.Add(property); + } + } + } + + protected abstract IEnumerable CollectElementsToProxyInternal(IProxyGenerationHook hook); + + public virtual void Generate(ClassEmitter @class, ProxyGenerationOptions options) + { + foreach (var method in methods) + { + if (!method.Standalone) + { + continue; + } + + ImplementMethod(method, + @class, + options, + @class.CreateMethod); + } + + foreach (var property in properties) + { + ImplementProperty(@class, property, options); + } + + foreach (var @event in events) + { + ImplementEvent(@class, @event, options); + } + + } + + public void AddInterfaceToProxy(Type @interface) + { + Debug.Assert(@interface != null, "@interface == null", "Shouldn't be adding empty interfaces..."); + Debug.Assert(@interface.IsInterface, "@interface.IsInterface", "Should be adding interfaces only..."); + Debug.Assert(!interfaces.Contains(@interface), "!interfaces.ContainsKey(@interface)", "Shouldn't be adding same interface twice..."); + + interfaces.Add(@interface); + } + + private void ImplementEvent(ClassEmitter emitter, MetaEvent @event, ProxyGenerationOptions options) + { + @event.BuildEventEmitter(emitter); + ImplementMethod(@event.Adder, emitter, options, @event.Emitter.CreateAddMethod); + ImplementMethod(@event.Remover, emitter, options, @event.Emitter.CreateRemoveMethod); + + } + + private void ImplementProperty(ClassEmitter emitter, MetaProperty property, ProxyGenerationOptions options) + { + property.BuildPropertyEmitter(emitter); + if (property.CanRead) + { + ImplementMethod(property.Getter, emitter, options, property.Emitter.CreateGetMethod); + } + + if (property.CanWrite) + { + ImplementMethod(property.Setter, emitter, options, property.Emitter.CreateSetMethod); + + } + } + + protected abstract MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, + ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod); + + private void ImplementMethod(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options, + OverrideMethodDelegate overrideMethod) + { + { + var generator = GetMethodGenerator(method, @class, options, overrideMethod); + if (generator == null) return; + var proxyMethod = generator.Generate(@class, options, namingScope); + foreach (var attribute in AttributeUtil.GetNonInheritableAttributes(method.Method)) + { + proxyMethod.DefineCustomAttribute(attribute); + } + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateProxyTargetContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateProxyTargetContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateProxyTargetContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateProxyTargetContributor.cs Sun Feb 13 20:09:38 2011 @@ -0,0 +1,78 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + + internal class DelegateProxyTargetContributor : CompositeTypeContributor + { + private readonly Type targetType; + + public DelegateProxyTargetContributor(Type targetType, INamingScope namingScope) : base(namingScope) + { + this.targetType = targetType; + } + + protected override IEnumerable CollectElementsToProxyInternal(IProxyGenerationHook hook) + { + Debug.Assert(hook != null, "hook != null"); + var targetItem = new DelegateMembersCollector(targetType) {Logger = Logger}; + targetItem.CollectMembersToProxy(hook); + yield return targetItem; + } + + protected override MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, + ProxyGenerationOptions options, + OverrideMethodDelegate overrideMethod) + { + var invocation = GetInvocationType(method, @class, options); + return new MethodWithInvocationGenerator(method, + @class.GetField("__interceptors"), + invocation, + (c, m) => c.GetField("__target").ToExpression(), + overrideMethod, + null); + } + + private Type GetInvocationType(MetaMethod method, ClassEmitter emitter, ProxyGenerationOptions options) + { + var scope = emitter.ModuleScope; + var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, null, null); + + // no locking required as we're already within a lock + var invocation = scope.GetFromCache(key); + if (invocation != null) + { + return invocation; + } + + invocation = new CompositionInvocationTypeGenerator(method.Method.DeclaringType, + method, + method.Method, + false, + null) + .Generate(emitter, options, namingScope) + .BuildType(); + + scope.RegisterInCache(key, invocation); + + return invocation; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\Delegates.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\Delegates.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\Delegates.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\Delegates.cs Sun Feb 13 20:06:57 2011 @@ -0,0 +1,27 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal delegate MethodEmitter OverrideMethodDelegate( + string name, MethodAttributes attributes, MethodInfo methodToOverride); + + internal delegate Expression GetTargetExpressionDelegate(ClassEmitter @class, MethodInfo method); + internal delegate Reference GetTargetReferenceDelegate(ClassEmitter @class, MethodInfo method); +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateTypeGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateTypeGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateTypeGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\DelegateTypeGenerator.cs Sun Feb 13 20:09:47 2011 @@ -0,0 +1,111 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Reflection; + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class DelegateTypeGenerator : IGenerator + { + private const TypeAttributes DelegateFlags = TypeAttributes.Class | + TypeAttributes.Public | + TypeAttributes.Sealed | + TypeAttributes.AnsiClass | + TypeAttributes.AutoClass; + + private readonly MetaMethod method; + private readonly Type targetType; + + public DelegateTypeGenerator(MetaMethod method, Type targetType) + { + this.method = method; + this.targetType = targetType; + } + + #region IGenerator Members + + public AbstractTypeEmitter Generate(ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) + { + var emitter = GetEmitter(@class, namingScope); + BuildConstructor(emitter); + BuildInvokeMethod(emitter); + return emitter; + } + + #endregion + + private void BuildInvokeMethod(AbstractTypeEmitter @delegate) + { + var paramTypes = GetParamTypes(@delegate); + var invoke = @delegate.CreateMethod("Invoke", + MethodAttributes.Public | + MethodAttributes.HideBySig | + MethodAttributes.NewSlot | + MethodAttributes.Virtual, + @delegate.GetClosedParameterType(method.MethodOnTarget.ReturnType), + paramTypes); + invoke.MethodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); + } + + private Type[] GetParamTypes(AbstractTypeEmitter @delegate) + { + var parameters = method.MethodOnTarget.GetParameters(); + if (@delegate.TypeBuilder.IsGenericType) + { + var types = new Type[parameters.Length]; + + for (var i = 0; i < parameters.Length; i++) + { + types[i] = @delegate.GetClosedParameterType(parameters[i].ParameterType); + } + return types; + } + var paramTypes = new Type[parameters.Length + 1]; + paramTypes[0] = targetType; + for (var i = 0; i < parameters.Length; i++) + { + paramTypes[i + 1] = @delegate.GetClosedParameterType(parameters[i].ParameterType); + } + return paramTypes; + } + + private void BuildConstructor(AbstractTypeEmitter emitter) + { + var constructor = emitter.CreateConstructor(new ArgumentReference(typeof (object)), + new ArgumentReference(typeof (IntPtr))); + constructor.ConstructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); + } + + private AbstractTypeEmitter GetEmitter(ClassEmitter @class, INamingScope namingScope) + { + var methodInfo = method.MethodOnTarget; + var suggestedName = string.Format("Castle.Proxies.Delegates.{0}_{1}", + methodInfo.DeclaringType.Name, + method.Method.Name); + var uniqueName = namingScope.ParentScope.GetUniqueName(suggestedName); + + var @delegate = new ClassEmitter(@class.ModuleScope, + uniqueName, + typeof (MulticastDelegate), + Type.EmptyTypes, + DelegateFlags); + @delegate.CopyGenericParametersFromMethod(method.Method); + return @delegate; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ForwardingMethodGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ForwardingMethodGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ForwardingMethodGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ForwardingMethodGenerator.cs Sun Feb 13 20:07:09 2011 @@ -0,0 +1,44 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class ForwardingMethodGenerator : MethodGenerator + { + private readonly GetTargetReferenceDelegate getTargetReference; + + public ForwardingMethodGenerator(MetaMethod method, OverrideMethodDelegate overrideMethod, GetTargetReferenceDelegate getTargetReference) + : base(method, overrideMethod) + { + this.getTargetReference = getTargetReference; + } + + protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) + { + var targetReference = getTargetReference(@class, MethodToOverride); + var arguments = ArgumentsUtil.ConvertToArgumentReferenceExpression(MethodToOverride.GetParameters()); + + emitter.CodeBuilder.AddStatement(new ReturnStatement( + new MethodInvocationExpression( + targetReference, + MethodToOverride, + arguments) { VirtualCall = true })); + return emitter; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersCollector.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersCollector.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersCollector.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersCollector.cs Sun Feb 13 20:13:54 2011 @@ -0,0 +1,41 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Reflection; + using Castle.DynamicProxy.Generators; + + internal class InterfaceMembersCollector : MembersCollector + { + public InterfaceMembersCollector(Type @interface) + : base(@interface) + { + + } + + protected override MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone) + { + if (!IsAccessible(method)) + { + return null; + } + + var proxyable = AcceptMethod(method, false, hook); + return new MetaMethod(method, method, isStandalone, proxyable, false); + } + + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersOnClassCollector.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersOnClassCollector.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersOnClassCollector.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceMembersOnClassCollector.cs Sun Feb 13 20:13:41 2011 @@ -0,0 +1,53 @@ +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Reflection; + using Generators; + + internal class InterfaceMembersOnClassCollector : MembersCollector + { + private readonly bool onlyProxyVirtual; + private readonly InterfaceMapping map; + + public InterfaceMembersOnClassCollector(Type type, bool onlyProxyVirtual, InterfaceMapping map) : base(type) + { + this.onlyProxyVirtual = onlyProxyVirtual; + this.map = map; + } + + protected override MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone) + { + if (!IsAccessible(method)) + { + return null; + } + + if (onlyProxyVirtual && IsVirtuallyImplementedInterfaceMethod(method)) + { + return null; + } + + var methodOnTarget = GetMethodOnTarget(method); + + var proxyable = AcceptMethod(method, onlyProxyVirtual, hook); + return new MetaMethod(method, methodOnTarget, isStandalone, proxyable, methodOnTarget.IsPrivate == false); + } + + private MethodInfo GetMethodOnTarget(MethodInfo method) + { + int index = Array.IndexOf(map.InterfaceMethods, method); + if (index == -1) + { + return null; + } + + return map.TargetMethods[index]; + } + + private bool IsVirtuallyImplementedInterfaceMethod(MethodInfo method) + { + var info = GetMethodOnTarget(method); + return info != null && info.IsFinal == false; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyInstanceContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyInstanceContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyInstanceContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyInstanceContributor.cs Sun Feb 13 20:07:28 2011 @@ -0,0 +1,57 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.CodeBuilders; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class InterfaceProxyInstanceContributor : ProxyInstanceContributor + { + + protected override Expression GetTargetReferenceExpression(ClassEmitter emitter) + { + return emitter.GetField("__target").ToExpression(); + } + + public InterfaceProxyInstanceContributor(Type targetType, string proxyGeneratorId, Type[] interfaces) + : base(targetType, interfaces, proxyGeneratorId) + { + } + +#if !SILVERLIGHT + protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo, ArgumentReference streamingContext, ClassEmitter emitter) + { + var targetField = emitter.GetField("__target"); + + codebuilder.AddStatement(new ExpressionStatement( + new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.AddValue_Object, + new ConstReference("__targetFieldType").ToExpression(), + new ConstReference( + targetField.Reference.FieldType.AssemblyQualifiedName). + ToExpression()))); + + codebuilder.AddStatement(new ExpressionStatement( + new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.AddValue_Object, + new ConstReference("__theInterface").ToExpression(), + new ConstReference(targetType.AssemblyQualifiedName). + ToExpression()))); + } +#endif + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyTargetContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyTargetContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyTargetContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyTargetContributor.cs Sun Feb 13 20:10:29 2011 @@ -0,0 +1,110 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + + internal class InterfaceProxyTargetContributor : CompositeTypeContributor + { + private readonly Type proxyTargetType; + private readonly bool canChangeTarget; + + public InterfaceProxyTargetContributor(Type proxyTargetType, bool canChangeTarget, INamingScope namingScope) + : base(namingScope) + { + this.proxyTargetType = proxyTargetType; + this.canChangeTarget = canChangeTarget; + } + + protected override IEnumerable CollectElementsToProxyInternal(IProxyGenerationHook hook) + { + Debug.Assert(hook != null, "hook != null"); + + foreach (var @interface in interfaces) + { + var item = GetCollectorForInterface(@interface); + item.Logger = Logger; + item.CollectMembersToProxy(hook); + yield return item; + } + } + + protected virtual MembersCollector GetCollectorForInterface(Type @interface) + { + return new InterfaceMembersOnClassCollector(@interface, false, proxyTargetType.GetInterfaceMap(@interface)); + } + + protected override MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod) + { + if (!method.Proxyable) + { + return new ForwardingMethodGenerator(method, + overrideMethod, + (c, m) => c.GetField("__target")); + } + + var invocation = GetInvocationType(method, @class, options); + + return new MethodWithInvocationGenerator(method, + @class.GetField("__interceptors"), + invocation, + (c, m) => c.GetField("__target").ToExpression(), + overrideMethod, + null); + } + + private Type GetInvocationType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options) + { + var scope = @class.ModuleScope; + + Type[] invocationInterfaces; + if(canChangeTarget) + { + invocationInterfaces = new[] { typeof(IInvocation), typeof(IChangeProxyTarget) }; + } + else + { + + invocationInterfaces = new[] { typeof(IInvocation) }; + } + + var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, invocationInterfaces, null); + + // no locking required as we're already within a lock + + var invocation = scope.GetFromCache(key); + if (invocation != null) + { + return invocation; + } + + invocation = new CompositionInvocationTypeGenerator(method.Method.DeclaringType, + method, + method.Method, + canChangeTarget, + null) + .Generate(@class, options, namingScope).BuildType(); + + scope.RegisterInCache(key, invocation); + + return invocation; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithOptionalTargetContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithOptionalTargetContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithOptionalTargetContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithOptionalTargetContributor.cs Sun Feb 13 20:07:03 2011 @@ -0,0 +1,43 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + + internal class InterfaceProxyWithOptionalTargetContributor : InterfaceProxyWithoutTargetContributor + { + private readonly GetTargetReferenceDelegate getTargetReference; + + public InterfaceProxyWithOptionalTargetContributor(INamingScope namingScope, GetTargetExpressionDelegate getTarget, + GetTargetReferenceDelegate getTargetReference) + : base(namingScope, getTarget) + { + this.getTargetReference = getTargetReference; + } + + protected override MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, + ProxyGenerationOptions options, + OverrideMethodDelegate overrideMethod) + { + if (!method.Proxyable) + { + return new OptionallyForwardingMethodGenerator(method, overrideMethod, getTargetReference); + } + + return base.GetMethodGenerator(method, @class, options, overrideMethod); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithoutTargetContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithoutTargetContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithoutTargetContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithoutTargetContributor.cs Sun Feb 13 20:07:49 2011 @@ -0,0 +1,86 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + + internal class InterfaceProxyWithoutTargetContributor : CompositeTypeContributor + { + private readonly GetTargetExpressionDelegate getTargetExpression; + + public InterfaceProxyWithoutTargetContributor(INamingScope namingScope, GetTargetExpressionDelegate getTarget) + : base(namingScope) + { + getTargetExpression = getTarget; + } + + protected override IEnumerable CollectElementsToProxyInternal(IProxyGenerationHook hook) + { + Debug.Assert(hook != null, "hook != null"); + foreach (var @interface in interfaces) + { + var item = new InterfaceMembersCollector(@interface); + item.CollectMembersToProxy(hook); + yield return item; + } + } + + protected override MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod) + { + if (!method.Proxyable) + { + return new MinimialisticMethodGenerator(method, overrideMethod); + } + + var invocation = GetInvocationType(method, @class, options); + return new MethodWithInvocationGenerator(method, + @class.GetField("__interceptors"), + invocation, + getTargetExpression, + overrideMethod, + null); + } + + private Type GetInvocationType(MetaMethod method, ClassEmitter emitter, ProxyGenerationOptions options) + { + var scope = emitter.ModuleScope; + var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, null, null); + + // no locking required as we're already within a lock + var invocation = scope.GetFromCache(key); + if (invocation != null) + { + return invocation; + } + + invocation = new CompositionInvocationTypeGenerator(method.Method.DeclaringType, + method, + method.Method, + false, + null) + .Generate(emitter, options, namingScope) + .BuildType(); + + scope.RegisterInCache(key, invocation); + + return invocation; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithTargetInterfaceTargetContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithTargetInterfaceTargetContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithTargetInterfaceTargetContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InterfaceProxyWithTargetInterfaceTargetContributor.cs Sun Feb 13 20:10:47 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + + using Castle.DynamicProxy.Generators; + + internal class InterfaceProxyWithTargetInterfaceTargetContributor : InterfaceProxyTargetContributor + { + protected override MembersCollector GetCollectorForInterface(Type @interface) + { + return new InterfaceMembersCollector(@interface); + } + + public InterfaceProxyWithTargetInterfaceTargetContributor(Type proxyTargetType, bool allowChangeTarget, INamingScope namingScope) + : base(proxyTargetType, allowChangeTarget, namingScope) + { + + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithDelegateContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithDelegateContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithDelegateContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithDelegateContributor.cs Sun Feb 13 20:11:24 2011 @@ -0,0 +1,104 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Diagnostics; + using System.Reflection; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class InvocationWithDelegateContributor : IInvocationCreationContributor + { + private readonly Type delegateType; + private readonly Type targetType; + private readonly MetaMethod method; + private readonly INamingScope namingScope; + + public InvocationWithDelegateContributor(Type delegateType, Type targetType,MetaMethod method, INamingScope namingScope) + { + Debug.Assert(delegateType.IsGenericType == false, "delegateType.IsGenericType == false"); + this.delegateType = delegateType; + this.targetType = targetType; + this.method = method; + this.namingScope = namingScope; + } + + public ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, AbstractTypeEmitter invocation) + { + var arguments = GetArguments(baseCtorArguments); + var constructor = invocation.CreateConstructor(arguments); + + var delegateField = invocation.CreateField("delegate", delegateType); + constructor.CodeBuilder.AddStatement(new AssignStatement(delegateField, new ReferenceExpression(arguments[0]))); + return constructor; + } + + public MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, Expression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget) + { + var allArgs = GetAllArgs(args, targetField); + var @delegate = (Reference)invocation.GetField("delegate"); + + return new MethodInvocationExpression(@delegate, GetCallbackMethod(), allArgs); + } + + public MethodInfo GetCallbackMethod() + { + return delegateType.GetMethod("Invoke"); + } + + public Expression[] GetConstructorInvocationArguments(Expression[] arguments, ClassEmitter proxy) + { + var allArguments = new Expression[arguments.Length + 1]; + allArguments[0] = new ReferenceExpression(BuildDelegateToken(proxy)); + Array.Copy(arguments, 0, allArguments, 1, arguments.Length); + return allArguments; + } + + private FieldReference BuildDelegateToken(ClassEmitter proxy) + { + var callback = proxy.CreateStaticField(namingScope.GetUniqueName("callback_" + method.Method.Name), delegateType); + var createDelegate = new MethodInvocationExpression( + null, + DelegateMethods.CreateDelegate, + new TypeTokenExpression(delegateType), + NullExpression.Instance, + new MethodTokenExpression(method.MethodOnTarget)); + var bindDelegate = new AssignStatement(callback, new ConvertExpression(delegateType, createDelegate)); + + proxy.ClassConstructor.CodeBuilder.AddStatement(bindDelegate); + return callback; + } + + private ArgumentReference[] GetArguments(ArgumentReference[] baseCtorArguments) + { + var arguments = new ArgumentReference[baseCtorArguments.Length + 1]; + arguments[0] = new ArgumentReference(delegateType); + baseCtorArguments.CopyTo(arguments, 1); + return arguments; + } + + private Expression[] GetAllArgs(Expression[] args, Reference targetField) + { + var allArgs = new Expression[args.Length + 1]; + args.CopyTo(allArgs, 1); + allArgs[0] = new ConvertExpression(targetType, targetField.ToExpression()); + return allArgs; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithGenericDelegateContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithGenericDelegateContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithGenericDelegateContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\InvocationWithGenericDelegateContributor.cs Sun Feb 13 20:10:41 2011 @@ -0,0 +1,84 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Diagnostics; + using System.Reflection; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class InvocationWithGenericDelegateContributor : IInvocationCreationContributor + { + private readonly Type delegateType; + private readonly MetaMethod method; + private readonly Reference targetReference; + + public InvocationWithGenericDelegateContributor(Type delegateType, MetaMethod method, Reference targetReference) + { + Debug.Assert(delegateType.IsGenericType, "delegateType.IsGenericType"); + this.delegateType = delegateType; + this.method = method; + this.targetReference = targetReference; + } + + public ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, AbstractTypeEmitter invocation) + { + return invocation.CreateConstructor(baseCtorArguments); + } + + public MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, Expression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget) + { + var @delegate = GetDelegate(invocation, invokeMethodOnTarget); + return new MethodInvocationExpression(@delegate, GetCallbackMethod(), args); + } + + public MethodInfo GetCallbackMethod() + { + return delegateType.GetMethod("Invoke"); + } + + public Expression[] GetConstructorInvocationArguments(Expression[] arguments, ClassEmitter proxy) + { + return arguments; + } + + private Reference GetDelegate(AbstractTypeEmitter invocation, MethodEmitter invokeMethodOnTarget) + { + var closedDelegateType = delegateType.MakeGenericType(invocation.GenericTypeParams); + var localReference = invokeMethodOnTarget.CodeBuilder.DeclareLocal(closedDelegateType); + var closedMethodOnTarget = method.MethodOnTarget.MakeGenericMethod(invocation.GenericTypeParams); + var localTarget = new ReferenceExpression(targetReference); + invokeMethodOnTarget.CodeBuilder.AddStatement( + SetDelegate(localReference, localTarget, closedDelegateType, closedMethodOnTarget)); + return localReference; + } + + private AssignStatement SetDelegate(LocalReference localDelegate, ReferenceExpression localTarget, + Type closedDelegateType, MethodInfo closedMethodOnTarget) + { + var delegateCreateDelegate = new MethodInvocationExpression( + null, + DelegateMethods.CreateDelegate, + new TypeTokenExpression(closedDelegateType), + localTarget, + new MethodTokenExpression(closedMethodOnTarget)); + return new AssignStatement(localDelegate, new ConvertExpression(closedDelegateType, delegateCreateDelegate)); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ITypeContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ITypeContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ITypeContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ITypeContributor.cs Sun Feb 13 20:06:40 2011 @@ -0,0 +1,29 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using Castle.DynamicProxy.Generators; + + using Generators.Emitters; + + /// + /// Interface describing elements composing generated type + /// + internal interface ITypeContributor + { + void CollectElementsToProxy(IProxyGenerationHook hook, MetaType model); + void Generate(ClassEmitter @class, ProxyGenerationOptions options); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\MembersCollector.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\MembersCollector.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\MembersCollector.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\MembersCollector.cs Sun Feb 13 20:13:33 2011 @@ -0,0 +1,284 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using Castle.Core.Logging; + using Castle.DynamicProxy.Generators; + + internal abstract class MembersCollector + { + private const BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; + private ILogger logger = NullLogger.Instance; + + private ICollection checkedMethods = +#if SL3 + new List(); +#else + new HashSet(); +#endif + private readonly IDictionary properties = new Dictionary(); + private readonly IDictionary events = new Dictionary(); + private readonly IDictionary methods = new Dictionary(); + + protected readonly Type type; + + protected MembersCollector(Type type) + { + this.type = type; + } + + public ILogger Logger + { + get { return logger; } + set { logger = value; } + } + + public IEnumerable Methods + { + get { return methods.Values; } + } + + public IEnumerable Properties + { + get { return properties.Values; } + } + + public IEnumerable Events + { + get { return events.Values; } + } + + public virtual void CollectMembersToProxy(IProxyGenerationHook hook) + { + if (checkedMethods == null) // this method was already called! + { + throw new InvalidOperationException( + string.Format("Can't call 'CollectMembersToProxy' method twice. This usually signifies a bug in custom {0}.", + typeof (ITypeContributor))); + } + CollectProperties(hook); + CollectEvents(hook); + // Methods go last, because properties and events have methods too (getters/setters add/remove) + // and we don't want to get duplicates, so we collect property and event methods first + // then we collect methods, and add only these that aren't there yet + CollectMethods(hook); + + checkedMethods = null; // this is ugly, should have a boolean flag for this or something + } + + private void CollectProperties(IProxyGenerationHook hook) + { + PropertyInfo[] propertiesFound = type.GetProperties(Flags); + foreach (PropertyInfo property in propertiesFound) + { + AddProperty(property, hook); + } + } + + private void CollectEvents(IProxyGenerationHook hook) + { + EventInfo[] eventsFound = type.GetEvents(Flags); + foreach (EventInfo @event in eventsFound) + { + AddEvent(@event, hook); + } + } + + private void CollectMethods(IProxyGenerationHook hook) + { + MethodInfo[] methodsFound = MethodFinder.GetAllInstanceMethods(type, Flags); + foreach (MethodInfo method in methodsFound) + { + AddMethod(method, hook, true); + } + } + + private void AddProperty(PropertyInfo property, IProxyGenerationHook hook) + { + MetaMethod getter = null; + MetaMethod setter = null; + + if (property.CanRead) + { + MethodInfo getMethod = property.GetGetMethod(true); + getter = AddMethod(getMethod, hook, false); + } + + if (property.CanWrite) + { + MethodInfo setMethod = property.GetSetMethod(true); + setter = AddMethod(setMethod, hook, false); + } + + if (setter==null && getter == null) + { + return; + } + + var nonInheritableAttributes = AttributeUtil.GetNonInheritableAttributes(property); + var arguments = property.GetIndexParameters(); + + properties[property] = new MetaProperty(property.Name, + property.PropertyType, + property.DeclaringType, + getter, + setter, + nonInheritableAttributes, + arguments.Select(a => a.ParameterType).ToArray()); + } + + private void AddEvent(EventInfo @event, IProxyGenerationHook hook) + { + MethodInfo addMethod = @event.GetAddMethod(true); + MethodInfo removeMethod = @event.GetRemoveMethod(true); + MetaMethod adder = null; + MetaMethod remover = null; + + if (addMethod != null) + { + adder = AddMethod(addMethod, hook, false); + } + + if (removeMethod != null) + { + remover = AddMethod(removeMethod, hook, false); + } + + if (adder == null && remover == null) return; + + events[@event] = new MetaEvent(@event.Name, + @event.DeclaringType, @event.EventHandlerType, adder, remover, EventAttributes.None); + } + + private MetaMethod AddMethod(MethodInfo method, IProxyGenerationHook hook, bool isStandalone) + { + if (checkedMethods.Contains(method)) + { + return null; + } + checkedMethods.Add(method); + + if (methods.ContainsKey(method)) + { + return null; + } + var methodToGenerate = GetMethodToGenerate(method, hook, isStandalone); + if (methodToGenerate != null) + { + methods[method] = methodToGenerate; + } + + return methodToGenerate; + } + + protected abstract MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone); + + /// + /// Checks if the method is public or protected. + /// + /// + /// + protected bool IsAccessible(MethodBase method) + { + // Accessibility supported by the full framework and CoreCLR + if (method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly) + { + return true; + } + +#if !SILVERLIGHT + // Accessibility not supported by the CoreCLR + if (method.IsFamilyAndAssembly) + { + return true; + } + if (InternalsHelper.IsInternalToDynamicProxy(method.DeclaringType.Assembly) && method.IsAssembly) + { + return true; + } +#else + // Explicitly implemented interface method on class + if (method.IsPrivate && method.IsFinal) + { + Logger.Debug("Excluded explicitly implemented interface method {0} on type {1} because it cannot be intercepted.", + method.Name, method.DeclaringType.FullName); + } +#endif + return false; + } + + /// + /// Performs some basic screening and invokes the + /// to select methods. + /// + /// + /// + /// + /// + protected bool AcceptMethod(MethodInfo method, bool onlyVirtuals, IProxyGenerationHook hook) + { + // we can never intercept a sealed (final) method + if (method.IsFinal) + { + Logger.Debug("Excluded sealed method {0} on {1} because it cannot be intercepted.", method.Name, method.DeclaringType.FullName); + return false; + } + + bool isInternalsAndNotVisibleToDynamicProxy = InternalsHelper.IsInternal(method); + if (isInternalsAndNotVisibleToDynamicProxy) + { + isInternalsAndNotVisibleToDynamicProxy = InternalsHelper.IsInternalToDynamicProxy(method.DeclaringType.Assembly) == + false; + } + + if (isInternalsAndNotVisibleToDynamicProxy) + return false; + + if (onlyVirtuals && !method.IsVirtual) + { +#if !SILVERLIGHT + if (method.DeclaringType != typeof(MarshalByRefObject)) +#endif + { + Logger.Debug("Excluded non-virtual method {0} on {1} because it cannot be intercepted.", method.Name, method.DeclaringType.FullName); + hook.NonProxyableMemberNotification(type, method); + } + return false; + } + + //can only proxy methods that are public or protected (or internals that have already been checked above) + if ((method.IsPublic || method.IsFamily || method.IsAssembly || method.IsFamilyOrAssembly) == false) + return false; + + +#if !SILVERLIGHT + if (method.DeclaringType == typeof(MarshalByRefObject)) + { + return false; + } +#endif + if (method.DeclaringType == typeof(object) && method.Name.Equals("Finalize", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + return hook.ShouldInterceptMethod(type, method); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\MinimialisticMethodGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\MinimialisticMethodGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\MinimialisticMethodGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\MinimialisticMethodGenerator.cs Sun Feb 13 20:07:15 2011 @@ -0,0 +1,61 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System.Reflection; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class MinimialisticMethodGenerator : MethodGenerator + { + + public MinimialisticMethodGenerator(MetaMethod method, OverrideMethodDelegate overrideMethod) + : base(method, overrideMethod) + { + } + + protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) + { + InitOutParameters(emitter, MethodToOverride.GetParameters()); + + if (emitter.ReturnType == typeof(void)) + { + emitter.CodeBuilder.AddStatement(new ReturnStatement()); + } + else + { + emitter.CodeBuilder.AddStatement(new ReturnStatement(new DefaultValueExpression(emitter.ReturnType))); + } + + return emitter; + } + + private void InitOutParameters(MethodEmitter emitter, ParameterInfo[] parameters) + { + for (int index = 0; index < parameters.Length; index++) + { + var parameter = parameters[index]; + if (parameter.IsOut) + { + emitter.CodeBuilder.AddStatement( + new AssignArgumentStatement(new ArgumentReference(parameter.ParameterType, index + 1), + new DefaultValueExpression(parameter.ParameterType))); + } + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\MixinContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\MixinContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\MixinContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\MixinContributor.cs Sun Feb 13 20:11:33 2011 @@ -0,0 +1,150 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class MixinContributor : CompositeTypeContributor + { + private readonly bool canChangeTarget; + private readonly IList empty = new List(); + private readonly IDictionary fields = new Dictionary(); + private readonly GetTargetExpressionDelegate getTargetExpression; + + public MixinContributor(INamingScope namingScope, bool canChangeTarget) + :base(namingScope) + { + this.canChangeTarget = canChangeTarget; + getTargetExpression = BuildGetTargetExpression(); + } + + public IEnumerable Fields + { + get { return fields.Values; } + } + + private GetTargetExpressionDelegate BuildGetTargetExpression() + { + if (!canChangeTarget) + { + return (c, m) => fields[m.DeclaringType].ToExpression(); + } + + return (c, m) => new NullCoalescingOperatorExpression( + new AsTypeReference(c.GetField("__target"), m.DeclaringType).ToExpression(), + fields[m.DeclaringType].ToExpression()); + } + + protected override IEnumerable CollectElementsToProxyInternal(IProxyGenerationHook hook) + { + foreach (var @interface in interfaces) + { + var item = new InterfaceMembersCollector(@interface); + item.CollectMembersToProxy(hook); + yield return item; + } + } + + public override void Generate(ClassEmitter @class, ProxyGenerationOptions options) + { + foreach (var @interface in interfaces) + { + fields[@interface] = BuildTargetField(@class, @interface); + } + + foreach (var emptyInterface in empty) + { + fields[emptyInterface] = BuildTargetField(@class, emptyInterface); + } + + base.Generate(@class, options); + } + + public void AddEmptyInterface(Type @interface) + { + Debug.Assert(@interface != null, "@interface == null", "Shouldn't be adding empty interfaces..."); + Debug.Assert(@interface.IsInterface, "@interface.IsInterface", "Should be adding interfaces only..."); + Debug.Assert(!interfaces.Contains(@interface), "!interfaces.Contains(@interface)", "Shouldn't be adding same interface twice..."); + Debug.Assert(!empty.Contains(@interface), "!empty.Contains(@interface)", "Shouldn't be adding same interface twice..."); + empty.Add(@interface); + } + + protected override MethodGenerator GetMethodGenerator(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod) + { + if (!method.Proxyable) + { + return new ForwardingMethodGenerator(method, + overrideMethod, + (c, i) => fields[i.DeclaringType]); + } + + var invocation = GetInvocationType(method, @class, options); + return new MethodWithInvocationGenerator(method, + @class.GetField("__interceptors"), + invocation, + getTargetExpression, + overrideMethod, + null); + } + + private Type GetInvocationType(MetaMethod method, ClassEmitter emitter, ProxyGenerationOptions options) + { + var scope = emitter.ModuleScope; + Type[] invocationInterfaces; + if (canChangeTarget) + { + invocationInterfaces = new[] { typeof(IInvocation), typeof(IChangeProxyTarget) }; + } + else + { + + invocationInterfaces = new[] { typeof(IInvocation) }; + } + var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, invocationInterfaces, null); + + // no locking required as we're already within a lock + + var invocation = scope.GetFromCache(key); + if (invocation != null) + { + return invocation; + } + + invocation = new CompositionInvocationTypeGenerator(method.Method.DeclaringType, + method, + method.Method, + canChangeTarget, + null) + .Generate(emitter, options, namingScope) + .BuildType(); + + scope.RegisterInCache(key, invocation); + + return invocation; + } + + private FieldReference BuildTargetField(ClassEmitter @class, Type type) + { + var name = "__mixin_" + type.FullName.Replace(".", "_"); + return @class.CreateField(namingScope.GetUniqueName(name), type); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\OptionallyForwardingMethodGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\OptionallyForwardingMethodGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\OptionallyForwardingMethodGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\OptionallyForwardingMethodGenerator.cs Sun Feb 13 20:08:06 2011 @@ -0,0 +1,90 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Reflection; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class OptionallyForwardingMethodGenerator : MethodGenerator + { + // TODO: This class largely duplicates code from Forwarding and Minimalistic generators. Should be refactored to change that + private readonly GetTargetReferenceDelegate getTargetReference; + + public OptionallyForwardingMethodGenerator(MetaMethod method, OverrideMethodDelegate overrideMethod, + GetTargetReferenceDelegate getTargetReference) + : base(method, overrideMethod) + { + this.getTargetReference = getTargetReference; + } + + protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, + ProxyGenerationOptions options, INamingScope namingScope) + { + var targetReference = getTargetReference(@class, MethodToOverride); + + emitter.CodeBuilder.AddStatement( + new ExpressionStatement( + new IfNullExpression(targetReference, IfNull(emitter.ReturnType), IfNotNull(targetReference)))); + return emitter; + } + + private Expression IfNotNull(Reference targetReference) + { + var expression = new MultiStatementExpression(); + var arguments = ArgumentsUtil.ConvertToArgumentReferenceExpression(MethodToOverride.GetParameters()); + + expression.AddStatement(new ReturnStatement( + new MethodInvocationExpression( + targetReference, + MethodToOverride, + arguments) { VirtualCall = true })); + return expression; + } + + private Expression IfNull(Type returnType) + { + var expression = new MultiStatementExpression(); + InitOutParameters(expression, MethodToOverride.GetParameters()); + + if (returnType == typeof(void)) + { + expression.AddStatement(new ReturnStatement()); + } + else + { + expression.AddStatement(new ReturnStatement(new DefaultValueExpression(returnType))); + } + return expression; + } + + private void InitOutParameters(MultiStatementExpression expression, ParameterInfo[] parameters) + { + for (var index = 0; index < parameters.Length; index++) + { + var parameter = parameters[index]; + if (parameter.IsOut) + { + expression.AddStatement( + new AssignArgumentStatement(new ArgumentReference(parameter.ParameterType, index + 1), + new DefaultValueExpression(parameter.ParameterType))); + } + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ProxyInstanceContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ProxyInstanceContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\ProxyInstanceContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\ProxyInstanceContributor.cs Sun Feb 13 20:09:52 2011 @@ -0,0 +1,178 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; +#if !SILVERLIGHT + using System.Runtime.Serialization; +#endif + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.CodeBuilders; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Serialization; + using Castle.DynamicProxy.Tokens; + + internal abstract class ProxyInstanceContributor : ITypeContributor + { + // TODO: this whole type (and its descendants) should be #if !SILVERLIGHT... and empty type should be used instead for SL + + protected readonly Type targetType; + private readonly string proxyTypeId; + private readonly Type[] interfaces; + + protected ProxyInstanceContributor(Type targetType, Type[] interfaces,string proxyTypeId) + { + this.targetType = targetType; + this.proxyTypeId = proxyTypeId; + this.interfaces = interfaces ?? Type.EmptyTypes; + } + + protected abstract Expression GetTargetReferenceExpression(ClassEmitter emitter); + + + public virtual void Generate(ClassEmitter @class, ProxyGenerationOptions options) + { + var interceptors = @class.GetField("__interceptors"); +#if !SILVERLIGHT + ImplementGetObjectData(@class); +#endif + ImplementProxyTargetAccessor(@class, interceptors); + foreach (var attribute in AttributeUtil.GetNonInheritableAttributes(targetType)) + { + @class.DefineCustomAttribute(attribute); + } + } + + protected void ImplementProxyTargetAccessor(ClassEmitter emitter, FieldReference interceptorsField) + { + + MethodEmitter dynProxyGetTarget = emitter.CreateMethod("DynProxyGetTarget", typeof(object)); + + dynProxyGetTarget.CodeBuilder.AddStatement( + new ReturnStatement(new ConvertExpression(typeof(object), targetType, GetTargetReferenceExpression(emitter)))); + + MethodEmitter getInterceptors = emitter.CreateMethod("GetInterceptors", typeof(IInterceptor[])); + + getInterceptors.CodeBuilder.AddStatement( + new ReturnStatement(interceptorsField)); + } + +#if !SILVERLIGHT + + protected void ImplementGetObjectData(ClassEmitter emitter) + { + var getObjectData = emitter.CreateMethod("GetObjectData", typeof(void), new[] { typeof(SerializationInfo), typeof(StreamingContext) }); + var info = getObjectData.Arguments[0]; + + var typeLocal = getObjectData.CodeBuilder.DeclareLocal(typeof (Type)); + + getObjectData.CodeBuilder.AddStatement( + new AssignStatement( + typeLocal, + new MethodInvocationExpression( + null, + TypeMethods.StaticGetType, + new ConstReference(typeof (ProxyObjectReference).AssemblyQualifiedName).ToExpression(), + new ConstReference(1).ToExpression(), + new ConstReference(0).ToExpression()))); + + getObjectData.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression( + info, + SerializationInfoMethods.SetType, + typeLocal.ToExpression()))); + + foreach (var field in emitter.GetAllFields()) + { + if (field.Reference.IsStatic) continue; + if (field.Reference.IsNotSerialized) continue; + AddAddValueInvocation(info, getObjectData, field); + } + + LocalReference interfacesLocal = getObjectData.CodeBuilder.DeclareLocal(typeof (string[])); + + getObjectData.CodeBuilder.AddStatement( + new AssignStatement( + interfacesLocal, + new NewArrayExpression(interfaces.Length, typeof (string)))); + + for (int i = 0; i < interfaces.Length; i++) + { + getObjectData.CodeBuilder.AddStatement( + new AssignArrayStatement( + interfacesLocal, + i, + new ConstReference(interfaces[i].AssemblyQualifiedName).ToExpression())); + } + + getObjectData.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression( + info, + SerializationInfoMethods.AddValue_Object, + new ConstReference("__interfaces").ToExpression(), + interfacesLocal.ToExpression()))); + + getObjectData.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression( + info, + SerializationInfoMethods.AddValue_Object, + new ConstReference("__baseType").ToExpression(), + new ConstReference(emitter.BaseType.AssemblyQualifiedName).ToExpression()))); + + getObjectData.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression( + info, + SerializationInfoMethods.AddValue_Object, + new ConstReference("__proxyGenerationOptions").ToExpression(), + emitter.GetField("proxyGenerationOptions").ToExpression()))); + + + + getObjectData.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression(info, + SerializationInfoMethods.AddValue_Object, + new ConstReference("__proxyTypeId").ToExpression(), + new ConstReference(proxyTypeId).ToExpression()))); + + CustomizeGetObjectData(getObjectData.CodeBuilder, info, getObjectData.Arguments[1], emitter); + + getObjectData.CodeBuilder.AddStatement(new ReturnStatement()); + } + + protected virtual void AddAddValueInvocation(ArgumentReference serializationInfo, MethodEmitter getObjectData, FieldReference field) + { + getObjectData.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression( + serializationInfo, + SerializationInfoMethods.AddValue_Object, + new ConstReference(field.Reference.Name).ToExpression(), + field.ToExpression()))); + return; + } + + protected abstract void CustomizeGetObjectData(AbstractCodeBuilder builder, ArgumentReference serializationInfo, ArgumentReference streamingContext, ClassEmitter emitter); +#endif + public void CollectElementsToProxy(IProxyGenerationHook hook, MetaType model) + { + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\WrappedClassMembersCollector.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\WrappedClassMembersCollector.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Contributors\WrappedClassMembersCollector.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Contributors\WrappedClassMembersCollector.cs Sun Feb 13 20:14:06 2011 @@ -0,0 +1,86 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Contributors +{ + using System; + using System.Reflection; + using System.Runtime.CompilerServices; + + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + + internal class WrappedClassMembersCollector : ClassMembersCollector + { + public WrappedClassMembersCollector(Type type) : base(type) + { + } + + public override void CollectMembersToProxy(IProxyGenerationHook hook) + { + base.CollectMembersToProxy(hook); + CollectFields(hook); + // TODO: perhaps we should also look for nested classes... + } + + protected override MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone) + { +#if SILVERLIGHT + if(method.IsPublic == false) + { + // we can't proxy protected methods like this on Silverlight + return null; + } +#endif + if (!IsAccessible(method)) + { + return null; + } + + var accepted = AcceptMethod(method, true, hook); + if (!accepted && !method.IsAbstract) + { + //we don't need to do anything... + return null; + } + + return new MetaMethod(method, method, isStandalone, accepted, hasTarget: true); + } + + protected bool IsGeneratedByTheCompiler(FieldInfo field) + { + // for example fields backing autoproperties + return Attribute.IsDefined(field, typeof(CompilerGeneratedAttribute)); + } + + protected virtual bool IsOKToBeOnProxy(FieldInfo field) + { + return IsGeneratedByTheCompiler(field); + } + + private void CollectFields(IProxyGenerationHook hook) + { + var fields = type.GetAllFields(); + foreach (var field in fields) + { + if (IsOKToBeOnProxy(field)) + { + continue; + } + + hook.NonProxyableMemberNotification(type, field); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\DefaultProxyBuilder.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\DefaultProxyBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\DefaultProxyBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\DefaultProxyBuilder.cs Sun Feb 13 20:10:05 2011 @@ -0,0 +1,178 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + + using Castle.Core.Logging; + using Castle.DynamicProxy.Generators; + +#if SILVERLIGHT + using Castle.DynamicProxy.SilverlightExtensions; +#endif + + /// + /// Default implementation of interface producing in-memory proxy assemblies. + /// + internal class DefaultProxyBuilder : IProxyBuilder + { + private readonly ModuleScope scope; + private ILogger logger = NullLogger.Instance; + + /// + /// Initializes a new instance of the class with new . + /// + public DefaultProxyBuilder() + : this(new ModuleScope()) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The module scope for generated proxy types. + public DefaultProxyBuilder(ModuleScope scope) + { + this.scope = scope; + } + + public ILogger Logger + { + get { return logger; } + set { logger = value; } + } + + public ModuleScope ModuleScope + { + get { return scope; } + } + + [Obsolete("Use CreateClassProxyType method instead.")] + public Type CreateClassProxy(Type classToProxy, ProxyGenerationOptions options) + { + return CreateClassProxyType(classToProxy, Type.EmptyTypes, options); + } + + [Obsolete("Use CreateClassProxyType method instead.")] + public Type CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) + { + return CreateClassProxyType(classToProxy, additionalInterfacesToProxy, options); + } + + public Type CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) + { + AssertValidType(classToProxy); + AssertValidTypes(additionalInterfacesToProxy); + + var generator = new ClassProxyGenerator(scope, classToProxy) { Logger = logger }; + return generator.GenerateCode(additionalInterfacesToProxy, options); + } + + public Type CreateClassProxyTypeWithTarget(Type classToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options) + { + AssertValidType(classToProxy); + AssertValidTypes(additionalInterfacesToProxy); + var generator = new ClassProxyWithTargetGenerator(scope, classToProxy, additionalInterfacesToProxy, options) + { Logger = logger }; + return generator.GetGeneratedType(); + } + + public Type CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + Type targetType, + ProxyGenerationOptions options) + { + AssertValidType(interfaceToProxy); + AssertValidTypes(additionalInterfacesToProxy); + + var generator = new InterfaceProxyWithTargetGenerator(scope, interfaceToProxy) { Logger = logger }; + return generator.GenerateCode(targetType, additionalInterfacesToProxy, options); + } + + public Type CreateInterfaceProxyTypeWithTargetInterface(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options) + { + AssertValidType(interfaceToProxy); + AssertValidTypes(additionalInterfacesToProxy); + + var generator = new InterfaceProxyWithTargetInterfaceGenerator(scope, interfaceToProxy) { Logger = logger }; + return generator.GenerateCode(interfaceToProxy, additionalInterfacesToProxy, options); + } + + public Type CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options) + { + AssertValidType(interfaceToProxy); + AssertValidTypes(additionalInterfacesToProxy); + + var generator = new InterfaceProxyWithoutTargetGenerator(scope, interfaceToProxy) { Logger = logger }; + return generator.GenerateCode(typeof(object), additionalInterfacesToProxy, options); + } + + private void AssertValidType(Type target) + { + if (target.IsGenericTypeDefinition) + { + throw new GeneratorException("Type " + target.FullName + " is a generic type definition. " + + "Can not create proxy for open generic types."); + } + if (IsPublic(target) == false) + { +#if !SILVERLIGHT + if (IsAccessible(target) == false) + { + throw new GeneratorException("Type " + target.FullName + " is not visible to DynamicProxy. " + + "Can not create proxy for types that are not accessible. " + + "Make the type public, or internal and mark your assembly with " + + "[assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)] attribute."); + } +#else + throw new GeneratorException("Type " + target.FullName + " is not public. " + + "Can not create proxy for types that are not accessible."); +#endif + } + } + + private void AssertValidTypes(IEnumerable targetTypes) + { + if (targetTypes != null) + { + foreach (var t in targetTypes) + { + AssertValidType(t); + } + } + } + +#if !SILVERLIGHT + private bool IsAccessible(Type target) + { + var isTargetNested = target.IsNested; + var isNestedAndInternal = isTargetNested && (target.IsNestedAssembly || target.IsNestedFamORAssem); + var isInternalNotNested = target.IsVisible == false && isTargetNested == false; + + var internalAndVisibleToDynProxy = (isInternalNotNested || isNestedAndInternal) && + InternalsHelper.IsInternalToDynamicProxy(target.Assembly); + return internalAndVisibleToDynProxy; + } +#endif + + private bool IsPublic(Type target) + { + return target.IsPublic || target.IsNestedPublic; + } + } +} \ No newline at end of file Binary files nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\DynProxy.snk and nmock3-62490\MAIN\Source\Castle\DynamicProxy\DynProxy.snk differ diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\AttributeDisassembler.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\AttributeDisassembler.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\AttributeDisassembler.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\AttributeDisassembler.cs Sun Feb 13 20:36:26 2011 @@ -0,0 +1,283 @@ +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + +#if !SILVERLIGHT + [Serializable] +#endif + internal class AttributeDisassembler : IAttributeDisassembler + { + public CustomAttributeBuilder Disassemble(Attribute attribute) + { + Type type = attribute.GetType(); + + try + { + ConstructorInfo ctor; + object[] ctorArgs = GetConstructorAndArgs(type, attribute, out ctor); + var replicated = (Attribute) Activator.CreateInstance(type, ctorArgs); + PropertyInfo[] properties; + object[] propertyValues = GetPropertyValues(type, out properties, attribute, replicated); + FieldInfo[] fields; + object[] fieldValues = GetFieldValues(type, out fields, attribute, replicated); + return new CustomAttributeBuilder(ctor, ctorArgs, properties, propertyValues, fields, fieldValues); + } + catch (Exception ex) + { + // there is no real way to log a warning here... + return HandleError(type,ex); + } + } + + /// + /// Handles error during disassembly process + /// + /// Type of the attribute being disassembled + /// Exception thrown during the process + /// usually null, or (re)throws the exception + protected virtual CustomAttributeBuilder HandleError(Type attributeType, Exception exception) + { + // ouch... + var message = "DynamicProxy was unable to disassemble attribute " + attributeType.Name + + " using default AttributeDisassembler. " + + string.Format("To handle the disassembly process properly implement the {0} interface, ", typeof (IAttributeDisassembler)) + + "and register your disassembler to handle this type of attributes using " + + typeof (AttributeUtil).Name + ".AddDisassembler<" + attributeType.Name + ">(yourDisassembler) method"; + throw new ProxyGenerationException(message, exception); + } + + private static object[] GetConstructorAndArgs(Type attType, Attribute attribute, out ConstructorInfo ci) + { + var ctorArgs = new object[0]; + + ci = attType.GetConstructors()[0]; + + ParameterInfo[] constructorParams = ci.GetParameters(); + + if (constructorParams.Length != 0) + { + ctorArgs = new object[constructorParams.Length]; + + InitializeConstructorArgs(attType, attribute, ctorArgs, constructorParams); + } + + return ctorArgs; + } + + private static object[] GetPropertyValues(Type attType, out PropertyInfo[] properties, Attribute original, + Attribute replicated) + { + List propertyCandidates = GetPropertyCandidates(attType); + + var selectedValues = new List(propertyCandidates.Count); + var selectedProperties = new List(propertyCandidates.Count); + foreach (PropertyInfo property in propertyCandidates) + { + object originalValue = property.GetValue(original, null); + object replicatedValue = property.GetValue(replicated, null); + if (AreAttributeElementsEqual(originalValue, replicatedValue)) + { + //this property has default value so we skip it + continue; + } + + selectedProperties.Add(property); + selectedValues.Add(originalValue); + } + + properties = selectedProperties.ToArray(); + return selectedValues.ToArray(); + } + + private static object[] GetFieldValues(Type attType, out FieldInfo[] fields, Attribute original, Attribute replicated) + { + FieldInfo[] fieldsCandidates = attType.GetFields(BindingFlags.Public | BindingFlags.Instance); + + var selectedValues = new List(fieldsCandidates.Length); + var selectedFields = new List(fieldsCandidates.Length); + foreach (FieldInfo field in fieldsCandidates) + { + object originalValue = field.GetValue(original); + object replicatedValue = field.GetValue(replicated); + if (AreAttributeElementsEqual(originalValue, replicatedValue)) + { + //this field has default value so we skip it + continue; + } + + selectedFields.Add(field); + selectedValues.Add(originalValue); + } + + fields = selectedFields.ToArray(); + return selectedValues.ToArray(); + } + + /// + /// Here we try to match a constructor argument to its value. + /// Since we can't get the values from the assembly, we use some heuristics to get it. + /// a/ we first try to match all the properties on the attributes by name (case insensitive) to the argument + /// b/ if we fail we try to match them by property type, with some smarts about convertions (i,e: can use Guid for string). + /// + private static void InitializeConstructorArgs(Type attType, Attribute attribute, object[] args, + ParameterInfo[] parameterInfos) + { + for (int i = 0; i < args.Length; i++) + { + args[i] = GetArgValue(attType, attribute, parameterInfos[i]); + } + } + + private static object GetArgValue(Type attType, Attribute attribute, ParameterInfo parameterInfo) + { + Type paramType = parameterInfo.ParameterType; + + PropertyInfo[] propertyInfos = attType.GetProperties(); + //first try to find a property with + foreach (PropertyInfo propertyInfo in propertyInfos) + { + if (propertyInfo.CanRead == false && propertyInfo.GetIndexParameters().Length != 0) + { + continue; + } + + if (String.Compare(propertyInfo.Name, parameterInfo.Name, StringComparison.CurrentCultureIgnoreCase) == 0) + { + return ConvertValue(propertyInfo.GetValue(attribute, null), paramType); + } + } + + PropertyInfo bestMatch = null; + //now we try to find it by type + foreach (PropertyInfo propertyInfo in propertyInfos) + { + if (propertyInfo.CanRead == false && propertyInfo.GetIndexParameters().Length != 0) + continue; + bestMatch = ReplaceIfBetterMatch(parameterInfo, propertyInfo, bestMatch); + } + if (bestMatch != null) + { + return ConvertValue(bestMatch.GetValue(attribute, null), paramType); + } + return GetDefaultValueFor(paramType); + } + + /// + /// We have the following rules here. + /// Try to find a matching type, failing that, if the parameter is string, get the first property (under the assumption that + /// we can convert it. + /// + private static PropertyInfo ReplaceIfBetterMatch(ParameterInfo parameterInfo, PropertyInfo propertyInfo, + PropertyInfo bestMatch) + { + bool notBestMatch = bestMatch == null || bestMatch.PropertyType != parameterInfo.ParameterType; + if (propertyInfo.PropertyType == parameterInfo.ParameterType && notBestMatch) + return propertyInfo; + if (parameterInfo.ParameterType == typeof (string) && notBestMatch) + return propertyInfo; + return bestMatch; + } + + /// + /// Attributes can only accept simple types, so we return null for null, + /// if the value is passed as string we call to string (should help with converting), + /// otherwise, we use the value as is (enums, integer, etc). + /// + private static object ConvertValue(object obj, Type paramType) + { + if (obj == null) + return null; + if (paramType == typeof (String)) + return obj.ToString(); + return obj; + } + + private static object GetDefaultValueFor(Type type) + { + if (type == typeof (bool)) + { + return false; + } + if (type.IsEnum) + { +#if SILVERLIGHT + return Castle.DynamicProxy.SilverlightExtensions.EnumHelper.GetValues(type).GetValue(0); +#else + return Enum.GetValues(type).GetValue(0); +#endif + } + if (type == typeof (char)) + { + return Char.MinValue; + } + if (type.IsPrimitive) + { + return 0; + } + + return null; + } + + private static List GetPropertyCandidates(Type attributeType) + { + var propertyCandidates = new List(); + + foreach (PropertyInfo pi in attributeType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + if (pi.CanRead && pi.CanWrite) + { + propertyCandidates.Add(pi); + } + } + + return propertyCandidates; + } + + private static bool AreAttributeElementsEqual(object first, object second) + { + //we can have either System.Type, string or numeric type + if (first == null) + { + return second == null; + } + + //let's try string + var firstString = first as string; + if (firstString != null) + { + return AreStringsEqual(firstString, second as string); + } + + //by now we should only be left with numeric types + return first.Equals(second); + } + + private static bool AreStringsEqual(string first, string second) + { + Debug.Assert(first != null, "first != null"); + return first.Equals(second, StringComparison.Ordinal); + } + + public bool Equals(AttributeDisassembler other) + { + return !ReferenceEquals(null, other); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof (AttributeDisassembler)) return false; + return Equals((AttributeDisassembler) obj); + } + + public override int GetHashCode() + { + return GetType().GetHashCode(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\AttributesToAvoidReplicating.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\AttributesToAvoidReplicating.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\AttributesToAvoidReplicating.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\AttributesToAvoidReplicating.cs Mon Feb 14 13:26:18 2011 @@ -0,0 +1,54 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Runtime.InteropServices; + using System.Security.Permissions; + + // [ILMergeExclude] + internal static class AttributesToAvoidReplicating + { + private static readonly IList attributes = new List(); + + static AttributesToAvoidReplicating() + { + Add(); +#if !SILVERLIGHT + Add(); +#endif +#if DOTNET40 + Add(); +#endif + } + + public static void Add(Type attribute) + { + if (attributes.Contains(attribute) == false) + attributes.Add(attribute); + } + + public static void Add() + { + Add(typeof (T)); + } + + public static bool Contains(Type type) + { + return attributes.Contains(type); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\BaseProxyGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\BaseProxyGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\BaseProxyGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\BaseProxyGenerator.cs Sun Feb 13 20:10:13 2011 @@ -0,0 +1,455 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Reflection; + using System.Runtime.Serialization; +#if !SILVERLIGHT + using System.Xml.Serialization; +#endif + using Castle.Components.DictionaryAdapter; + using Castle.Core.Internal; + using Castle.Core.Logging; + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.CodeBuilders; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + +#if SILVERLIGHT + using Castle.DynamicProxy.SilverlightExtensions; +#endif + + /// + /// Base class that exposes the common functionalities + /// to proxy generation. + /// + internal abstract class BaseProxyGenerator + { + private readonly ModuleScope scope; + + protected readonly Type targetType; + private ILogger logger = NullLogger.Instance; + private ProxyGenerationOptions proxyGenerationOptions; + + protected BaseProxyGenerator(ModuleScope scope, Type targetType) + { + this.scope = scope; + this.targetType = targetType; + } + + public ILogger Logger + { + get { return logger; } + set { logger = value; } + } + + protected ProxyGenerationOptions ProxyGenerationOptions + { + get + { + if (proxyGenerationOptions == null) + { + throw new InvalidOperationException("ProxyGenerationOptions must be set before being retrieved."); + } + return proxyGenerationOptions; + } + set + { + if (proxyGenerationOptions != null) + { + throw new InvalidOperationException("ProxyGenerationOptions can only be set once."); + } + proxyGenerationOptions = value; + } + } + + protected ModuleScope Scope + { + get { return scope; } + } + + protected FieldReference CreateOptionsField(ClassEmitter emitter) + { + return emitter.CreateStaticField("proxyGenerationOptions", typeof(ProxyGenerationOptions)); + } + + protected void InitializeStaticFields(Type builtType) + { + builtType.SetStaticField("proxyGenerationOptions", BindingFlags.Public, ProxyGenerationOptions); + } + + protected void CheckNotGenericTypeDefinition(Type type, string argumentName) + { + if (type != null && type.IsGenericTypeDefinition) + { + throw new ArgumentException("Type cannot be a generic type definition. Type: " + type.FullName, argumentName); + } + } + + protected void CheckNotGenericTypeDefinitions(IEnumerable types, string argumentName) + { + if (types == null) return; + foreach (var t in types) + { + CheckNotGenericTypeDefinition(t, argumentName); + } + } + + protected virtual ClassEmitter BuildClassEmitter(string typeName, Type parentType, IEnumerable interfaces) + { + CheckNotGenericTypeDefinition(parentType, "parentType"); + CheckNotGenericTypeDefinitions(interfaces, "interfaces"); + + return new ClassEmitter(Scope, typeName, parentType, interfaces); + } + + protected void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor, + params FieldReference[] fields) + { + ArgumentReference[] args; + ParameterInfo[] baseConstructorParams = null; + + if (baseConstructor != null) + { + baseConstructorParams = baseConstructor.GetParameters(); + } + + if (baseConstructorParams != null && baseConstructorParams.Length != 0) + { + args = new ArgumentReference[fields.Length + baseConstructorParams.Length]; + + var offset = fields.Length; + for (var i = offset; i < offset + baseConstructorParams.Length; i++) + { + var paramInfo = baseConstructorParams[i - offset]; + args[i] = new ArgumentReference(paramInfo.ParameterType); + } + } + else + { + args = new ArgumentReference[fields.Length]; + } + + for (var i = 0; i < fields.Length; i++) + { + args[i] = new ArgumentReference(fields[i].Reference.FieldType); + } + + var constructor = emitter.CreateConstructor(args); + if(baseConstructorParams != null && baseConstructorParams.Length != 0) + { + var last = baseConstructorParams.Last(); + if (last.ParameterType.IsArray && last.HasAttribute()) + { + var parameter = constructor.ConstructorBuilder.DefineParameter(args.Length, ParameterAttributes.None, last.Name); + var builder = AttributeUtil.CreateBuilder(); + parameter.SetCustomAttribute(builder); + } + } + + for (var i = 0; i < fields.Length; i++) + { + constructor.CodeBuilder.AddStatement(new AssignStatement(fields[i], args[i].ToExpression())); + } + + // Invoke base constructor + + if (baseConstructor != null) + { + Debug.Assert(baseConstructorParams != null); + + var slice = new ArgumentReference[baseConstructorParams.Length]; + Array.Copy(args, fields.Length, slice, 0, baseConstructorParams.Length); + + constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, slice); + } + else + { + constructor.CodeBuilder.InvokeBaseConstructor(); + } + + constructor.CodeBuilder.AddStatement(new ReturnStatement()); + } + + /// + /// Generates a parameters constructor that initializes the proxy + /// state with just to make it non-null. + /// + /// This constructor is important to allow proxies to be XML serializable + /// + /// + protected void GenerateParameterlessConstructor(ClassEmitter emitter, Type baseClass, FieldReference interceptorField) + { + // Check if the type actually has a default constructor + var defaultConstructor = baseClass.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, + null); + + if (defaultConstructor == null) + { + defaultConstructor = baseClass.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, + null); + + if (defaultConstructor == null || defaultConstructor.IsPrivate) + { + return; + } + } + + var constructor = emitter.CreateConstructor(); + + // initialize fields with an empty interceptor + + constructor.CodeBuilder.AddStatement(new AssignStatement(interceptorField, + new NewArrayExpression(1, typeof(IInterceptor)))); + constructor.CodeBuilder.AddStatement( + new AssignArrayStatement(interceptorField, 0, new NewInstanceExpression(typeof(StandardInterceptor), new Type[0]))); + + // Invoke base constructor + + constructor.CodeBuilder.InvokeBaseConstructor(defaultConstructor); + + constructor.CodeBuilder.AddStatement(new ReturnStatement()); + } + + protected void EnsureOptionsOverrideEqualsAndGetHashCode(ProxyGenerationOptions options) + { + if (Logger.IsWarnEnabled) + { + // Check the proxy generation hook + if (!OverridesEqualsAndGetHashCode(options.Hook.GetType())) + { + Logger.Warn("The IProxyGenerationHook type {0} does not override both Equals and GetHashCode. " + + "If these are not correctly overridden caching will fail to work causing performance problems.", + options.Hook.GetType().FullName); + } + + // Interceptor selectors no longer need to override Equals and GetHashCode + } + } + + private bool OverridesEqualsAndGetHashCode(Type type) + { + var equalsMethod = type.GetMethod("Equals", BindingFlags.Public | BindingFlags.Instance); + if (equalsMethod == null || equalsMethod.DeclaringType == typeof(object) || equalsMethod.IsAbstract) + { + return false; + } + + var getHashCodeMethod = type.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance); + if (getHashCodeMethod == null || getHashCodeMethod.DeclaringType == typeof(object) || getHashCodeMethod.IsAbstract) + { + return false; + } + + return true; + } + + protected void AddMapping(Type @interface, ITypeContributor implementer, IDictionary mapping) + { + Debug.Assert(implementer != null, "implementer != null"); + Debug.Assert(@interface != null, "@interface != null"); + Debug.Assert(@interface.IsInterface, "@interface.IsInterface"); + + if (!mapping.ContainsKey(@interface)) + { + AddMappingNoCheck(@interface, implementer, mapping); + } + } + + /// + /// It is safe to add mapping (no mapping for the interface exists) + /// + /// + /// + /// + protected void AddMappingNoCheck(Type @interface, ITypeContributor implementer, + IDictionary mapping) + { + mapping.Add(@interface, implementer); + } + + protected void AddMappingForISerializable(IDictionary typeImplementerMapping, + ITypeContributor instance) + { +#if !SILVERLIGHT + AddMapping(typeof(ISerializable), instance, typeImplementerMapping); +#endif + } + + protected void HandleExplicitlyPassedProxyTargetAccessor(ICollection targetInterfaces, + ICollection additionalInterfaces) + { + var interfaceName = typeof(IProxyTargetAccessor).ToString(); + //ok, let's determine who tried to sneak the IProxyTargetAccessor in... + string message; + if (targetInterfaces.Contains(typeof(IProxyTargetAccessor))) + { + message = + string.Format( + "Target type for the proxy implements {0} which is a DynamicProxy infrastructure interface and you should never implement it yourself. Are you trying to proxy an existing proxy?", + interfaceName); + } + else if (ProxyGenerationOptions.MixinData.ContainsMixin(typeof(IProxyTargetAccessor))) + { + var mixinType = ProxyGenerationOptions.MixinData.GetMixinInstance(typeof(IProxyTargetAccessor)).GetType(); + message = + string.Format( + "Mixin type {0} implements {1} which is a DynamicProxy infrastructure interface and you should never implement it yourself. Are you trying to mix in an existing proxy?", + mixinType.Name, interfaceName); + } + else if (additionalInterfaces.Contains(typeof(IProxyTargetAccessor))) + { + message = + string.Format( + "You passed {0} as one of additional interfaces to proxy which is a DynamicProxy infrastructure interface and is implemented by every proxy anyway. Please remove it from the list of additional interfaces to proxy.", + interfaceName); + } + else + { + // this can technicaly never happen + message = string.Format("It looks like we have a bug with regards to how we handle {0}. Please report it.", + interfaceName); + } + throw new ProxyGenerationException("This is a DynamicProxy2 error: " + message); + } + + protected void CreateInterceptorsField(ClassEmitter emitter) + { + var interceptorsField = emitter.CreateField("__interceptors", typeof(IInterceptor[])); + +#if !SILVERLIGHT + emitter.DefineCustomAttributeFor(interceptorsField); +#endif + } + + protected void CreateSelectorField(ClassEmitter emitter) + { + if (ProxyGenerationOptions.Selector == null) + { + return; + } + + emitter.CreateField("__selector", typeof(IInterceptorSelector)); + return; + } + + protected virtual void CreateTypeAttributes(ClassEmitter emitter) + { + emitter.AddCustomAttributes(ProxyGenerationOptions); +#if !SILVERLIGHT + emitter.DefineCustomAttribute(new object[] {targetType}); +#endif + } + + protected virtual void CreateFields(ClassEmitter emitter) + { + CreateOptionsField(emitter); + CreateSelectorField(emitter); + CreateInterceptorsField(emitter); + } + + protected Type ObtainProxyType(CacheKey cacheKey, Func factory) + { + using (var locker = Scope.Lock.ForReadingUpgradeable()) + { + var cacheType = GetFromCache(cacheKey); + if (cacheType != null) + { + Logger.Debug("Found cached proxy type {0} for target type {1}.", cacheType.FullName, targetType.FullName); + return cacheType; + } + + // Upgrade the lock to a write lock, then read again. This is to avoid generating duplicate types + // under heavy multithreaded load. + locker.Upgrade(); + + cacheType = GetFromCache(cacheKey); + if (cacheType != null) + { + Logger.Debug("Found cached proxy type {0} for target type {1}.", cacheType.FullName, targetType.FullName); + return cacheType; + } + + // Log details about the cache miss + Logger.Debug("No cached proxy type was found for target type {0}.", targetType.FullName); + EnsureOptionsOverrideEqualsAndGetHashCode(ProxyGenerationOptions); + + + var name = Scope.NamingScope.GetUniqueName("Castle.Proxies." + targetType.Name + "Proxy"); + var proxyType = factory.Invoke(name, Scope.NamingScope.SafeSubScope()); + + AddToCache(cacheKey, proxyType); + return proxyType; + } + } + + #region Type tokens related operations + + protected void GenerateConstructors(ClassEmitter emitter, Type baseType, params FieldReference[] fields) + { + var constructors = + baseType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + + foreach (var constructor in constructors) + { + if (!IsConstructorVisible(constructor)) continue; + + GenerateConstructor(emitter, constructor, fields); + } + } + + private bool IsConstructorVisible(ConstructorInfo constructor) + { + return constructor.IsPublic + || constructor.IsFamily + || constructor.IsFamilyOrAssembly +#if !Silverlight + || (constructor.IsAssembly && InternalsHelper.IsInternalToDynamicProxy(constructor.DeclaringType.Assembly)); +#else + ; +#endif + } + + protected ConstructorEmitter GenerateStaticConstructor(ClassEmitter emitter) + { + return emitter.CreateTypeConstructor(); + } + + protected void CompleteInitCacheMethod(ConstructorCodeBuilder constCodeBuilder) + { + constCodeBuilder.AddStatement(new ReturnStatement()); + } + + #endregion + + #region Cache related + + protected Type GetFromCache(CacheKey key) + { + return scope.GetFromCache(key); + } + + protected void AddToCache(CacheKey key, Type type) + { + scope.RegisterInCache(key, type); + } + + #endregion + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\CacheKey.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\CacheKey.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\CacheKey.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\CacheKey.cs Sun Feb 13 20:09:15 2011 @@ -0,0 +1,88 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Reflection; + +#if !SILVERLIGHT + [Serializable] +#endif + internal class CacheKey + { + private readonly MemberInfo target; + private readonly Type[] interfaces; + private readonly ProxyGenerationOptions options; + private readonly Type type; + + /// + /// Initializes a new instance of the class. + /// + /// Target element. This is either target type or target method for invocation types. + /// The type of the proxy. This is base type for invocation types. + /// The interfaces. + /// The options. + public CacheKey(MemberInfo target, Type type, Type[] interfaces, ProxyGenerationOptions options) + { + this.target = target; + this.type = type; + this.interfaces = interfaces ?? Type.EmptyTypes; + this.options = options; + } + + /// + /// Initializes a new instance of the class. + /// + /// Type of the target. + /// The interfaces. + /// The options. + public CacheKey(Type target, Type[] interfaces, ProxyGenerationOptions options) + : this(target, null, interfaces, options) + { + } + + public override int GetHashCode() + { + int result = target.GetHashCode(); + foreach (Type inter in interfaces) + { + result += 29 + inter.GetHashCode(); + } + if (options != null) + result = 29*result + options.GetHashCode(); + if (type != null) + result = 29*result + type.GetHashCode(); + return result; + } + + public override bool Equals(object obj) + { + if (this == obj) return true; + + CacheKey cacheKey = obj as CacheKey; + if (cacheKey == null) return false; + + if (!Equals(type, cacheKey.type)) return false; + if (!Equals(target, cacheKey.target)) return false; + if (interfaces.Length != cacheKey.interfaces.Length) return false; + for (int i = 0; i < interfaces.Length; i++) + { + if (!Equals(interfaces[i], cacheKey.interfaces[i])) return false; + } + if (!Equals(options, cacheKey.options)) return false; + return true; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyGenerator.cs Sun Feb 13 20:07:43 2011 @@ -0,0 +1,202 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Serialization; + + internal class ClassProxyGenerator : BaseProxyGenerator + { + public ClassProxyGenerator(ModuleScope scope, Type targetType) : base(scope, targetType) + { + CheckNotGenericTypeDefinition(targetType, "targetType"); + EnsureDoesNotImplementIProxyTargetAccessor(targetType, "targetType"); + } + + private void EnsureDoesNotImplementIProxyTargetAccessor(Type type, string name) + { + if (!typeof (IProxyTargetAccessor).IsAssignableFrom(type)) + { + return; + } + var message = + string.Format( + "Target type for the proxy implements {0} which is a DynamicProxy infrastructure interface and you should never implement it yourself. Are you trying to proxy an existing proxy?", + typeof (IProxyTargetAccessor)); + throw new ArgumentException(message, name); + } + + public Type GenerateCode(Type[] interfaces, ProxyGenerationOptions options) + { + // make sure ProxyGenerationOptions is initialized + options.Initialize(); + + interfaces = TypeUtil.GetAllInterfaces(interfaces).ToArray(); + CheckNotGenericTypeDefinitions(interfaces, "interfaces"); + ProxyGenerationOptions = options; + var cacheKey = new CacheKey(targetType, interfaces, options); + return ObtainProxyType(cacheKey, (n, s) => GenerateType(n, interfaces, s)); + } + + protected virtual Type GenerateType(string name, Type[] interfaces, INamingScope namingScope) + { + IEnumerable contributors; + var implementedInterfaces = GetTypeImplementerMapping(interfaces, out contributors, namingScope); + + var model = new MetaType(); + // Collect methods + foreach (var contributor in contributors) + { + contributor.CollectElementsToProxy(ProxyGenerationOptions.Hook, model); + } + ProxyGenerationOptions.Hook.MethodsInspected(); + + var emitter = BuildClassEmitter(name, targetType, implementedInterfaces); + + CreateFields(emitter); + CreateTypeAttributes(emitter); + + + // Constructor + var cctor = GenerateStaticConstructor(emitter); + + var constructorArguments = new List(); + foreach (var contributor in contributors) + { + contributor.Generate(emitter, ProxyGenerationOptions); + + // TODO: redo it + if (contributor is MixinContributor) + { + constructorArguments.AddRange((contributor as MixinContributor).Fields); + } + } + + // constructor arguments + var interceptorsField = emitter.GetField("__interceptors"); + constructorArguments.Add(interceptorsField); + var selector = emitter.GetField("__selector"); + if (selector != null) + { + constructorArguments.Add(selector); + } + + GenerateConstructors(emitter, targetType, constructorArguments.ToArray()); + GenerateParameterlessConstructor(emitter, targetType, interceptorsField); + + // Complete type initializer code body + CompleteInitCacheMethod(cctor.CodeBuilder); + + // Crosses fingers and build type + + Type proxyType = emitter.BuildType(); + InitializeStaticFields(proxyType); + return proxyType; + } + + protected virtual IEnumerable GetTypeImplementerMapping(Type[] interfaces, out IEnumerable contributors, INamingScope namingScope) + { + var methodsToSkip = new List(); + var proxyInstance = new ClassProxyInstanceContributor(targetType, methodsToSkip, interfaces, ProxyTypeConstants.Class); + // TODO: the trick with methodsToSkip is not very nice... + var proxyTarget = new ClassProxyTargetContributor(targetType, methodsToSkip, namingScope) { Logger = Logger }; + IDictionary typeImplementerMapping = new Dictionary(); + + // Order of interface precedence: + // 1. first target + // target is not an interface so we do nothing + + var targetInterfaces = targetType.GetAllInterfaces(); + var additionalInterfaces = TypeUtil.GetAllInterfaces(interfaces); + // 2. then mixins + var mixins = new MixinContributor(namingScope, false) { Logger = Logger }; + if (ProxyGenerationOptions.HasMixins) + { + foreach (var mixinInterface in ProxyGenerationOptions.MixinData.MixinInterfaces) + { + if (targetInterfaces.Contains(mixinInterface)) + { + // OK, so the target implements this interface. We now do one of two things: + if (additionalInterfaces.Contains(mixinInterface) && typeImplementerMapping.ContainsKey(mixinInterface) == false) + { + AddMappingNoCheck(mixinInterface, proxyTarget, typeImplementerMapping); + proxyTarget.AddInterfaceToProxy(mixinInterface); + } + // we do not intercept the interface + mixins.AddEmptyInterface(mixinInterface); + } + else + { + if (!typeImplementerMapping.ContainsKey(mixinInterface)) + { + mixins.AddInterfaceToProxy(mixinInterface); + AddMappingNoCheck(mixinInterface, mixins, typeImplementerMapping); + } + } + } + } + var additionalInterfacesContributor = new InterfaceProxyWithoutTargetContributor(namingScope, + (c, m) => NullExpression.Instance) + { Logger = Logger }; + // 3. then additional interfaces + foreach (var @interface in additionalInterfaces) + { + if (targetInterfaces.Contains(@interface)) + { + if (typeImplementerMapping.ContainsKey(@interface)) continue; + + // we intercept the interface, and forward calls to the target type + AddMappingNoCheck(@interface, proxyTarget, typeImplementerMapping); + proxyTarget.AddInterfaceToProxy(@interface); + } + else if (ProxyGenerationOptions.MixinData.ContainsMixin(@interface) == false) + { + additionalInterfacesContributor.AddInterfaceToProxy(@interface); + AddMapping(@interface, additionalInterfacesContributor, typeImplementerMapping); + } + } +#if !SILVERLIGHT + // 4. plus special interfaces + if (targetType.IsSerializable) + { + AddMappingForISerializable(typeImplementerMapping, proxyInstance); + } +#endif + try + { + AddMappingNoCheck(typeof(IProxyTargetAccessor), proxyInstance, typeImplementerMapping); + } + catch (ArgumentException ) + { + HandleExplicitlyPassedProxyTargetAccessor(targetInterfaces, additionalInterfaces); + } + + contributors = new List + { + proxyTarget, + mixins, + additionalInterfacesContributor, + proxyInstance + }; + return typeImplementerMapping.Keys; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyWithTargetGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyWithTargetGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyWithTargetGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\ClassProxyWithTargetGenerator.cs Sun Feb 13 20:08:36 2011 @@ -0,0 +1,214 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using System.Xml.Serialization; + + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Serialization; + + internal class ClassProxyWithTargetGenerator : BaseProxyGenerator + { + private readonly Type[] additionalInterfacesToProxy; + + public ClassProxyWithTargetGenerator(ModuleScope scope, Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) + : base(scope, classToProxy) + { + CheckNotGenericTypeDefinition(targetType, "targetType"); + EnsureDoesNotImplementIProxyTargetAccessor(targetType, "targetType"); + CheckNotGenericTypeDefinitions(additionalInterfacesToProxy, "additionalInterfacesToProxy"); + + options.Initialize(); + ProxyGenerationOptions = options; + this.additionalInterfacesToProxy = TypeUtil.GetAllInterfaces(additionalInterfacesToProxy).ToArray(); + } + + private void EnsureDoesNotImplementIProxyTargetAccessor(Type type, string name) + { + if (!typeof(IProxyTargetAccessor).IsAssignableFrom(type)) + { + return; + } + var message = + string.Format( + "Target type for the proxy implements {0} which is a DynamicProxy infrastructure interface and you should never implement it yourself. Are you trying to proxy an existing proxy?", + typeof (IProxyTargetAccessor)); + throw new ArgumentException(message, name); + } + + public Type GetGeneratedType() + { + var cacheKey = new CacheKey(targetType, additionalInterfacesToProxy, ProxyGenerationOptions); + return ObtainProxyType(cacheKey, GenerateType); + } + + private Type GenerateType(string name, INamingScope namingScope) + { + IEnumerable contributors; + var implementedInterfaces = GetTypeImplementerMapping(out contributors, namingScope); + + var model = new MetaType(); + // Collect methods + foreach (var contributor in contributors) + { + contributor.CollectElementsToProxy(ProxyGenerationOptions.Hook, model); + } + ProxyGenerationOptions.Hook.MethodsInspected(); + + var emitter = BuildClassEmitter(name, targetType, implementedInterfaces); + + CreateFields(emitter); + CreateTypeAttributes(emitter); + + + // Constructor + var cctor = GenerateStaticConstructor(emitter); + + var targetField = CreateTargetField(emitter); + var constructorArguments = new List { targetField }; + + foreach (var contributor in contributors) + { + contributor.Generate(emitter, ProxyGenerationOptions); + + // TODO: redo it + if (contributor is MixinContributor) + { + constructorArguments.AddRange((contributor as MixinContributor).Fields); + } + } + + // constructor arguments + var interceptorsField = emitter.GetField("__interceptors"); + constructorArguments.Add(interceptorsField); + var selector = emitter.GetField("__selector"); + if (selector != null) + { + constructorArguments.Add(selector); + } + + GenerateConstructors(emitter, targetType, constructorArguments.ToArray()); + GenerateParameterlessConstructor(emitter, targetType, interceptorsField); + + // Complete type initializer code body + CompleteInitCacheMethod(cctor.CodeBuilder); + + // Crosses fingers and build type + + Type proxyType = emitter.BuildType(); + InitializeStaticFields(proxyType); + return proxyType; + } + + protected virtual IEnumerable GetTypeImplementerMapping(out IEnumerable contributors, INamingScope namingScope) + { + var methodsToSkip = new List(); + var proxyInstance = new ClassProxyInstanceContributor(targetType, methodsToSkip, additionalInterfacesToProxy, ProxyTypeConstants.ClassWithTarget); + // TODO: the trick with methodsToSkip is not very nice... + var proxyTarget = new ClassProxyWithTargetTargetContributor(targetType, methodsToSkip, namingScope) { Logger = Logger }; + IDictionary typeImplementerMapping = new Dictionary(); + + // Order of interface precedence: + // 1. first target + // target is not an interface so we do nothing + + var targetInterfaces = targetType.GetAllInterfaces(); + // 2. then mixins + var mixins = new MixinContributor(namingScope, false) { Logger = Logger }; + if (ProxyGenerationOptions.HasMixins) + { + foreach (var mixinInterface in ProxyGenerationOptions.MixinData.MixinInterfaces) + { + if (targetInterfaces.Contains(mixinInterface)) + { + // OK, so the target implements this interface. We now do one of two things: + if (additionalInterfacesToProxy.Contains(mixinInterface) && typeImplementerMapping.ContainsKey(mixinInterface) == false) + { + AddMappingNoCheck(mixinInterface, proxyTarget, typeImplementerMapping); + proxyTarget.AddInterfaceToProxy(mixinInterface); + } + // we do not intercept the interface + mixins.AddEmptyInterface(mixinInterface); + } + else + { + if (!typeImplementerMapping.ContainsKey(mixinInterface)) + { + mixins.AddInterfaceToProxy(mixinInterface); + AddMappingNoCheck(mixinInterface, mixins, typeImplementerMapping); + } + } + } + } + var additionalInterfacesContributor = new InterfaceProxyWithoutTargetContributor(namingScope, + (c, m) => NullExpression.Instance) { Logger = Logger }; + // 3. then additional interfaces + foreach (var @interface in additionalInterfacesToProxy) + { + if (targetInterfaces.Contains(@interface)) + { + if (typeImplementerMapping.ContainsKey(@interface)) continue; + + // we intercept the interface, and forward calls to the target type + AddMappingNoCheck(@interface, proxyTarget, typeImplementerMapping); + proxyTarget.AddInterfaceToProxy(@interface); + } + else if (ProxyGenerationOptions.MixinData.ContainsMixin(@interface) == false) + { + additionalInterfacesContributor.AddInterfaceToProxy(@interface); + AddMapping(@interface, additionalInterfacesContributor, typeImplementerMapping); + } + } +#if !SILVERLIGHT + // 4. plus special interfaces + if (targetType.IsSerializable) + { + AddMappingForISerializable(typeImplementerMapping, proxyInstance); + } +#endif + try + { + AddMappingNoCheck(typeof(IProxyTargetAccessor), proxyInstance, typeImplementerMapping); + } + catch (ArgumentException) + { + HandleExplicitlyPassedProxyTargetAccessor(targetInterfaces, additionalInterfacesToProxy); + } + + contributors = new List + { + proxyTarget, + mixins, + additionalInterfacesContributor, + proxyInstance + }; + return typeImplementerMapping.Keys; + } + + + private FieldReference CreateTargetField(ClassEmitter emitter) + { + var targetField = emitter.CreateField("__target", targetType); + emitter.DefineCustomAttributeFor(targetField); + return targetField; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\CompositionInvocationTypeGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\CompositionInvocationTypeGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\CompositionInvocationTypeGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\CompositionInvocationTypeGenerator.cs Sun Feb 13 20:08:30 2011 @@ -0,0 +1,79 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class CompositionInvocationTypeGenerator : InvocationTypeGenerator + { + public static readonly Type BaseType = typeof(CompositionInvocation); + + public CompositionInvocationTypeGenerator(Type target, MetaMethod method, MethodInfo callback, bool canChangeTarget, IInvocationCreationContributor contributor) + : base(target, method, callback, canChangeTarget, contributor) + { + } + + protected override FieldReference GetTargetReference() + { + return new FieldReference(InvocationMethods.Target); + } + + protected override Type GetBaseType() + { + return BaseType; + } + + protected override void ImplementInvokeMethodOnTarget(AbstractTypeEmitter invocation, ParameterInfo[] parameters, MethodEmitter invokeMethodOnTarget, Reference targetField) + { + invokeMethodOnTarget.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression(SelfReference.Self, InvocationMethods.EnsureValidTarget))); + base.ImplementInvokeMethodOnTarget(invocation, parameters, invokeMethodOnTarget, targetField); + } + + protected override ArgumentReference[] GetBaseCtorArguments(Type targetFieldType, ProxyGenerationOptions proxyGenerationOptions, out ConstructorInfo baseConstructor) + { + if (proxyGenerationOptions.Selector == null) + { + baseConstructor = InvocationMethods.CompositionInvocationConstructorNoSelector; + return new[] + { + new ArgumentReference(targetFieldType), + new ArgumentReference(typeof(object)), + new ArgumentReference(typeof(IInterceptor[])), + new ArgumentReference(typeof(MethodInfo)), + new ArgumentReference(typeof(object[])), + }; + } + + baseConstructor = InvocationMethods.CompositionInvocationConstructorWithSelector; + return new[] + { + new ArgumentReference(targetFieldType), + new ArgumentReference(typeof(object)), + new ArgumentReference(typeof(IInterceptor[])), + new ArgumentReference(typeof(MethodInfo)), + new ArgumentReference(typeof(object[])), + new ArgumentReference(typeof(IInterceptorSelector)), + new ArgumentReference(typeof(IInterceptor[]).MakeByRefType()) + }; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\DelegateMembersCollector.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\DelegateMembersCollector.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\DelegateMembersCollector.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\DelegateMembersCollector.cs Sun Feb 13 20:13:48 2011 @@ -0,0 +1,39 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Reflection; + using Castle.DynamicProxy.Contributors; + + internal class DelegateMembersCollector : MembersCollector + { + public DelegateMembersCollector(Type type) : base(type) + { + } + + protected override MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone) + { + var accepted = AcceptMethod(method, true, hook); + if (accepted == false) + { + //we don't need to do anything... + return null; + } + + return new MetaMethod(method, method, isStandalone, true, !method.IsAbstract); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerationHook.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerationHook.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerationHook.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerationHook.cs Sun Feb 13 20:36:50 2011 @@ -0,0 +1,50 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Reflection; + + internal class DelegateProxyGenerationHook : IProxyGenerationHook + { + #region IProxyGenerationHook Members + + public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo) + { + return methodInfo.Name.Equals("Invoke"); + } + + public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo) + { + } + + public void MethodsInspected() + { + } + + #endregion + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj.GetType() == typeof (DelegateProxyGenerationHook); + } + + public override int GetHashCode() + { + return GetType().GetHashCode(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\DelegateProxyGenerator.cs Sun Feb 13 20:07:35 2011 @@ -0,0 +1,130 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Reflection; + using System.Xml.Serialization; + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Serialization; + + internal class DelegateProxyGenerator : BaseProxyGenerator + { + public DelegateProxyGenerator(ModuleScope scope, Type delegateType) : base(scope, delegateType) + { + ProxyGenerationOptions = new ProxyGenerationOptions(new DelegateProxyGenerationHook()); + ProxyGenerationOptions.Initialize(); + } + + public Type GetProxyType() + { + var cacheKey = new CacheKey(targetType, null, null); + return ObtainProxyType(cacheKey, GenerateType); + } + + + private Type GenerateType(string name, INamingScope namingScope) + { + IEnumerable contributors; + var implementedInterfaces = GetTypeImplementerMapping(out contributors, namingScope); + + var model = new MetaType(); + // Collect methods + foreach (var contributor in contributors) + { + contributor.CollectElementsToProxy(ProxyGenerationOptions.Hook, model); + } + ProxyGenerationOptions.Hook.MethodsInspected(); + + var emitter = BuildClassEmitter(name, typeof (object), implementedInterfaces); + + CreateFields(emitter); + CreateTypeAttributes(emitter); + + // Constructor + var cctor = GenerateStaticConstructor(emitter); + + var targetField = CreateTargetField(emitter); + var constructorArguments = new List {targetField}; + + foreach (var contributor in contributors) + { + contributor.Generate(emitter, ProxyGenerationOptions); + } + + // constructor arguments + var interceptorsField = emitter.GetField("__interceptors"); + constructorArguments.Add(interceptorsField); + var selector = emitter.GetField("__selector"); + if (selector != null) + { + constructorArguments.Add(selector); + } + + GenerateConstructor(emitter, null, constructorArguments.ToArray()); + GenerateParameterlessConstructor(emitter, targetType, interceptorsField); + + // Complete type initializer code body + CompleteInitCacheMethod(cctor.CodeBuilder); + + // Crosses fingers and build type + + var proxyType = emitter.BuildType(); + InitializeStaticFields(proxyType); + return proxyType; + } + + protected virtual IEnumerable GetTypeImplementerMapping(out IEnumerable contributors, + INamingScope namingScope) + { + var methodsToSkip = new List(); + var proxyInstance = new ClassProxyInstanceContributor(targetType, methodsToSkip, Type.EmptyTypes, + ProxyTypeConstants.ClassWithTarget); + var proxyTarget = new DelegateProxyTargetContributor(targetType, namingScope) {Logger = Logger}; + IDictionary typeImplementerMapping = new Dictionary(); + + // Order of interface precedence: + // 1. first target, target is not an interface so we do nothing + // 2. then mixins - we support none so we do nothing + // 3. then additional interfaces - we support none so we do nothing +#if !SILVERLIGHT + // 4. plus special interfaces + if (targetType.IsSerializable) + { + AddMappingForISerializable(typeImplementerMapping, proxyInstance); + } +#endif + AddMappingNoCheck(typeof (IProxyTargetAccessor), proxyInstance, typeImplementerMapping); + + contributors = new List + { + proxyTarget, + proxyInstance + }; + return typeImplementerMapping.Keys; + } + + + private FieldReference CreateTargetField(ClassEmitter emitter) + { + var targetField = emitter.CreateField("__target", targetType); + emitter.DefineCustomAttributeFor(targetField); + return targetField; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\AbstractTypeEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\AbstractTypeEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\AbstractTypeEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\AbstractTypeEmitter.cs Sun Feb 13 20:11:59 2011 @@ -0,0 +1,374 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal abstract class AbstractTypeEmitter + { + private const MethodAttributes defaultAttributes = MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public; + private readonly TypeBuilder typebuilder; + private readonly ConstructorCollection constructors; + private readonly MethodCollection methods; + private readonly PropertiesCollection properties; + private readonly EventCollection events; + private readonly NestedClassCollection nested; + private readonly Dictionary name2GenericType; + + private GenericTypeParameterBuilder[] genericTypeParams; + + private readonly IDictionary fields = + new Dictionary(StringComparer.OrdinalIgnoreCase); + + protected AbstractTypeEmitter(TypeBuilder typeBuilder) + { + typebuilder = typeBuilder; + nested = new NestedClassCollection(); + methods = new MethodCollection(); + constructors = new ConstructorCollection(); + properties = new PropertiesCollection(); + events = new EventCollection(); + name2GenericType = new Dictionary(); + } + + public Type GetGenericArgument(String genericArgumentName) + { + return name2GenericType[genericArgumentName]; + } + + public Type[] GetGenericArgumentsFor(Type genericType) + { + List types = new List(); + + foreach (Type genType in genericType.GetGenericArguments()) + { + if (genType.IsGenericParameter) + { + types.Add(name2GenericType[genType.Name]); + } + else + { + types.Add(genType); + } + } + + return types.ToArray(); + } + + public Type[] GetGenericArgumentsFor(MethodInfo genericMethod) + { + List types = new List(); + foreach (Type genType in genericMethod.GetGenericArguments()) + { + types.Add(name2GenericType[genType.Name]); + } + + return types.ToArray(); + } + + public void AddCustomAttributes(ProxyGenerationOptions proxyGenerationOptions) + { + foreach (Attribute attr in proxyGenerationOptions.attributesToAddToGeneratedTypes) + { + var customAttributeBuilder = AttributeUtil.CreateBuilder(attr); + if (customAttributeBuilder != null) + { + typebuilder.SetCustomAttribute(customAttributeBuilder); + } + } + + foreach (var attribute in proxyGenerationOptions.AdditionalAttributes) + { + typebuilder.SetCustomAttribute(attribute); + } + } + + public void CreateDefaultConstructor() + { + if (TypeBuilder.IsInterface) + throw new InvalidOperationException ("Interfaces cannot have constructors."); + + constructors.Add(new ConstructorEmitter(this)); + } + + public ConstructorEmitter CreateConstructor(params ArgumentReference[] arguments) + { + if (TypeBuilder.IsInterface) + throw new InvalidOperationException ("Interfaces cannot have constructors."); + + var member = new ConstructorEmitter(this, arguments); + constructors.Add(member); + return member; + } + + public ConstructorEmitter CreateTypeConstructor() + { + var member = new TypeConstructorEmitter(this); + constructors.Add(member); + ClassConstructor = member; + return member; + } + + public TypeConstructorEmitter ClassConstructor { get; private set; } + + public MethodEmitter CreateMethod(string name, MethodAttributes attrs, Type returnType, params Type[] argumentTypes) + { + var member = new MethodEmitter(this, name, attrs, returnType, argumentTypes ?? Type.EmptyTypes); + methods.Add(member); + return member; + } + + public MethodEmitter CreateMethod(string name, Type returnType, params Type[] parameterTypes) + { + return CreateMethod(name, defaultAttributes, returnType, parameterTypes); + } + + public MethodEmitter CreateMethod(string name, MethodInfo methodToUseAsATemplate) + { + return CreateMethod(name, defaultAttributes, methodToUseAsATemplate); + } + + public MethodEmitter CreateMethod(string name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate) + { + var method = new MethodEmitter(this, name, attributes, methodToUseAsATemplate); + methods.Add(method); + return method; + } + + public FieldReference CreateStaticField(string name, Type fieldType) + { + return CreateStaticField(name, fieldType, FieldAttributes.Public); + } + + public FieldReference CreateStaticField(string name, Type fieldType, FieldAttributes atts) + { + atts |= FieldAttributes.Static; + return CreateField(name, fieldType, atts); + } + + public FieldReference CreateField(string name, Type fieldType) + { + return CreateField(name, fieldType, true); + } + + public FieldReference CreateField(string name, Type fieldType, bool serializable) + { + FieldAttributes atts = FieldAttributes.Public; + + if (!serializable) + { + atts |= FieldAttributes.NotSerialized; + } + + return CreateField(name, fieldType, atts); + } + + public FieldReference CreateField(string name, Type fieldType, FieldAttributes atts) + { + FieldBuilder fieldBuilder = typebuilder.DefineField(name, fieldType, atts); + var reference = new FieldReference(fieldBuilder); + fields[name] = reference; + return reference; + } + + public PropertyEmitter CreateProperty(string name, PropertyAttributes attributes, Type propertyType, Type[] arguments) + { + PropertyEmitter propEmitter = new PropertyEmitter(this, name, attributes, propertyType, arguments); + properties.Add(propEmitter); + return propEmitter; + } + + + public EventEmitter CreateEvent(string name, EventAttributes atts, Type type) + { + EventEmitter eventEmitter = new EventEmitter(this, name, atts, type); + events.Add(eventEmitter); + return eventEmitter; + } + + + public void DefineCustomAttribute(CustomAttributeBuilder attribute) + { + typebuilder.SetCustomAttribute(attribute); + } + + public void DefineCustomAttribute(object[] constructorArguments) where TAttribute:Attribute + { + var customAttributeBuilder = AttributeUtil.CreateBuilder(typeof (TAttribute), constructorArguments); + typebuilder.SetCustomAttribute(customAttributeBuilder); + } + + public void DefineCustomAttribute() where TAttribute : Attribute, new() + { + var customAttributeBuilder = AttributeUtil.CreateBuilder(); + typebuilder.SetCustomAttribute(customAttributeBuilder); + } + + public void DefineCustomAttributeFor(FieldReference field) where TAttribute : Attribute, new() + { + var customAttributeBuilder = AttributeUtil.CreateBuilder(); + var fieldbuilder = field.Fieldbuilder; + if(fieldbuilder==null) + { + throw new ArgumentException("Invalid field reference.This reference does not point to field on type being generated","field"); + } + fieldbuilder.SetCustomAttribute(customAttributeBuilder); + } + + + public ConstructorCollection Constructors + { + get { return constructors; } + } + + public NestedClassCollection Nested + { + get { return nested; } + } + + public TypeBuilder TypeBuilder + { + get { return typebuilder; } + } + + public Type BaseType + { + get + { + if (TypeBuilder.IsInterface) + throw new InvalidOperationException ("This emitter represents an interface; interfaces have no base types."); + return TypeBuilder.BaseType; + } + } + + public GenericTypeParameterBuilder[] GenericTypeParams + { + get { return genericTypeParams; } + } + + public void SetGenericTypeParameters(GenericTypeParameterBuilder[] genericTypeParameterBuilders) + { + this.genericTypeParams = genericTypeParameterBuilders; + } + + public void CopyGenericParametersFromMethod (MethodInfo methodToCopyGenericsFrom) + { + // big sanity check + if (genericTypeParams != null) + { + throw new ProxyGenerationException("CopyGenericParametersFromMethod: cannot invoke me twice"); + } + + SetGenericTypeParameters(GenericUtil.CopyGenericArguments(methodToCopyGenericsFrom, typebuilder, name2GenericType)); + } + + public FieldReference GetField(string name) + { + if(string.IsNullOrEmpty(name)) + return null; + + FieldReference value; + fields.TryGetValue(name, out value); + return value; + } + + public IEnumerable GetAllFields() + { + return fields.Values; + } + + public virtual Type BuildType() + { + EnsureBuildersAreInAValidState(); + + Type type = CreateType(typebuilder); + + foreach (NestedClassEmitter builder in nested) + { + builder.BuildType(); + } + + return type; + } + + protected virtual void EnsureBuildersAreInAValidState() + { + if (!typebuilder.IsInterface && constructors.Count == 0) + { + CreateDefaultConstructor(); + } + + foreach (IMemberEmitter builder in properties) + { + builder.EnsureValidCodeBlock(); + builder.Generate(); + } + foreach (IMemberEmitter builder in events) + { + builder.EnsureValidCodeBlock(); + builder.Generate(); + } + foreach (IMemberEmitter builder in constructors) + { + builder.EnsureValidCodeBlock(); + builder.Generate(); + } + foreach (IMemberEmitter builder in methods) + { + builder.EnsureValidCodeBlock(); + builder.Generate(); + } + } + + protected Type CreateType(TypeBuilder type) + { + try + { + return type.CreateType(); + } + catch (BadImageFormatException ex) + { + if (Debugger.IsAttached == false) + { + throw; + } + + if (ex.Message.Contains(@"HRESULT: 0x8007000B") == false) + { + throw; + } + + if (type.IsGenericTypeDefinition == false) + { + throw; + } + + var message = + "This is a DynamicProxy2 error: It looks like you enoutered a bug in Visual Studio debugger, " + + "which causes this exception when proxying types with generic methods having constraints on their generic arguments." + + "This code will work just fine without the debugger attached. " + + "If you wish to use debugger you may have to switch to Visual Studio 2010 where this bug was fixed."; + var exception = new ProxyGenerationException(message); + exception.Data.Add("ProxyType", type.ToString()); + throw exception; + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ArgumentsUtil.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ArgumentsUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ArgumentsUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ArgumentsUtil.cs Sun Feb 13 20:48:24 2011 @@ -0,0 +1,121 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal abstract class ArgumentsUtil + { + public static void EmitLoadOwnerAndReference(Reference reference, ILGenerator il) + { + if (reference == null) return; + + EmitLoadOwnerAndReference(reference.OwnerReference, il); + + reference.LoadReference(il); + } + + public static void InitializeArgumentsByPosition(ArgumentReference[] args, bool isStatic) + { + int offset = isStatic ? 0 : 1; + for (int i = 0; i < args.Length; ++i) + { + args[i].Position = i + offset; + } + } + + public static Type[] InitializeAndConvert(ArgumentReference[] args) + { + Type[] types = new Type[args.Length]; + + for (int i = 0; i < args.Length; ++i) + { + args[i].Position = i + 1; + types[i] = args[i].Type; + } + + return types; + } + + public static ArgumentReference[] ConvertToArgumentReference(Type[] args) + { + var arguments = new ArgumentReference[args.Length]; + + for (int i = 0; i < args.Length; ++i) + { + arguments[i] = new ArgumentReference(args[i]); + } + + return arguments; + } + + public static bool IsAnyByRef(ParameterInfo[] parameters) + { + for (int i = 0; i < parameters.Length; i++) + { + if (parameters[i].ParameterType.IsByRef) return true; + } + return false; + } + + public static ArgumentReference[] ConvertToArgumentReference(ParameterInfo[] args) + { + var arguments = new ArgumentReference[args.Length]; + + for (int i = 0; i < args.Length; ++i) + { + arguments[i] = new ArgumentReference(args[i].ParameterType); + } + + return arguments; + } + + public static ReferenceExpression[] ConvertToArgumentReferenceExpression(ParameterInfo[] args) + { + var arguments = new ReferenceExpression[args.Length]; + + for (int i = 0; i < args.Length; ++i) + { + arguments[i] = new ReferenceExpression(new ArgumentReference(args[i].ParameterType, i + 1)); + } + + return arguments; + } + public static Expression[] ConvertArgumentReferenceToExpression(ArgumentReference[] args) + { + Expression[] expressions = new Expression[args.Length]; + + for (int i = 0; i < args.Length; ++i) + { + expressions[i] = args[i].ToExpression(); + } + + return expressions; + } + + public static Type[] GetTypes(ParameterInfo[] parameters) + { + var types = new Type[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) + { + types[i] = parameters[i].ParameterType; + } + return types; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ClassEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ClassEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ClassEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ClassEmitter.cs Sun Feb 13 20:06:46 2011 @@ -0,0 +1,102 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Reflection; + using System.Reflection.Emit; + + internal class ClassEmitter : AbstractTypeEmitter + { + private readonly ModuleScope moduleScope; + private const TypeAttributes DefaultAttributes = TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable; + + public ClassEmitter(ModuleScope modulescope, String name, Type baseType, IEnumerable interfaces) + : this(modulescope, name, baseType, interfaces, DefaultAttributes, ShouldForceUnsigned()) + { + } + + public ClassEmitter(ModuleScope modulescope, String name, Type baseType, IEnumerable interfaces, TypeAttributes flags) + : this(modulescope, name, baseType, interfaces, flags, ShouldForceUnsigned()) + { + } + + public ClassEmitter(ModuleScope modulescope, String name, Type baseType, IEnumerable interfaces, TypeAttributes flags, + bool forceUnsigned) + : this(CreateTypeBuilder(modulescope, name, baseType, interfaces, flags, forceUnsigned)) + { + interfaces = InitializeGenericArgumentsFromBases(ref baseType, interfaces); + + if (interfaces != null) + { + foreach (Type inter in interfaces) + { + TypeBuilder.AddInterfaceImplementation(inter); + } + } + + TypeBuilder.SetParent(baseType); + moduleScope = modulescope; + } + + public ModuleScope ModuleScope + { + get { return moduleScope; } + } + + private static TypeBuilder CreateTypeBuilder(ModuleScope modulescope, string name, Type baseType, IEnumerable interfaces, + TypeAttributes flags, bool forceUnsigned) + { + bool isAssemblySigned = !forceUnsigned && !StrongNameUtil.IsAnyTypeFromUnsignedAssembly(baseType, interfaces); + return modulescope.DefineType(isAssemblySigned, name, flags); + } + + private static bool ShouldForceUnsigned() + { + return StrongNameUtil.CanStrongNameAssembly == false; + } + + public ClassEmitter(TypeBuilder typeBuilder) + : base(typeBuilder) + { + } + + // The ambivalent generic parameter handling of base type and interfaces has been removed from the ClassEmitter, it isn't used by the proxy + // generators anyway. If a concrete user needs to support generic bases, a subclass can override this method (and not call this base + // implementation), call CopyGenericParametersFromMethod and replace baseType and interfaces by versions bound to the newly created GenericTypeParams. + protected virtual IEnumerable InitializeGenericArgumentsFromBases(ref Type baseType, IEnumerable interfaces) + { + if (baseType != null && baseType.IsGenericTypeDefinition) + { + throw new NotSupportedException("ClassEmitter does not support open generic base types. Type: " + baseType.FullName); + } + + if (interfaces == null) + { + return interfaces; + } + + foreach (var inter in interfaces) + { + if (inter.IsGenericTypeDefinition) + { + throw new NotSupportedException("ClassEmitter does not support open generic interfaces. Type: " + inter.FullName); + } + } + return interfaces; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\AbstractCodeBuilder.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\AbstractCodeBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\AbstractCodeBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\AbstractCodeBuilder.cs Sun Feb 13 20:48:29 2011 @@ -0,0 +1,80 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.CodeBuilders +{ + using System; + using System.Reflection.Emit; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using System.Collections.Generic; + + internal abstract class AbstractCodeBuilder + { + private bool isEmpty; + private readonly ILGenerator generator; + private readonly List stmts; + private readonly List ilmarkers; + + protected AbstractCodeBuilder(ILGenerator generator) + { + this.generator = generator; + stmts = new List(); + ilmarkers = new List(); + isEmpty = true; + } + + //NOTE: should we make this obsolete if no one is using it? + public /*protected internal*/ ILGenerator Generator + { + get { return generator; } + } + + public AbstractCodeBuilder AddStatement(Statement stmt) + { + SetNonEmpty(); + stmts.Add(stmt); + return this; + } + + public LocalReference DeclareLocal(Type type) + { + LocalReference local = new LocalReference(type); + ilmarkers.Add(local); + return local; + } + + public /*protected internal*/ void SetNonEmpty() + { + isEmpty = false; + } + + internal bool IsEmpty + { + get { return isEmpty; } + } + + internal void Generate(IMemberEmitter member, ILGenerator il) + { + foreach (Reference local in ilmarkers) + { + local.Generate(il); + } + + foreach (Statement stmt in stmts) + { + stmt.Emit(member, il); + } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\ConstructorCodeBuilder.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\ConstructorCodeBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\ConstructorCodeBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\ConstructorCodeBuilder.cs Sun Feb 13 20:48:43 2011 @@ -0,0 +1,55 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.CodeBuilders +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class ConstructorCodeBuilder : AbstractCodeBuilder + { + private readonly Type baseType; + + public ConstructorCodeBuilder(Type baseType, ILGenerator generator) : base(generator) + { + this.baseType = baseType; + } + + public void InvokeBaseConstructor() + { + Type type = baseType; + if (type.ContainsGenericParameters) + type = type.GetGenericTypeDefinition (); // need to get generic type definition, otherwise the GetConstructor method might throw NotSupportedException + + BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + var baseDefaultCtor = type.GetConstructor(flags, null, new Type[0], null); + + InvokeBaseConstructor (baseDefaultCtor); + } + + public void InvokeBaseConstructor(ConstructorInfo constructor) + { + AddStatement(new ConstructorInvocationStatement(constructor)); + } + + public void InvokeBaseConstructor(ConstructorInfo constructor, params ArgumentReference[] arguments) + { + AddStatement( + new ConstructorInvocationStatement(constructor, + ArgumentsUtil.ConvertArgumentReferenceToExpression(arguments))); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\MethodCodeBuilder.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\MethodCodeBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\MethodCodeBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\CodeBuilders\MethodCodeBuilder.cs Sun Feb 13 20:48:35 2011 @@ -0,0 +1,25 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.CodeBuilders +{ + using System.Reflection.Emit; + + internal class MethodCodeBuilder : AbstractCodeBuilder + { + public MethodCodeBuilder(ILGenerator generator) : base(generator) + { + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorCollection.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorCollection.cs Sun Feb 13 20:13:16 2011 @@ -0,0 +1,22 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System.Collections.ObjectModel; + + internal class ConstructorCollection : Collection + { + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\ConstructorEmitter.cs Sun Feb 13 20:13:00 2011 @@ -0,0 +1,102 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + using Castle.DynamicProxy.Generators.Emitters.CodeBuilders; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class ConstructorEmitter : IMemberEmitter + { + private readonly ConstructorBuilder builder; + private readonly AbstractTypeEmitter maintype; + + private ConstructorCodeBuilder constructorCodeBuilder; + + protected internal ConstructorEmitter(AbstractTypeEmitter maintype, ConstructorBuilder builder) + { + this.maintype = maintype; + this.builder = builder; + } + + internal ConstructorEmitter(AbstractTypeEmitter maintype, params ArgumentReference[] arguments) + { + this.maintype = maintype; + + var args = ArgumentsUtil.InitializeAndConvert(arguments); + + builder = maintype.TypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, args); + } + + public virtual ConstructorCodeBuilder CodeBuilder + { + get + { + if (constructorCodeBuilder == null) + { + constructorCodeBuilder = new ConstructorCodeBuilder( + maintype.BaseType, builder.GetILGenerator()); + } + return constructorCodeBuilder; + } + } + + public ConstructorBuilder ConstructorBuilder + { + get { return builder; } + } + + public MemberInfo Member + { + get { return builder; } + } + + public Type ReturnType + { + get { return typeof(void); } + } + + private bool ImplementedByRuntime + { + get + { + var attributes = builder.GetMethodImplementationFlags(); + return (attributes & MethodImplAttributes.Runtime) != 0; + } + } + + public virtual void EnsureValidCodeBlock() + { + if (ImplementedByRuntime == false && CodeBuilder.IsEmpty) + { + CodeBuilder.InvokeBaseConstructor(); + CodeBuilder.AddStatement(new ReturnStatement()); + } + } + + public virtual void Generate() + { + if (ImplementedByRuntime) + { + return; + } + + CodeBuilder.Generate(this, builder.GetILGenerator()); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventCollection.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventCollection.cs Sun Feb 13 20:12:54 2011 @@ -0,0 +1,22 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System.Collections.ObjectModel; + + internal class EventCollection : Collection + { + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\EventEmitter.cs Sun Feb 13 20:12:42 2011 @@ -0,0 +1,93 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + internal class EventEmitter : IMemberEmitter + { + private readonly AbstractTypeEmitter typeEmitter; + private readonly Type type; + private readonly EventBuilder eventBuilder; + private MethodEmitter addMethod; + private MethodEmitter removeMethod; + public EventEmitter(AbstractTypeEmitter typeEmitter, string name, EventAttributes attributes, Type type) + { + if (name == null) throw new ArgumentNullException("name"); + if (type == null) throw new ArgumentNullException("type"); + this.typeEmitter = typeEmitter; + this.type = type; + eventBuilder = typeEmitter.TypeBuilder.DefineEvent(name, attributes, type); + } + + public MemberInfo Member + { + get { return null; } + } + + public Type ReturnType + { + get { return type; } + } + + public void Generate() + { + if (addMethod == null) + { + throw new InvalidOperationException("Event add method was not created"); + } + if (removeMethod == null) + { + throw new InvalidOperationException("Event remove method was not created"); + } + addMethod.Generate(); + eventBuilder.SetAddOnMethod(addMethod.MethodBuilder); + + removeMethod.Generate(); + eventBuilder.SetRemoveOnMethod(removeMethod.MethodBuilder); + + } + + public MethodEmitter CreateAddMethod(string addMethodName, MethodAttributes attributes, MethodInfo methodToOverride) + { + if (addMethod != null) + { + throw new InvalidOperationException("An add method exists"); + } + + addMethod = new MethodEmitter(typeEmitter, addMethodName, attributes, methodToOverride); + return addMethod; + } + + public void EnsureValidCodeBlock() + { + addMethod.EnsureValidCodeBlock(); + removeMethod.EnsureValidCodeBlock(); + } + + public MethodEmitter CreateRemoveMethod(string removeMethodName, MethodAttributes attributes, MethodInfo methodToOverride) + { + + if (removeMethod != null) + { + throw new InvalidOperationException("A remove method exists"); + } + removeMethod = new MethodEmitter(typeEmitter, removeMethodName, attributes, methodToOverride); + return removeMethod; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\GenericUtil.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\GenericUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\GenericUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\GenericUtil.cs Sun Feb 13 18:56:57 2011 @@ -0,0 +1,246 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + +#if SILVERLIGHT + using Castle.Core.Extensions; +#endif + + internal delegate GenericTypeParameterBuilder[] ApplyGenArgs(String[] argumentNames); + + internal class GenericUtil + { + public static Dictionary GetGenericArgumentsMap(AbstractTypeEmitter parentEmitter) + { + if (parentEmitter.GenericTypeParams == null || parentEmitter.GenericTypeParams.Length == 0) + { + return new Dictionary(0); + } + + var name2GenericType = new Dictionary(parentEmitter.GenericTypeParams.Length); + foreach (var genType in parentEmitter.GenericTypeParams) + { + name2GenericType.Add(genType.Name, genType); + } + return name2GenericType; + } + + public static GenericTypeParameterBuilder[] CopyGenericArguments( + MethodInfo methodToCopyGenericsFrom, + TypeBuilder builder, + Dictionary name2GenericType) + { + return + CopyGenericArguments(methodToCopyGenericsFrom, name2GenericType, + builder.DefineGenericParameters); + } + + public static GenericTypeParameterBuilder[] CopyGenericArguments( + MethodInfo methodToCopyGenericsFrom, + MethodBuilder builder, + Dictionary name2GenericType) + { + return + CopyGenericArguments(methodToCopyGenericsFrom, name2GenericType, + builder.DefineGenericParameters); + } + + private static GenericTypeParameterBuilder[] CopyGenericArguments( + MethodInfo methodToCopyGenericsFrom, + Dictionary name2GenericType, + ApplyGenArgs genericParameterGenerator) + { + var originalGenericArguments = methodToCopyGenericsFrom.GetGenericArguments(); + if (originalGenericArguments.Length == 0) + { + return null; + } + + var argumentNames = GetArgumentNames(originalGenericArguments); + var newGenericParameters = genericParameterGenerator(argumentNames); + + for (int i = 0; i < newGenericParameters.Length; i++) + { + try + { + var attributes = originalGenericArguments[i].GenericParameterAttributes; + var types = originalGenericArguments[i].GetGenericParameterConstraints(); + + newGenericParameters[i].SetGenericParameterAttributes(attributes); + +#if SILVERLIGHT + Type[] interfacesConstraints = Castle.Core.Extensions.SilverlightExtensions.FindAll(types, delegate(Type type) { return type.IsInterface; }); + + Type baseClassConstraint = Castle.DynamicProxy.SilverlightExtensions.Extensions.Find(types, delegate(Type type) { return type.IsClass; }); +#else + var interfacesConstraints = Array.FindAll(types, type => type.IsInterface); + var baseClassConstraint = Array.Find(types, type => type.IsClass); +#endif + + if (interfacesConstraints.Length != 0) + { + for (int j = 0; j < interfacesConstraints.Length; ++j) + { + interfacesConstraints[j] = + AdjustConstraintToNewGenericParameters(interfacesConstraints[j], methodToCopyGenericsFrom, + originalGenericArguments, newGenericParameters); + } + newGenericParameters[i].SetInterfaceConstraints(interfacesConstraints); + } + + if (baseClassConstraint != null) + { + baseClassConstraint = AdjustConstraintToNewGenericParameters(baseClassConstraint, methodToCopyGenericsFrom, + originalGenericArguments, newGenericParameters); + newGenericParameters[i].SetBaseTypeConstraint(baseClassConstraint); + } + CopyNonInheritableAttributes(newGenericParameters[i], originalGenericArguments[i]); + } + catch (NotSupportedException) + { + // Doesnt matter + + newGenericParameters[i].SetGenericParameterAttributes(GenericParameterAttributes.None); + } + + name2GenericType[argumentNames[i]] = newGenericParameters[i]; + } + + return newGenericParameters; + } + + private static void CopyNonInheritableAttributes(GenericTypeParameterBuilder newGenericParameter, Type originalGenericArgument) + { + foreach (var attribute in AttributeUtil.GetNonInheritableAttributes(originalGenericArgument)) + { + newGenericParameter.SetCustomAttribute(attribute); + } + } + + private static string[] GetArgumentNames(Type[] originalGenericArguments) + { + String[] argumentNames = new String[originalGenericArguments.Length]; + + for (int i = 0; i < argumentNames.Length; i++) + { + argumentNames[i] = originalGenericArguments[i].Name; + } + return argumentNames; + } + + private static Type AdjustConstraintToNewGenericParameters( + Type constraint, MethodInfo methodToCopyGenericsFrom, Type[] originalGenericParameters, GenericTypeParameterBuilder[] newGenericParameters) + { + if (constraint.IsGenericType) + { + Type[] genericArgumentsOfConstraint = constraint.GetGenericArguments(); + + for (int i = 0; i < genericArgumentsOfConstraint.Length; ++i) + { + genericArgumentsOfConstraint[i] = + AdjustConstraintToNewGenericParameters(genericArgumentsOfConstraint[i], methodToCopyGenericsFrom, originalGenericParameters, newGenericParameters); + } + return constraint.GetGenericTypeDefinition().MakeGenericType(genericArgumentsOfConstraint); + } + else if (constraint.IsGenericParameter) + { + // Determine the source of the parameter + if (constraint.DeclaringMethod != null) + { + // constraint comes from the method + int index = Array.IndexOf(originalGenericParameters, constraint); + Trace.Assert(index != -1, + "When a generic method parameter has a constraint on another method parameter, both parameters must be declared on the same method."); + return newGenericParameters[index]; + } + else // parameter from surrounding type + { + Trace.Assert(constraint.DeclaringType.IsGenericTypeDefinition); + Trace.Assert(methodToCopyGenericsFrom.DeclaringType.IsGenericType + && constraint.DeclaringType == methodToCopyGenericsFrom.DeclaringType.GetGenericTypeDefinition (), + "When a generic method parameter has a constraint on a generic type parameter, the generic type must be the declaring typer of the method."); + + int index = Array.IndexOf(constraint.DeclaringType.GetGenericArguments(), constraint); + Trace.Assert (index != -1, "The generic parameter comes from the given type."); + return methodToCopyGenericsFrom.DeclaringType.GetGenericArguments() [index]; // these are the actual, concrete types + } + } + else + { + return constraint; + } + } + + public static Type[] ExtractParametersTypes( + ParameterInfo[] baseMethodParameters, + Dictionary name2GenericType) + { + Type[] newParameters = new Type[baseMethodParameters.Length]; + + for (int i = 0; i < baseMethodParameters.Length; i++) + { + ParameterInfo param = baseMethodParameters[i]; + Type paramType = param.ParameterType; + + newParameters[i] = ExtractCorrectType(paramType, name2GenericType); + } + + return newParameters; + } + + public static Type ExtractCorrectType(Type paramType, Dictionary name2GenericType) + { + if (paramType.IsArray) + { + int rank = paramType.GetArrayRank(); + + Type underlyingType = paramType.GetElementType(); + + if (underlyingType.IsGenericParameter) + { + GenericTypeParameterBuilder genericType; + if (name2GenericType.TryGetValue(underlyingType.Name, out genericType) == false) + return paramType; + + if (rank == 1) + { + return genericType.MakeArrayType(); + } + return genericType.MakeArrayType(rank); + } + if (rank == 1) + { + return underlyingType.MakeArrayType(); + } + return underlyingType.MakeArrayType(rank); + } + + if (paramType.IsGenericParameter) + { + GenericTypeParameterBuilder value; + if (name2GenericType.TryGetValue(paramType.Name, out value)) + return value; + } + + return paramType; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\IMemberEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\IMemberEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\IMemberEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\IMemberEmitter.cs Sun Feb 13 20:54:20 2011 @@ -0,0 +1,30 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection; + + internal interface IMemberEmitter + { + MemberInfo Member { get; } + + Type ReturnType { get; } + + void Generate(); + + void EnsureValidCodeBlock(); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdcOpCodesDictionary.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdcOpCodesDictionary.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdcOpCodesDictionary.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdcOpCodesDictionary.cs Sun Feb 13 20:54:25 2011 @@ -0,0 +1,67 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Reflection.Emit; + + /// s + /// Provides appropriate Ldc.X opcode for the type of primitive value to be loaded. + /// + internal sealed class LdcOpCodesDictionary : Dictionary + { + private static readonly LdcOpCodesDictionary dict = new LdcOpCodesDictionary(); + + // has to be assigned explicitly to suppress compiler warning + private static readonly OpCode emptyOpCode = new OpCode(); + + private LdcOpCodesDictionary() + { + Add(typeof(bool), OpCodes.Ldc_I4); + Add(typeof(char), OpCodes.Ldc_I4); + Add(typeof(SByte), OpCodes.Ldc_I4); + Add(typeof(Int16), OpCodes.Ldc_I4); + Add(typeof(Int32), OpCodes.Ldc_I4); + Add(typeof(Int64), OpCodes.Ldc_I8); + Add(typeof(float), OpCodes.Ldc_R4); + Add(typeof(double), OpCodes.Ldc_R8); + Add(typeof(byte), OpCodes.Ldc_I4_0); + Add(typeof(UInt16), OpCodes.Ldc_I4_0); + Add(typeof(UInt32), OpCodes.Ldc_I4_0); + Add(typeof(UInt64), OpCodes.Ldc_I4_0); + } + + public new OpCode this[Type type] + { + get + { + if (ContainsKey(type)) + return base[type]; + return EmptyOpCode; + } + } + + public static LdcOpCodesDictionary Instance + { + get { return dict; } + } + + public static OpCode EmptyOpCode + { + get { return emptyOpCode; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdindOpCodesDictionary.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdindOpCodesDictionary.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdindOpCodesDictionary.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\LdindOpCodesDictionary.cs Sun Feb 13 20:54:30 2011 @@ -0,0 +1,68 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Reflection.Emit; + + /// + /// Provides appropriate Ldind.X opcode for + /// the type of primitive value to be loaded indirectly. + /// + internal sealed class LdindOpCodesDictionary : Dictionary + { + private static readonly LdindOpCodesDictionary _dict = new LdindOpCodesDictionary(); + + // has to be assigned explicitly to suppress compiler warning + private static readonly OpCode emptyOpCode = new OpCode(); + + private LdindOpCodesDictionary() + { + Add(typeof(bool), OpCodes.Ldind_I1); + Add(typeof(char), OpCodes.Ldind_I2); + Add(typeof(SByte), OpCodes.Ldind_I1); + Add(typeof(Int16), OpCodes.Ldind_I2); + Add(typeof(Int32), OpCodes.Ldind_I4); + Add(typeof(Int64), OpCodes.Ldind_I8); + Add(typeof(float), OpCodes.Ldind_R4); + Add(typeof(double), OpCodes.Ldind_R8); + Add(typeof(byte), OpCodes.Ldind_U1); + Add(typeof(UInt16), OpCodes.Ldind_U2); + Add(typeof(UInt32), OpCodes.Ldind_U4); + Add(typeof(UInt64), OpCodes.Ldind_I8); + } + + public new OpCode this[Type type] + { + get + { + if (ContainsKey(type)) + return base[type]; + return EmptyOpCode; + } + } + + public static LdindOpCodesDictionary Instance + { + get { return _dict; } + } + + public static OpCode EmptyOpCode + { + get { return emptyOpCode; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodCollection.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodCollection.cs Sun Feb 13 20:49:10 2011 @@ -0,0 +1,22 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System.Collections.ObjectModel; + + internal class MethodCollection : Collection + { + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\MethodEmitter.cs Sun Feb 13 20:49:00 2011 @@ -0,0 +1,188 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + using System.Linq; + + using Castle.DynamicProxy.Generators.Emitters.CodeBuilders; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + [DebuggerDisplay("{builder.Name}")] + internal class MethodEmitter : IMemberEmitter + { + private readonly MethodBuilder builder; + private readonly GenericTypeParameterBuilder[] genericTypeParams; + + private ArgumentReference[] arguments; + + private MethodCodeBuilder codebuilder; + + protected internal MethodEmitter(MethodBuilder builder) + { + this.builder = builder; + } + + internal MethodEmitter(AbstractTypeEmitter owner, String name, MethodAttributes attributes) + : this(owner.TypeBuilder.DefineMethod(name, attributes)) + { + } + + internal MethodEmitter(AbstractTypeEmitter owner, String name, + MethodAttributes attributes, Type returnType, + params Type[] argumentTypes) + : this(owner, name, attributes) + { + SetParameters(argumentTypes); + SetReturnType(returnType); + } + + internal MethodEmitter(AbstractTypeEmitter owner, String name, + MethodAttributes attributes, MethodInfo methodToUseAsATemplate) + : this(owner, name, attributes) + { + var name2GenericType = GenericUtil.GetGenericArgumentsMap(owner); + + var returnType = GenericUtil.ExtractCorrectType(methodToUseAsATemplate.ReturnType, name2GenericType); + var baseMethodParameters = methodToUseAsATemplate.GetParameters(); + var parameters = GenericUtil.ExtractParametersTypes(baseMethodParameters, name2GenericType); + + genericTypeParams = GenericUtil.CopyGenericArguments(methodToUseAsATemplate, builder, name2GenericType); + SetParameters(parameters); + SetReturnType(returnType); + SetSignature(returnType, methodToUseAsATemplate.ReturnParameter, parameters, baseMethodParameters); + DefineParameters(baseMethodParameters); + } + + public GenericTypeParameterBuilder[] GenericTypeParams + { + get { return genericTypeParams; } + } + + public virtual MethodCodeBuilder CodeBuilder + { + get + { + if (codebuilder == null) + codebuilder = new MethodCodeBuilder(builder.GetILGenerator()); + return codebuilder; + } + } + + public ArgumentReference[] Arguments + { + get { return arguments; } + } + + public MethodBuilder MethodBuilder + { + get { return builder; } + } + + private bool ImplementedByRuntime + { + get + { + var attributes = builder.GetMethodImplementationFlags(); + return (attributes & MethodImplAttributes.Runtime) != 0; + } + } + + #region IMemberEmitter Members + + public Type ReturnType + { + get { return builder.ReturnType; } + } + + public MemberInfo Member + { + get { return builder; } + } + + public virtual void EnsureValidCodeBlock() + { + if (ImplementedByRuntime == false && CodeBuilder.IsEmpty) + { + CodeBuilder.AddStatement(new NopStatement()); + CodeBuilder.AddStatement(new ReturnStatement()); + } + } + + public virtual void Generate() + { + if (ImplementedByRuntime) + return; + + codebuilder.Generate(this, builder.GetILGenerator()); + } + + #endregion + + private void SetReturnType(Type returnType) + { + builder.SetReturnType(returnType); + } + + private void SetSignature(Type returnType, ParameterInfo returnParameter, Type[] parameters, ParameterInfo[] baseMethodParameters) + { + builder.SetSignature( + returnType, +#if SILVERLIGHT + null, + null, +#else + returnParameter.GetRequiredCustomModifiers(), + returnParameter.GetOptionalCustomModifiers(), +#endif + parameters, +#if SILVERLIGHT + null, + null +#else + baseMethodParameters.Select(x => x.GetRequiredCustomModifiers()).ToArray(), + baseMethodParameters.Select(x => x.GetOptionalCustomModifiers()).ToArray() +#endif + ); + } + + public void DefineCustomAttribute(CustomAttributeBuilder attribute) + { + builder.SetCustomAttribute(attribute); + } + + public void SetParameters(Type[] paramTypes) + { + builder.SetParameters(paramTypes); + arguments = ArgumentsUtil.ConvertToArgumentReference(paramTypes); + ArgumentsUtil.InitializeArgumentsByPosition(arguments, MethodBuilder.IsStatic); + } + + private void DefineParameters(ParameterInfo[] parameters) + { + foreach (var parameter in parameters) + { + var parameterBuilder = builder.DefineParameter(parameter.Position + 1, parameter.Attributes, parameter.Name); + foreach (var attribute in parameter.GetNonInheritableAttributes()) + { + parameterBuilder.SetCustomAttribute(attribute); + } + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassCollection.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassCollection.cs Sun Feb 13 20:12:27 2011 @@ -0,0 +1,22 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System.Collections.ObjectModel; + + internal class NestedClassCollection : Collection + { + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\NestedClassEmitter.cs Sun Feb 13 20:12:05 2011 @@ -0,0 +1,47 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + internal class NestedClassEmitter : AbstractTypeEmitter + { + public NestedClassEmitter(AbstractTypeEmitter maintype, String name, Type baseType, Type[] interfaces) + : this(maintype, CreateTypeBuilder (maintype, name, TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Class, baseType, interfaces)) + { + } + + public NestedClassEmitter(AbstractTypeEmitter maintype, String name, TypeAttributes attributes, Type baseType, Type[] interfaces) + : this(maintype, CreateTypeBuilder (maintype, name, attributes, baseType, interfaces)) + { + } + + private static TypeBuilder CreateTypeBuilder(AbstractTypeEmitter maintype, string name, TypeAttributes attributes, Type baseType, Type[] interfaces) + { + return maintype.TypeBuilder.DefineNestedType( + name, + attributes, + baseType, interfaces); + } + + public NestedClassEmitter(AbstractTypeEmitter maintype, TypeBuilder typeBuilder) + : base(typeBuilder) + { + maintype.Nested.Add(this); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\OpCodeUtil.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\OpCodeUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\OpCodeUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\OpCodeUtil.cs Sun Feb 13 18:56:57 2011 @@ -0,0 +1,209 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection.Emit; + + internal abstract class OpCodeUtil + { + /// + /// Emits a load opcode of the appropriate kind for a constant string or + /// primitive value. + /// + /// + /// + public static void EmitLoadOpCodeForConstantValue(ILGenerator gen, object value) + { + if (value is String) + { + gen.Emit(OpCodes.Ldstr, value.ToString()); + } + else if (value is Int32) + { + OpCode code = LdcOpCodesDictionary.Instance[value.GetType()]; + gen.Emit(code, (int) value); + } + else if (value is bool) + { + OpCode code = LdcOpCodesDictionary.Instance[value.GetType()]; + gen.Emit(code, Convert.ToInt32(value)); + } + else + { + throw new NotSupportedException(); + } + } + + /// + /// Emits a load opcode of the appropriate kind for the constant default value of a + /// type, such as 0 for value types and null for reference types. + /// + public static void EmitLoadOpCodeForDefaultValueOfType(ILGenerator gen, Type type) + { + if (type.IsPrimitive) + { + var opCode = LdcOpCodesDictionary.Instance[type]; + switch (opCode.StackBehaviourPush) + { + case StackBehaviour.Pushi: + gen.Emit(opCode, 0); + if (Is64BitTypeLoadedAsInt32(type)) + { + // we load Int32, and have to convert it to 64bit type + gen.Emit(OpCodes.Conv_I8); + } + break; + case StackBehaviour.Pushr8: + gen.Emit(opCode, 0D); + break; + case StackBehaviour.Pushi8: + gen.Emit(opCode, 0L); + break; + case StackBehaviour.Pushr4: + gen.Emit(opCode, 0F); + break; + default: + throw new NotSupportedException(); + } + } + else + { + gen.Emit(OpCodes.Ldnull); + } + } + + private static bool Is64BitTypeLoadedAsInt32(Type type) + { + return type == typeof (long) || type == typeof (ulong); + } + + /// + /// Emits a load indirect opcode of the appropriate type for a value or object reference. + /// Pops a pointer off the evaluation stack, dereferences it and loads + /// a value of the specified type. + /// + /// + /// + public static void EmitLoadIndirectOpCodeForType(ILGenerator gen, Type type) + { + if (type.IsEnum) + { + EmitLoadIndirectOpCodeForType(gen, GetUnderlyingTypeOfEnum(type)); + return; + } + + if (type.IsByRef) + { + throw new NotSupportedException("Cannot load ByRef values"); + } + else if (type.IsPrimitive && type != typeof (IntPtr)) + { + OpCode opCode = LdindOpCodesDictionary.Instance[type]; + + if (opCode == LdindOpCodesDictionary.EmptyOpCode) + { + throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); + } + + gen.Emit(opCode); + } + else if (type.IsValueType) + { + gen.Emit(OpCodes.Ldobj, type); + } + else if (type.IsGenericParameter) + { + gen.Emit(OpCodes.Ldobj, type); + } + else + { + gen.Emit(OpCodes.Ldind_Ref); + } + } + + /// + /// Emits a store indirectopcode of the appropriate type for a value or object reference. + /// Pops a value of the specified type and a pointer off the evaluation stack, and + /// stores the value. + /// + /// + /// + public static void EmitStoreIndirectOpCodeForType(ILGenerator gen, Type type) + { + if (type.IsEnum) + { + EmitStoreIndirectOpCodeForType(gen, GetUnderlyingTypeOfEnum(type)); + return; + } + + if (type.IsByRef) + { + throw new NotSupportedException("Cannot store ByRef values"); + } + else if (type.IsPrimitive && type != typeof (IntPtr)) + { + OpCode opCode = StindOpCodesDictionary.Instance[type]; + + if (Equals(opCode, StindOpCodesDictionary.EmptyOpCode)) + { + throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); + } + + gen.Emit(opCode); + } + else if (type.IsValueType) + { + gen.Emit(OpCodes.Stobj, type); + } + else if (type.IsGenericParameter) + { + gen.Emit(OpCodes.Stobj, type); + } + else + { + gen.Emit(OpCodes.Stind_Ref); + } + } + + private static Type GetUnderlyingTypeOfEnum(Type enumType) + { + Enum baseType = (Enum) Activator.CreateInstance(enumType); + TypeCode code = baseType.GetTypeCode(); + + switch (code) + { + case TypeCode.SByte: + return typeof (SByte); + case TypeCode.Byte: + return typeof (Byte); + case TypeCode.Int16: + return typeof (Int16); + case TypeCode.Int32: + return typeof (Int32); + case TypeCode.Int64: + return typeof (Int64); + case TypeCode.UInt16: + return typeof (UInt16); + case TypeCode.UInt32: + return typeof (UInt32); + case TypeCode.UInt64: + return typeof (UInt64); + default: + throw new NotSupportedException(); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertiesCollection.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertiesCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertiesCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertiesCollection.cs Sun Feb 13 20:13:22 2011 @@ -0,0 +1,25 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System.Collections.ObjectModel; + + /// + /// Summary description for PropertiesCollection. + /// + internal class PropertiesCollection : Collection + { + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertyEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertyEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertyEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\PropertyEmitter.cs Sun Feb 13 20:12:48 2011 @@ -0,0 +1,147 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + using Castle.DynamicProxy.Tokens; + + internal class PropertyEmitter : IMemberEmitter + { + private readonly PropertyBuilder builder; + private readonly AbstractTypeEmitter parentTypeEmitter; + private MethodEmitter getMethod; + private MethodEmitter setMethod; + + // private ParameterInfo[] indexParameters; + + private delegate PropertyBuilder DefineProperty_Clr2_0( + string name, PropertyAttributes attributes, Type propertyType, Type[] parameters); + + public delegate PropertyBuilder DefineProperty_Clr_2_0_SP1(string name, + PropertyAttributes attributes, + CallingConventions callingConvention, + Type returnType, + Type[] returnTypeRequiredCustomModifiers, + Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, + Type[][] parameterTypeRequiredCustomModifiers, + Type[][] parameterTypeOptionalCustomModifiers); + + public PropertyEmitter(AbstractTypeEmitter parentTypeEmitter, string name, PropertyAttributes attributes, Type propertyType, Type[] arguments) + { + this.parentTypeEmitter = parentTypeEmitter; + + // DYNPROXY-73 - AmbiguousMatchException for properties + // This is a workaround for a framework limitation in CLR 2.0 + // This limitation was removed in CLR 2.0 SP1, but we don't want to + // tie ourselves to that version. This perform the lookup for the new overload + // dynamically, so we have a nice fallback on vanilla CLR 2.0 + + if (TypeBuilderMethods.DefineProperty == null) + { + DefineProperty_Clr2_0 oldDefineProperty = parentTypeEmitter.TypeBuilder.DefineProperty; + builder = oldDefineProperty(name, attributes, propertyType, arguments); + } + else + { + DefineProperty_Clr_2_0_SP1 newDefinedProperty = (DefineProperty_Clr_2_0_SP1) + Delegate.CreateDelegate(typeof (DefineProperty_Clr_2_0_SP1), + parentTypeEmitter.TypeBuilder, + TypeBuilderMethods.DefineProperty); + builder = newDefinedProperty( + name, attributes, CallingConventions.HasThis, propertyType, + null, null, arguments, null, null); + } + } + + public MethodEmitter CreateGetMethod(string name, MethodAttributes attrs, MethodInfo methodToOverride, params Type[] parameters) + { + if (getMethod != null) + { + throw new InvalidOperationException("A get method exists"); + } + + getMethod = new MethodEmitter(parentTypeEmitter, name, attrs, methodToOverride); + return getMethod; + } + + public MethodEmitter CreateGetMethod(string name, MethodAttributes attributes, MethodInfo methodToOverride) + { + return CreateGetMethod(name, attributes, methodToOverride, Type.EmptyTypes); + } + + public MethodEmitter CreateSetMethod(string name, MethodAttributes attrs, MethodInfo methodToOverride, params Type[] parameters) + { + if (setMethod != null) + { + throw new InvalidOperationException("A set method exists"); + } + + setMethod = new MethodEmitter(parentTypeEmitter, name, attrs, methodToOverride); + return setMethod; + } + + public MethodEmitter CreateSetMethod(string name, MethodAttributes attributes, MethodInfo methodToOverride) + { + var method = CreateSetMethod(name, attributes, methodToOverride, Type.EmptyTypes); + return method; + } + + public MemberInfo Member + { + get { return null; } + } + + public Type ReturnType + { + get { return builder.PropertyType; } + } + + public void Generate() + { + if (setMethod != null) + { + setMethod.Generate(); + builder.SetSetMethod(setMethod.MethodBuilder); + } + + if (getMethod != null) + { + getMethod.Generate(); + builder.SetGetMethod(getMethod.MethodBuilder); + } + } + + public void EnsureValidCodeBlock() + { + if (setMethod != null) + { + setMethod.EnsureValidCodeBlock(); + } + + if (getMethod != null) + { + getMethod.EnsureValidCodeBlock(); + } + } + + public void DefineCustomAttribute(CustomAttributeBuilder attribute) + { + builder.SetCustomAttribute(attribute); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AddressOfReferenceExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AddressOfReferenceExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AddressOfReferenceExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AddressOfReferenceExpression.cs Sun Feb 13 20:44:54 2011 @@ -0,0 +1,35 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class AddressOfReferenceExpression : Expression + { + private readonly Reference reference; + + public AddressOfReferenceExpression(Reference reference) + { + this.reference = reference; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(reference.OwnerReference, gen); + + reference.LoadAddressOfReference(gen); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ArgumentReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ArgumentReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ArgumentReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ArgumentReference.cs Sun Feb 13 20:44:59 2011 @@ -0,0 +1,76 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class ArgumentReference : TypeReference + { + public ArgumentReference(Type argumentType) + : base(argumentType) + { + Position = -1; + } + + public ArgumentReference(Type argumentType, int position) + : base(argumentType) + { + Position = position; + } + + internal int Position { get; set; } + + public override void LoadReference(ILGenerator gen) + { + if (Position == -1) + { + throw new ProxyGenerationException("ArgumentReference unitialized"); + } + switch (Position) + { + case 0: + gen.Emit(OpCodes.Ldarg_0); + break; + case 1: + gen.Emit(OpCodes.Ldarg_1); + break; + case 2: + gen.Emit(OpCodes.Ldarg_2); + break; + case 3: + gen.Emit(OpCodes.Ldarg_3); + break; + default: + gen.Emit(OpCodes.Ldarg_S, Position); + break; + } + } + + public override void StoreReference(ILGenerator gen) + { + if (Position == -1) + { + throw new ProxyGenerationException("ArgumentReference unitialized"); + } + gen.Emit(OpCodes.Starg, Position); + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + throw new NotSupportedException(); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArgumentStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArgumentStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArgumentStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArgumentStatement.cs Sun Feb 13 20:45:05 2011 @@ -0,0 +1,37 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class AssignArgumentStatement:Statement + { + private readonly ArgumentReference argument; + private readonly Expression expression; + + public AssignArgumentStatement(ArgumentReference argument, Expression expression) + { + this.argument = argument; + this.expression = expression; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(argument, gen); + expression.Emit(member, gen); + + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArrayStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArrayStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArrayStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArrayStatement.cs Sun Feb 13 20:45:10 2011 @@ -0,0 +1,43 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class AssignArrayStatement : Statement + { + private readonly Reference targetArray; + private readonly int targetPosition; + private readonly Expression value; + + public AssignArrayStatement(Reference targetArray, int targetPosition, Expression value) + { + this.targetArray = targetArray; + this.targetPosition = targetPosition; + this.value = value; + } + + public override void Emit(IMemberEmitter member, ILGenerator il) + { + ArgumentsUtil.EmitLoadOwnerAndReference(targetArray, il); + + il.Emit(OpCodes.Ldc_I4, targetPosition); + + value.Emit(member, il); + + il.Emit(OpCodes.Stelem_Ref); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignStatement.cs Sun Feb 13 20:45:16 2011 @@ -0,0 +1,37 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class AssignStatement : Statement + { + private readonly Reference target; + private readonly Expression expression; + + public AssignStatement(Reference target, Expression expression) + { + this.target = target; + this.expression = expression; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(target.OwnerReference, gen); + expression.Emit(member, gen); + target.StoreReference(gen); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AsTypeReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AsTypeReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AsTypeReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\AsTypeReference.cs Sun Feb 13 20:45:22 2011 @@ -0,0 +1,55 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class AsTypeReference : Reference + { + private readonly Reference reference; + private readonly Type type; + + public AsTypeReference(Reference reference, Type type) + { + if (reference == null) throw new ArgumentNullException("reference"); + if (type == null) throw new ArgumentNullException("type"); + this.reference = reference; + this.type = type; + if(reference == OwnerReference) + { + OwnerReference = null; + } + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + // NOTE: Or maybe throw new NotSupportedException() ? + reference.LoadAddressOfReference(gen); + } + + public override void LoadReference(ILGenerator gen) + { + reference.LoadReference(gen); + gen.Emit(OpCodes.Isinst, type); + } + + public override void StoreReference(ILGenerator gen) + { + // NOTE: Or maybe throw new NotSupportedException() ? + reference.StoreReference(gen); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\BindDelegateExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\BindDelegateExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\BindDelegateExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\BindDelegateExpression.cs Sun Feb 13 20:45:27 2011 @@ -0,0 +1,56 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + internal class BindDelegateExpression:Expression + { + private readonly ConstructorInfo delegateCtor; + private readonly Expression owner; + private readonly MethodInfo methodToBindTo; + + public BindDelegateExpression(Type @delegate, Expression owner, MethodInfo methodToBindTo, GenericTypeParameterBuilder[] genericTypeParams) + { + delegateCtor = @delegate.GetConstructors()[0]; + this.methodToBindTo = methodToBindTo; + if(@delegate.IsGenericTypeDefinition) + { + var closedDelegate = @delegate.MakeGenericType(genericTypeParams); + delegateCtor = TypeBuilder.GetConstructor(closedDelegate, delegateCtor); + this.methodToBindTo = methodToBindTo.MakeGenericMethod(genericTypeParams); + } + this.owner = owner; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + owner.Emit(member, gen); + gen.Emit(OpCodes.Dup); + if (methodToBindTo.IsFinal) + { + gen.Emit(OpCodes.Ldftn, methodToBindTo); + } + else + { + gen.Emit(OpCodes.Ldvirtftn, methodToBindTo); + } + gen.Emit(OpCodes.Newobj, delegateCtor); + + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ByRefReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ByRefReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ByRefReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ByRefReference.cs Sun Feb 13 20:45:33 2011 @@ -0,0 +1,45 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class ByRefReference : TypeReference + { + private readonly LocalReference localReference; + + public ByRefReference(LocalReference localReference) + : base(localReference.Type) + { + this.localReference = localReference; + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + localReference.LoadAddressOfReference(gen); + } + + public override void LoadReference(ILGenerator gen) + { + localReference.LoadAddressOfReference(gen); + } + + public override void StoreReference(ILGenerator gen) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstReference.cs Sun Feb 13 20:45:38 2011 @@ -0,0 +1,54 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class ConstReference : TypeReference + { + private readonly object value; + + public ConstReference(object value) + : base(value.GetType()) + { + if (!value.GetType().IsPrimitive && !(value is String)) + { + throw new ProxyGenerationException("Invalid type to ConstReference"); + } + + this.value = value; + } + + public override void Generate(ILGenerator gen) + { + } + + public override void LoadReference(ILGenerator gen) + { + OpCodeUtil.EmitLoadOpCodeForConstantValue(gen, value); + } + + public override void StoreReference(ILGenerator gen) + { + throw new NotImplementedException("ConstReference.StoreReference"); + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + throw new NotSupportedException(); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstructorInvocationStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstructorInvocationStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstructorInvocationStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstructorInvocationStatement.cs Sun Feb 13 20:45:43 2011 @@ -0,0 +1,47 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + internal class ConstructorInvocationStatement : Statement + { + private readonly ConstructorInfo cmethod; + private readonly Expression[] args; + + public ConstructorInvocationStatement(ConstructorInfo method, params Expression[] args) + { + if (method == null) throw new ArgumentNullException("method"); + if (args == null) throw new ArgumentNullException("args"); + + cmethod = method; + this.args = args; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + gen.Emit(OpCodes.Ldarg_0); + + foreach (Expression exp in args) + { + exp.Emit(member, gen); + } + + gen.Emit(OpCodes.Call, cmethod); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConvertExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConvertExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConvertExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConvertExpression.cs Sun Feb 13 20:45:58 2011 @@ -0,0 +1,115 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class ConvertExpression : Expression + { + private readonly Expression right; + private Type fromType; + private Type target; + + public ConvertExpression(Type targetType, Expression right) + : this(targetType, typeof (object), right) + { + } + + public ConvertExpression(Type targetType, Type fromType, Expression right) + { + target = targetType; + this.fromType = fromType; + this.right = right; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + right.Emit(member, gen); + + if (fromType == target) + { + return; + } + + if (fromType.IsByRef) + { + fromType = fromType.GetElementType(); + } + + if (target.IsByRef) + { + target = target.GetElementType(); + } + + if (target.IsValueType) + { + if (fromType.IsValueType) + { + throw new NotImplementedException("Cannot convert between distinct value types"); + } + else + { + // Unbox conversion + // Assumes fromType is a boxed value + // if we can, we emit a box and ldind, otherwise, we will use unbox.any + if (LdindOpCodesDictionary.Instance[target] != LdindOpCodesDictionary.EmptyOpCode) + { + gen.Emit(OpCodes.Unbox, target); + OpCodeUtil.EmitLoadIndirectOpCodeForType(gen, target); + } + else + { + gen.Emit(OpCodes.Unbox_Any, target); + } + } + } + else + { + if (fromType.IsValueType) + { + // Box conversion + gen.Emit(OpCodes.Box, fromType); + EmitCastIfNeeded(typeof (object), target, gen); + } + else + { + // Possible down-cast + EmitCastIfNeeded(fromType, target, gen); + } + } + } + + private static void EmitCastIfNeeded(Type from, Type target, ILGenerator gen) + { + if (target.IsGenericParameter) + { + gen.Emit(OpCodes.Unbox_Any, target); + } + else if (from.IsGenericParameter) + { + gen.Emit(OpCodes.Box, from); + } + else if (target.IsGenericType && target != from) + { + gen.Emit(OpCodes.Castclass, target); + } + else if (target.IsSubclassOf(from)) + { + gen.Emit(OpCodes.Castclass, target); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\DefaultValueExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\DefaultValueExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\DefaultValueExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\DefaultValueExpression.cs Sun Feb 13 20:46:03 2011 @@ -0,0 +1,81 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class DefaultValueExpression : Expression + { + private readonly Type type; + + public DefaultValueExpression(Type type) + { + this.type = type; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + // TODO: check if this can be simplified by using more of OpCodeUtil and other existing types + if (IsPrimitiveOrClass(type)) + { + OpCodeUtil.EmitLoadOpCodeForDefaultValueOfType(gen, type); + } + else if(type.IsValueType || type.IsGenericParameter) + { + // TODO: handle decimal explicitly + var local = gen.DeclareLocal(type); + gen.Emit(OpCodes.Ldloca_S, local); + gen.Emit(OpCodes.Initobj, type); + gen.Emit(OpCodes.Ldloc, local); + } + else if (type.IsByRef) + { + EmitByRef(gen); + } + else + { + throw new ProxyGenerationException("Can't emit default value for type " + type); + } + } + + private bool IsPrimitiveOrClass(Type type) + { + if ((type.IsPrimitive && type != typeof(IntPtr))) + return true; + return ((type.IsClass || type.IsInterface) && + type.IsGenericParameter == false && + type.IsByRef == false); + } + + private void EmitByRef(ILGenerator gen) + { + var elementType = type.GetElementType(); + if (IsPrimitiveOrClass(elementType)) + { + OpCodeUtil.EmitLoadOpCodeForDefaultValueOfType(gen, elementType); + OpCodeUtil.EmitStoreIndirectOpCodeForType(gen, elementType); + } + else if (elementType.IsGenericParameter || elementType.IsValueType) + { + gen.Emit(OpCodes.Initobj, elementType); + } + else + { + throw new ProxyGenerationException("Can't emit default value for reference of type " + elementType); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Expression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Expression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Expression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Expression.cs Sun Feb 13 20:46:08 2011 @@ -0,0 +1,23 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal abstract class Expression : IILEmitter + { + public abstract void Emit(IMemberEmitter member, ILGenerator gen); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ExpressionStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ExpressionStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ExpressionStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ExpressionStatement.cs Sun Feb 13 20:46:13 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class ExpressionStatement : Statement + { + private readonly Expression expression; + + public ExpressionStatement(Expression expression) + { + this.expression = expression; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + // TODO: Should it discard any possible return value with a pop? + expression.Emit(member, gen); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\FieldReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\FieldReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\FieldReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\FieldReference.cs Sun Feb 13 20:46:17 2011 @@ -0,0 +1,95 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + + [DebuggerDisplay("{fieldbuilder.Name} ({fieldbuilder.FieldType})")] + internal class FieldReference : Reference + { + private readonly FieldInfo field; + private readonly FieldBuilder fieldbuilder; + private readonly bool isStatic; + + public FieldReference(FieldInfo field) + { + this.field = field; + if ((field.Attributes & FieldAttributes.Static) != 0) + { + isStatic = true; + owner = null; + } + } + + public FieldReference(FieldBuilder fieldbuilder) + { + this.fieldbuilder = fieldbuilder; + this.field = fieldbuilder; + if ((fieldbuilder.Attributes & FieldAttributes.Static) != 0) + { + isStatic = true; + owner = null; + } + } + + public FieldBuilder Fieldbuilder + { + get { return fieldbuilder; } + } + + public FieldInfo Reference + { + get { return field; } + } + + public override void LoadReference(ILGenerator gen) + { + if (isStatic) + { + gen.Emit(OpCodes.Ldsfld, Reference); + } + else + { + gen.Emit(OpCodes.Ldfld, Reference); + } + } + + public override void StoreReference(ILGenerator gen) + { + if (isStatic) + { + gen.Emit(OpCodes.Stsfld, Reference); + } + else + { + gen.Emit(OpCodes.Stfld, Reference); + } + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + if (isStatic) + { + gen.Emit(OpCodes.Ldsflda, Reference); + } + else + { + gen.Emit(OpCodes.Ldflda, Reference); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IfNullExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IfNullExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IfNullExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IfNullExpression.cs Sun Feb 13 20:46:22 2011 @@ -0,0 +1,42 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class IfNullExpression : Expression + { + private readonly Expression ifNotNull; + private readonly Expression ifNull; + private readonly Reference reference; + + public IfNullExpression(Reference reference, Expression ifNull, Expression ifNotNull) + { + this.reference = reference; + this.ifNull = ifNull; + this.ifNotNull = ifNotNull; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(reference, gen); + var notNull = gen.DefineLabel(); + gen.Emit(OpCodes.Brtrue_S, notNull); + ifNull.Emit(member, gen); + gen.MarkLabel(notNull); + ifNotNull.Emit(member, gen); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IILEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IILEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IILEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IILEmitter.cs Sun Feb 13 20:46:26 2011 @@ -0,0 +1,23 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal interface IILEmitter + { + void Emit(IMemberEmitter member, ILGenerator gen); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IndirectReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IndirectReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IndirectReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\IndirectReference.cs Sun Feb 13 20:46:31 2011 @@ -0,0 +1,69 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + /// + /// Wraps a reference that is passed + /// ByRef and provides indirect load/store support. + /// + internal class IndirectReference : TypeReference + { + public IndirectReference(TypeReference byRefReference) : + base(byRefReference, byRefReference.Type.GetElementType()) + { + if (!byRefReference.Type.IsByRef) + { + throw new ArgumentException("Expected an IsByRef reference", "byRefReference"); + } + } + + // TODO: Better name + public static TypeReference WrapIfByRef(TypeReference reference) + { + return reference.Type.IsByRef ? new IndirectReference(reference) : reference; + } + + // TODO: Better name + public static TypeReference[] WrapIfByRef(TypeReference[] references) + { + TypeReference[] result = new TypeReference[references.Length]; + + for (int i = 0; i < references.Length; i++) + { + result[i] = WrapIfByRef(references[i]); + } + + return result; + } + + public override void LoadReference(ILGenerator gen) + { + OpCodeUtil.EmitLoadIndirectOpCodeForType(gen, Type); + } + + public override void StoreReference(ILGenerator gen) + { + OpCodeUtil.EmitStoreIndirectOpCodeForType(gen, Type); + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + // Load of owner reference takes care of this. + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LiteralIntExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LiteralIntExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LiteralIntExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LiteralIntExpression.cs Sun Feb 13 20:46:36 2011 @@ -0,0 +1,68 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class LiteralIntExpression : Expression + { + private readonly int value; + + public LiteralIntExpression(int value) + { + this.value = value; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + switch (value) + { + case -1: + gen.Emit(OpCodes.Ldc_I4_M1); + break; + case 0: + gen.Emit(OpCodes.Ldc_I4_0); + break; + case 1: + gen.Emit(OpCodes.Ldc_I4_1); + break; + case 2: + gen.Emit(OpCodes.Ldc_I4_2); + break; + case 3: + gen.Emit(OpCodes.Ldc_I4_3); + break; + case 4: + gen.Emit(OpCodes.Ldc_I4_4); + break; + case 5: + gen.Emit(OpCodes.Ldc_I4_5); + break; + case 6: + gen.Emit(OpCodes.Ldc_I4_6); + break; + case 7: + gen.Emit(OpCodes.Ldc_I4_7); + break; + case 8: + gen.Emit(OpCodes.Ldc_I4_8); + break; + default: + gen.Emit(OpCodes.Ldc_I4, value); + break; + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadArrayElementExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadArrayElementExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadArrayElementExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadArrayElementExpression.cs Sun Feb 13 20:46:40 2011 @@ -0,0 +1,45 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class LoadArrayElementExpression : Expression + { + private readonly ConstReference index; + private readonly Reference arrayReference; + private readonly Type returnType; + + public LoadArrayElementExpression(int index, Reference arrayReference, Type returnType) + : this(new ConstReference(index), arrayReference, returnType) + { + } + + public LoadArrayElementExpression(ConstReference index, Reference arrayReference, Type returnType) + { + this.index = index; + this.arrayReference = arrayReference; + this.returnType = returnType; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(arrayReference, gen); + ArgumentsUtil.EmitLoadOwnerAndReference(index, gen); + gen.Emit(OpCodes.Ldelem, returnType); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadRefArrayElementExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadRefArrayElementExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadRefArrayElementExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadRefArrayElementExpression.cs Sun Feb 13 20:45:49 2011 @@ -0,0 +1,42 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class LoadRefArrayElementExpression : Expression + { + private readonly ConstReference index; + private readonly Reference arrayReference; + + public LoadRefArrayElementExpression(int index, Reference arrayReference) + : this(new ConstReference(index), arrayReference) + { + } + + public LoadRefArrayElementExpression(ConstReference index, Reference arrayReference) + { + this.index = index; + this.arrayReference = arrayReference; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(arrayReference, gen); + ArgumentsUtil.EmitLoadOwnerAndReference(index, gen); + gen.Emit(OpCodes.Ldelem_Ref); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LocalReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LocalReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LocalReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\LocalReference.cs Sun Feb 13 20:46:48 2011 @@ -0,0 +1,48 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class LocalReference : TypeReference + { + private LocalBuilder localbuilder; + + public LocalReference(Type type) : base(type) + { + } + + public override void Generate(ILGenerator gen) + { + localbuilder = gen.DeclareLocal(base.Type); + } + + public override void LoadReference(ILGenerator gen) + { + gen.Emit(OpCodes.Ldloc, localbuilder); + } + + public override void StoreReference(ILGenerator gen) + { + gen.Emit(OpCodes.Stloc, localbuilder); + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + gen.Emit(OpCodes.Ldloca, localbuilder); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodInvocationExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodInvocationExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodInvocationExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodInvocationExpression.cs Sun Feb 13 20:46:53 2011 @@ -0,0 +1,69 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection; + using System.Reflection.Emit; + + internal class MethodInvocationExpression : Expression + { + protected readonly MethodInfo method; + protected readonly Expression[] args; + protected readonly Reference owner; + + public MethodInvocationExpression(MethodInfo method, params Expression[] args) : + this(SelfReference.Self, method, args) + { + } + + public MethodInvocationExpression(MethodEmitter method, params Expression[] args) : + this(SelfReference.Self, method.MethodBuilder, args) + { + } + + public MethodInvocationExpression(Reference owner, MethodEmitter method, params Expression[] args) : + this(owner, method.MethodBuilder, args) + { + } + + public MethodInvocationExpression(Reference owner, MethodInfo method, params Expression[] args) + { + this.owner = owner; + this.method = method; + this.args = args; + } + + public bool VirtualCall { get; set; } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(owner, gen); + + foreach (Expression exp in args) + { + exp.Emit(member, gen); + } + + if (VirtualCall) + { + gen.Emit(OpCodes.Callvirt, method); + } + else + { + gen.Emit(OpCodes.Call, method); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodTokenExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodTokenExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodTokenExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodTokenExpression.cs Sun Feb 13 20:46:58 2011 @@ -0,0 +1,57 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + using Castle.DynamicProxy.Tokens; + + internal class MethodTokenExpression : Expression + { + private readonly MethodInfo method; +#if !MONO + private readonly Type declaringType; +#endif + public MethodTokenExpression(MethodInfo method) + { + this.method = method; +#if !MONO + declaringType = method.DeclaringType; +#endif + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + gen.Emit(OpCodes.Ldtoken, method); +#if !MONO + if (declaringType == null) + { + throw new GeneratorException("declaringType can't be null for this situation"); + } + gen.Emit(OpCodes.Ldtoken, declaringType); +#endif + + MethodInfo minfo = MethodBaseMethods.GetMethodFromHandle1; + +#if !MONO + minfo = MethodBaseMethods.GetMethodFromHandle2; +#endif + + gen.Emit(OpCodes.Call, minfo); + gen.Emit(OpCodes.Castclass, typeof (MethodInfo)); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MultiStatementExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MultiStatementExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MultiStatementExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\MultiStatementExpression.cs Sun Feb 13 20:47:04 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + internal class MultiStatementExpression : Expression + { + private readonly List statements = new List(); + + public void AddStatement(Statement statement) + { + statements.Add(statement); + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + statements.ForEach(s => s.Emit(member, gen)); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewArrayExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewArrayExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewArrayExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewArrayExpression.cs Sun Feb 13 20:47:08 2011 @@ -0,0 +1,40 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + /// + /// Summary description for NewArrayExpression. + /// + internal class NewArrayExpression : Expression + { + private readonly int size; + private readonly Type arrayType; + + public NewArrayExpression(int size, Type arrayType) + { + this.size = size; + this.arrayType = arrayType; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + gen.Emit(OpCodes.Ldc_I4, size); + gen.Emit(OpCodes.Newarr, arrayType); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewInstanceExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewInstanceExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewInstanceExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewInstanceExpression.cs Sun Feb 13 20:47:14 2011 @@ -0,0 +1,61 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + internal class NewInstanceExpression : Expression + { + private readonly Type type; + private readonly Type[] constructorArgs; + private readonly Expression[] arguments; + private ConstructorInfo constructor; + + public NewInstanceExpression(ConstructorInfo constructor, params Expression[] args) + { + this.constructor = constructor; + arguments = args; + } + + public NewInstanceExpression(Type target, Type[] constructor_args, params Expression[] args) + { + type = target; + this.constructorArgs = constructor_args; + arguments = args; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + foreach (Expression exp in arguments) + { + exp.Emit(member, gen); + } + + if (constructor == null) + { + constructor = type.GetConstructor(constructorArgs); + } + + if (constructor == null) + { + throw new ProxyGenerationException("Could not find constructor matching specified arguments"); + } + + gen.Emit(OpCodes.Newobj, constructor); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NopStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NopStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NopStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NopStatement.cs Sun Feb 13 20:47:19 2011 @@ -0,0 +1,26 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class NopStatement : Statement + { + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + gen.Emit(OpCodes.Nop); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullCoalescingOperatorExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullCoalescingOperatorExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullCoalescingOperatorExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullCoalescingOperatorExpression.cs Sun Feb 13 20:47:24 2011 @@ -0,0 +1,52 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class NullCoalescingOperatorExpression:Expression + { + private readonly Expression expression; + private readonly Expression @default; + + public NullCoalescingOperatorExpression(Expression expression, Expression @default) + { + if (expression == null) + { + throw new ArgumentNullException("expression"); + } + + if (@default == null) + { + throw new ArgumentNullException("default"); + } + + this.expression = expression; + this.@default = @default; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + expression.Emit(member, gen); + gen.Emit(OpCodes.Dup); + var label = gen.DefineLabel(); + gen.Emit(OpCodes.Brtrue_S, label); + gen.Emit(OpCodes.Pop); + @default.Emit(member, gen); + gen.MarkLabel(label); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullExpression.cs Sun Feb 13 20:47:28 2011 @@ -0,0 +1,32 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class NullExpression : Expression + { + public static readonly NullExpression Instance = new NullExpression(); + + protected NullExpression() + { + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + gen.Emit(OpCodes.Ldnull); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Reference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Reference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Reference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Reference.cs Sun Feb 13 20:47:33 2011 @@ -0,0 +1,58 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal abstract class Reference + { + protected Reference owner = SelfReference.Self; + + protected Reference() + { + } + + protected Reference(Reference owner) + { + this.owner = owner; + } + + public Reference OwnerReference + { + get { return owner; } + set { owner = value; } + } + + public virtual Expression ToExpression() + { + return new ReferenceExpression(this); + } + + public virtual Expression ToAddressOfExpression() + { + return new AddressOfReferenceExpression(this); + } + + public virtual void Generate(ILGenerator gen) + { + } + + public abstract void LoadAddressOfReference(ILGenerator gen); + + public abstract void LoadReference(ILGenerator gen); + + public abstract void StoreReference(ILGenerator gen); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferenceExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferenceExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferenceExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferenceExpression.cs Sun Feb 13 20:47:37 2011 @@ -0,0 +1,33 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class ReferenceExpression : Expression + { + private readonly Reference reference; + + public ReferenceExpression(Reference reference) + { + this.reference = reference; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ArgumentsUtil.EmitLoadOwnerAndReference(reference, gen); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferencesToObjectArrayExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferencesToObjectArrayExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferencesToObjectArrayExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferencesToObjectArrayExpression.cs Sun Feb 13 20:47:41 2011 @@ -0,0 +1,69 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + /// + /// + /// + internal class ReferencesToObjectArrayExpression : Expression + { + private readonly TypeReference[] args; + + public ReferencesToObjectArrayExpression(params TypeReference[] args) + { + this.args = args; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + LocalBuilder local = gen.DeclareLocal(typeof (object[])); + + gen.Emit(OpCodes.Ldc_I4, args.Length); + gen.Emit(OpCodes.Newarr, typeof (object)); + gen.Emit(OpCodes.Stloc, local); + + for (int i = 0; i < args.Length; i++) + { + gen.Emit(OpCodes.Ldloc, local); + gen.Emit(OpCodes.Ldc_I4, i); + + TypeReference reference = args[i]; + + ArgumentsUtil.EmitLoadOwnerAndReference(reference, gen); + + if (reference.Type.IsByRef) + { + throw new NotSupportedException(); + } + + if (reference.Type.IsValueType) + { + gen.Emit(OpCodes.Box, reference.Type.UnderlyingSystemType); + } + if (reference.Type.IsGenericParameter) + { + gen.Emit(OpCodes.Box, reference.Type); + } + + gen.Emit(OpCodes.Stelem_Ref); + } + + gen.Emit(OpCodes.Ldloc, local); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnReferenceExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnReferenceExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnReferenceExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnReferenceExpression.cs Sun Feb 13 20:47:46 2011 @@ -0,0 +1,39 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class ReturnReferenceExpression : TypeReference + { + public ReturnReferenceExpression(Type argumentType) : base(argumentType) + { + } + + public override void LoadReference(ILGenerator gen) + { + } + + public override void StoreReference(ILGenerator gen) + { + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + throw new NotSupportedException(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnStatement.cs Sun Feb 13 20:47:50 2011 @@ -0,0 +1,59 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal class ReturnStatement : Statement + { + private readonly Reference reference; + private readonly Expression expression; + + public ReturnStatement() + { + } + + public ReturnStatement(Reference reference) + { + this.reference = reference; + } + + public ReturnStatement(Expression expression) + { + this.expression = expression; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + if (reference != null) + { + ArgumentsUtil.EmitLoadOwnerAndReference(reference, gen); + } + else if (expression != null) + { + expression.Emit(member, gen); + } + else + { + if (member.ReturnType != typeof (void)) + { + OpCodeUtil.EmitLoadOpCodeForDefaultValueOfType(gen, member.ReturnType); + } + } + + gen.Emit(OpCodes.Ret); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\SelfReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\SelfReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\SelfReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\SelfReference.cs Sun Feb 13 20:47:55 2011 @@ -0,0 +1,43 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + + internal class SelfReference : Reference + { + public static readonly SelfReference Self = new SelfReference(); + + protected SelfReference() : base(null) + { + } + + public override void LoadReference(ILGenerator gen) + { + gen.Emit(OpCodes.Ldarg_0); + } + + public override void StoreReference(ILGenerator gen) + { + gen.Emit(OpCodes.Ldarg_0); + } + + public override void LoadAddressOfReference(ILGenerator gen) + { + throw new NotSupportedException(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Statement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Statement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Statement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\Statement.cs Sun Feb 13 20:48:01 2011 @@ -0,0 +1,23 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System.Reflection.Emit; + + internal abstract class Statement : IILEmitter + { + public abstract void Emit(IMemberEmitter member, ILGenerator gen); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ThrowStatement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ThrowStatement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ThrowStatement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\ThrowStatement.cs Sun Feb 13 20:48:05 2011 @@ -0,0 +1,44 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + internal class ThrowStatement : Statement + { + private readonly Type exceptionType; + private readonly string errorMessage; + + public ThrowStatement(Type exceptionType, String errorMessage) + { + this.exceptionType = exceptionType; + this.errorMessage = errorMessage; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + ConstructorInfo ci = exceptionType.GetConstructor(new[] {typeof (String)}); + var constRef = new ConstReference(errorMessage); + + var creationStmt = new NewInstanceExpression(ci, constRef.ToExpression()); + + creationStmt.Emit(member, gen); + + gen.Emit(OpCodes.Throw); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeReference.cs Sun Feb 13 20:48:12 2011 @@ -0,0 +1,37 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + + internal abstract class TypeReference : Reference + { + private readonly Type type; + + protected TypeReference(Type argumentType) : this(null, argumentType) + { + } + + protected TypeReference(Reference owner, Type type) : base(owner) + { + this.type = type; + } + + public Type Type + { + get { return type; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeTokenExpression.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeTokenExpression.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeTokenExpression.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeTokenExpression.cs Sun Feb 13 20:48:17 2011 @@ -0,0 +1,36 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST +{ + using System; + using System.Reflection.Emit; + using Castle.DynamicProxy.Tokens; + + internal class TypeTokenExpression : Expression + { + private readonly Type type; + + public TypeTokenExpression(Type type) + { + this.type = type; + } + + public override void Emit(IMemberEmitter member, ILGenerator gen) + { + gen.Emit(OpCodes.Ldtoken, type); + gen.Emit(OpCodes.Call, TypeMethods.GetTypeFromHandle); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StindOpCodesDictionary.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StindOpCodesDictionary.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StindOpCodesDictionary.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StindOpCodesDictionary.cs Sun Feb 13 20:54:43 2011 @@ -0,0 +1,68 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Reflection.Emit; + + /// + /// Provides appropriate Stind.X opcode + /// for the type of primitive value to be stored indirectly. + /// + internal sealed class StindOpCodesDictionary : Dictionary + { + private static readonly StindOpCodesDictionary dict = new StindOpCodesDictionary(); + + // has to be assigned explicitly to suppress compiler warning + private static readonly OpCode emptyOpCode = new OpCode(); + + private StindOpCodesDictionary() + { + Add(typeof(bool), OpCodes.Stind_I1); + Add(typeof(char), OpCodes.Stind_I2); + Add(typeof(SByte), OpCodes.Stind_I1); + Add(typeof(Int16), OpCodes.Stind_I2); + Add(typeof(Int32), OpCodes.Stind_I4); + Add(typeof(Int64), OpCodes.Stind_I8); + Add(typeof(float), OpCodes.Stind_R4); + Add(typeof(double), OpCodes.Stind_R8); + Add(typeof(byte), OpCodes.Stind_I1); + Add(typeof(UInt16), OpCodes.Stind_I2); + Add(typeof(UInt32), OpCodes.Stind_I4); + Add(typeof(UInt64), OpCodes.Stind_I8); + } + + public new OpCode this[Type type] + { + get + { + if (ContainsKey(type)) + return base[type]; + return EmptyOpCode; + } + } + + public static StindOpCodesDictionary Instance + { + get { return dict; } + } + + public static OpCode EmptyOpCode + { + get { return emptyOpCode; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StrongNameUtil.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StrongNameUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StrongNameUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\StrongNameUtil.cs Sun Feb 13 20:54:49 2011 @@ -0,0 +1,102 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; +#if !SILVERLIGHT + using System.Security; + using System.Security.Permissions; +#endif + + internal static class StrongNameUtil + { + private static readonly IDictionary signedAssemblyCache = new Dictionary(); +#if !SILVERLIGHT + private static readonly bool canStrongNameAssembly; +#endif + private static readonly object lockObject = new object(); + +#if !SILVERLIGHT +#if DOTNET40 + [SecuritySafeCritical] +#endif + static StrongNameUtil() + { + //idea after http://blogs.msdn.com/dmitryr/archive/2007/01/23/finding-out-the-current-trust-level-in-asp-net.aspx + try + { + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); + canStrongNameAssembly = true; + } + catch (SecurityException) + { + canStrongNameAssembly = false; + } + } +#endif + + public static bool IsAssemblySigned(Assembly assembly) + { + lock (lockObject) + { + if (signedAssemblyCache.ContainsKey(assembly) == false) + { + bool isSigned = ContainsPublicKey(assembly); + signedAssemblyCache.Add(assembly, isSigned); + } + return signedAssemblyCache[assembly]; + } + } + + private static bool ContainsPublicKey(Assembly assembly) + { + // Pulled from a comment on http://www.flawlesscode.com/post/2008/08/Mocking-and-IOC-in-Silverlight-2-Castle-Project-and-Moq-ports.aspx + if (assembly.FullName != null) + return !assembly.FullName.Contains("PublicKeyToken=null"); + return false; + } + + public static bool IsAnyTypeFromUnsignedAssembly(IEnumerable types) + { + return types.Any(t => IsAssemblySigned(t.Assembly) == false); + } + + public static bool IsAnyTypeFromUnsignedAssembly(Type baseType, IEnumerable interfaces) + { + if (baseType != null && IsAssemblySigned(baseType.Assembly) == false) + { + return true; + } + + return IsAnyTypeFromUnsignedAssembly(interfaces); + } + + public static bool CanStrongNameAssembly + { + get + { + return +#if SILVERLIGHT + false; +#else + canStrongNameAssembly; +#endif + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeConstructorEmitter.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeConstructorEmitter.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeConstructorEmitter.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeConstructorEmitter.cs Sun Feb 13 20:13:09 2011 @@ -0,0 +1,34 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal class TypeConstructorEmitter : ConstructorEmitter + { + internal TypeConstructorEmitter(AbstractTypeEmitter maintype) + : base(maintype, maintype.TypeBuilder.DefineTypeInitializer()) + { + } + + public override void EnsureValidCodeBlock() + { + if (CodeBuilder.IsEmpty) + { + CodeBuilder.AddStatement(new ReturnStatement()); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeUtil.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\Emitters\TypeUtil.cs Sun Feb 13 20:14:21 2011 @@ -0,0 +1,191 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + + internal static class TypeUtil + { + public static FieldInfo[] GetAllFields(this Type type) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + if (type.IsClass == false) + { + throw new ArgumentException(string.Format("Type {0} is not a class type. This method supports only classes", type)); + } + + var fields = new List(); + var currentType = type; + while (currentType != typeof(object)) + { + var currentFields = + currentType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); + fields.AddRange(currentFields); + currentType = currentType.BaseType; + } + + return fields.ToArray(); + } + + /// + /// Returns list of all unique interfaces implemented given types, including their base interfaces. + /// + /// + /// + public static ICollection GetAllInterfaces(params Type[] types) + { + if (types == null) + { + return Type.EmptyTypes; + } + + var dummy = new object(); + // we should move this to HashSet once we no longer support .NET 2.0 + IDictionary interfaces = new Dictionary(); + foreach (var type in types) + { + if (type == null) + { + continue; + } + + if (type.IsInterface) + { + interfaces[type] = dummy; + } + + foreach (var @interface in type.GetInterfaces()) + { + interfaces[@interface] = dummy; + } + } + + return Sort(interfaces.Keys); + } + + public static ICollection GetAllInterfaces(this Type type) + { + return GetAllInterfaces(new[] { type }); + } + + public static Type GetClosedParameterType(this AbstractTypeEmitter type, Type parameter) + { + if (parameter.IsGenericTypeDefinition) + { + return parameter.GetGenericTypeDefinition().MakeGenericType(type.GetGenericArgumentsFor(parameter)); + } + + if (parameter.IsGenericType) + { + var arguments = parameter.GetGenericArguments(); + if (CloseGenericParametersIfAny(type, arguments)) + { + return parameter.GetGenericTypeDefinition().MakeGenericType(arguments); + } + } + + if (parameter.IsGenericParameter) + { + return type.GetGenericArgument(parameter.Name); + } + + if (parameter.IsArray) + { + var elementType = GetClosedParameterType(type, parameter.GetElementType()); + return elementType.MakeArrayType(); + } + + if (parameter.IsByRef) + { + var elementType = GetClosedParameterType(type, parameter.GetElementType()); + return elementType.MakeByRefType(); + } + + return parameter; + } + + public static void SetStaticField(this Type type, string fieldName, BindingFlags additionalFlags, object value) + { + var flags = additionalFlags | BindingFlags.Static | BindingFlags.SetField; + + try + { + type.InvokeMember(fieldName, flags, null, null, new[] { value }); + } + catch (MissingFieldException e) + { + throw new ProxyGenerationException( + string.Format( + "Could not find field named '{0}' on type {1}. This is likely a bug in DynamicProxy. Please report it.", + fieldName, + type), e); + } + catch (TargetException e) + { + throw new ProxyGenerationException( + string.Format( + "There was an error trying to set field named '{0}' on type {1}. This is likely a bug in DynamicProxy. Please report it.", + fieldName, + type), e); + } + catch (TargetInvocationException e) // yes, this is not documented in MSDN. Yay for documentation + { + if ((e.InnerException is TypeInitializationException) == false) + { + throw; + } + throw new ProxyGenerationException( + string.Format( + "There was an error in static constructor on type {0}. This is likely a bug in DynamicProxy. Please report it.", + type), e); + } + } + + public static MemberInfo[] Sort(MemberInfo[] members) + { + Array.Sort(members, (l, r) => string.Compare(l.Name, r.Name)); + return members; + } + + private static bool CloseGenericParametersIfAny(AbstractTypeEmitter emitter, Type[] arguments) + { + var hasAnyGenericParameters = false; + for (var i = 0; i < arguments.Length; i++) + { + var newType = GetClosedParameterType(emitter, arguments[i]); + if (!ReferenceEquals(newType, arguments[i])) + { + arguments[i] = newType; + hasAnyGenericParameters = true; + } + } + return hasAnyGenericParameters; + } + + private static Type[] Sort(IEnumerable types) + { + var array = types.ToArray(); + //NOTE: is there a better, stable way to sort Types. We will need to revise this once we allow open generics + Array.Sort(array, (l, r) => string.Compare(l.AssemblyQualifiedName, r.AssemblyQualifiedName)); + return array; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorException.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorException.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorException.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorException.cs Sun Feb 13 20:36:56 2011 @@ -0,0 +1,39 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Runtime.Serialization; + +#if !SILVERLIGHT + [Serializable] +#endif + internal class GeneratorException : Exception + { + public GeneratorException(string message) : base(message) + { + } + + public GeneratorException(string message, Exception innerException) : base(message, innerException) + { + } + +#if !SILVERLIGHT + public GeneratorException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +#endif + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorUtil.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorUtil.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorUtil.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\GeneratorUtil.cs Sun Feb 13 20:37:02 2011 @@ -0,0 +1,65 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal static class GeneratorUtil + { + public static void CopyOutAndRefParameters(TypeReference[] dereferencedArguments, LocalReference invocation, MethodInfo method, MethodEmitter emitter) + { + var parameters = method.GetParameters(); + if (!ArgumentsUtil.IsAnyByRef(parameters)) + { + return; //saving the need to create locals if there is no need + } + + var arguments = StoreInvocationArgumentsInLocal(emitter, invocation); + + for (int i = 0; i < parameters.Length; i++) + { + if (!parameters[i].ParameterType.IsByRef) continue; + + emitter.CodeBuilder.AddStatement(AssignArgument(dereferencedArguments, i, arguments)); + } + } + + private static AssignStatement AssignArgument(TypeReference[] dereferencedArguments, int i, LocalReference invocationArgs) + { + return new AssignStatement(dereferencedArguments[i], Argument(i, invocationArgs, dereferencedArguments)); + } + + private static ConvertExpression Argument(int i, LocalReference invocationArgs, TypeReference[] arguments) + { + return new ConvertExpression(arguments[i].Type, new LoadRefArrayElementExpression(i, invocationArgs)); + } + + private static LocalReference StoreInvocationArgumentsInLocal(MethodEmitter emitter, LocalReference invocation) + { + var invocationArgs = emitter.CodeBuilder.DeclareLocal(typeof(object[])); + emitter.CodeBuilder.AddStatement(GetArguments(invocationArgs, invocation)); + return invocationArgs; + } + + private static AssignStatement GetArguments(LocalReference invocationArgs, LocalReference invocation) + { + return new AssignStatement(invocationArgs, new MethodInvocationExpression(invocation, InvocationMethods.GetArguments)); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\IGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\IGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\IGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\IGenerator.cs Sun Feb 13 20:06:33 2011 @@ -0,0 +1,23 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using Emitters; + + internal interface IGenerator + { + T Generate(ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\IInvocationCreationContributor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\IInvocationCreationContributor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\IInvocationCreationContributor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\IInvocationCreationContributor.cs Sun Feb 13 20:08:17 2011 @@ -0,0 +1,32 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + + internal interface IInvocationCreationContributor + { + ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, AbstractTypeEmitter invocation); + + MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, Expression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget); + + MethodInfo GetCallbackMethod(); + + Expression[] GetConstructorInvocationArguments(Expression[] arguments, ClassEmitter proxy); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\INamingScope.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\INamingScope.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\INamingScope.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\INamingScope.cs Sun Feb 13 20:37:11 2011 @@ -0,0 +1,45 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + /// + /// Represents the scope of uniquenes of names for types and their members + /// + internal interface INamingScope + { + /// + /// Gets a unique name based on + /// + /// Name suggested by the caller + /// Unique name based on . + /// + /// Implementers should provide name as closely resembling as possible. + /// Generally if no collision occurs it is suggested to return suggested name, otherwise append sequential suffix. + /// Implementers must return deterministic names, that is when is called twice + /// with the same suggested name, the same returned name should be provided each time. Non-deterministic return + /// values, like appending random suffices will break serialization of proxies. + /// + string GetUniqueName(string suggestedName); + + /// + /// Returns new, disposable naming scope. It is responsibilty of the caller to make sure that no naming collision + /// with enclosing scope, or other subscopes is possible. + /// + /// New naming scope. + INamingScope SafeSubScope(); + + INamingScope ParentScope { get; } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InheritanceInvocationTypeGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InheritanceInvocationTypeGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InheritanceInvocationTypeGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InheritanceInvocationTypeGenerator.cs Sun Feb 13 20:08:24 2011 @@ -0,0 +1,70 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal class InheritanceInvocationTypeGenerator : InvocationTypeGenerator + { + public static readonly Type BaseType = typeof(InheritanceInvocation); + + public InheritanceInvocationTypeGenerator(Type targetType, MetaMethod method, MethodInfo callback, IInvocationCreationContributor contributor) + : base(targetType, method, callback, false,contributor) + { + } + + protected override FieldReference GetTargetReference() + { + return new FieldReference(InvocationMethods.ProxyObject); + } + + protected override Type GetBaseType() + { + return BaseType; + } + + protected override ArgumentReference[] GetBaseCtorArguments(Type targetFieldType, ProxyGenerationOptions proxyGenerationOptions, out ConstructorInfo baseConstructor) + { + if (proxyGenerationOptions.Selector == null) + { + baseConstructor = InvocationMethods.InheritanceInvocationConstructorNoSelector; + return new[] + { + new ArgumentReference(typeof(Type)), + new ArgumentReference(typeof(object)), + new ArgumentReference(typeof(IInterceptor[])), + new ArgumentReference(typeof(MethodInfo)), + new ArgumentReference(typeof(object[])) + }; + } + + baseConstructor = InvocationMethods.InheritanceInvocationConstructorWithSelector; + return new[] + { + new ArgumentReference(typeof(Type)), + new ArgumentReference(typeof(object)), + new ArgumentReference(typeof(IInterceptor[])), + new ArgumentReference(typeof(MethodInfo)), + new ArgumentReference(typeof(object[])), + new ArgumentReference(typeof(IInterceptorSelector)), + new ArgumentReference(typeof(IInterceptor[]).MakeByRefType()) + }; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithoutTargetGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithoutTargetGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithoutTargetGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithoutTargetGenerator.cs Sun Feb 13 20:07:21 2011 @@ -0,0 +1,103 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Serialization; + + + internal class InterfaceProxyWithoutTargetGenerator : InterfaceProxyWithTargetGenerator + { + public InterfaceProxyWithoutTargetGenerator(ModuleScope scope, Type @interface) : base(scope, @interface) + { + } + + protected override ITypeContributor AddMappingForTargetType(IDictionary interfaceTypeImplementerMapping, Type proxyTargetType, ICollection targetInterfaces, ICollection additionalInterfaces, INamingScope namingScope) + { + var contributor = new InterfaceProxyWithoutTargetContributor(namingScope, (c, m) => NullExpression.Instance) + { Logger = Logger }; + foreach (var @interface in targetType.GetAllInterfaces()) + { + contributor.AddInterfaceToProxy(@interface); + AddMappingNoCheck(@interface, contributor, interfaceTypeImplementerMapping); + } + return contributor; + } + + protected override Type GenerateType(string typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope) + { + IEnumerable contributors; + var allInterfaces = GetTypeImplementerMapping(interfaces, targetType, out contributors,namingScope); + var model = new MetaType(); + // collect elements + foreach (var contributor in contributors) + { + contributor.CollectElementsToProxy(ProxyGenerationOptions.Hook,model); + } + + ProxyGenerationOptions.Hook.MethodsInspected(); + + ClassEmitter emitter; + FieldReference interceptorsField; + Type baseType = Init(typeName, out emitter, proxyTargetType, out interceptorsField, allInterfaces); + + + + // Constructor + + var cctor = GenerateStaticConstructor(emitter); + var mixinFieldsList = new List(); + + foreach (var contributor in contributors) + { + contributor.Generate(emitter, ProxyGenerationOptions); + + // TODO: redo it + if (contributor is MixinContributor) + { + mixinFieldsList.AddRange((contributor as MixinContributor).Fields); + } + } + + var ctorArguments = new List(mixinFieldsList) { interceptorsField, targetField }; + var selector = emitter.GetField("__selector"); + if (selector != null) + { + ctorArguments.Add(selector); + } + + GenerateConstructors(emitter, baseType, ctorArguments.ToArray()); + + // Complete type initializer code body + CompleteInitCacheMethod(cctor.CodeBuilder); + + // Crosses fingers and build type + Type generatedType = emitter.BuildType(); + + InitializeStaticFields(generatedType); + return generatedType; + } + + + protected override string GeneratorType + { + get { return ProxyTypeConstants.InterfaceWithoutTarget; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetGenerator.cs Sun Feb 13 20:08:46 2011 @@ -0,0 +1,287 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using System.Xml.Serialization; + + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Serialization; + + internal class InterfaceProxyWithTargetGenerator : BaseProxyGenerator + { + protected FieldReference targetField; + + + public InterfaceProxyWithTargetGenerator(ModuleScope scope, Type @interface) + : base(scope, @interface) + { + CheckNotGenericTypeDefinition(@interface, "@interface"); + } + + public Type GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options) + { + // make sure ProxyGenerationOptions is initialized + options.Initialize(); + + CheckNotGenericTypeDefinition(proxyTargetType, "proxyTargetType"); + CheckNotGenericTypeDefinitions(interfaces, "interfaces"); + EnsureValidBaseType(options.BaseTypeForInterfaceProxy); + ProxyGenerationOptions = options; + + interfaces = TypeUtil.GetAllInterfaces(interfaces).ToArray(); + var cacheKey = new CacheKey(proxyTargetType, targetType, interfaces, options); + + return ObtainProxyType(cacheKey, (n, s) => GenerateType(n, proxyTargetType, interfaces, s)); + + } + + private void EnsureValidBaseType(Type type) + { + if (type == null) + { + throw new ArgumentException( + "Base type for proxy is null reference. Please set it to System.Object or some other valid type."); + } + + if (!type.IsClass) + { + ThrowInvalidBaseType(type, "it is not a class type"); + } + + if(type.IsSealed) + { + ThrowInvalidBaseType(type, "it is sealed"); + } + + var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, Type.EmptyTypes, null); + + if (constructor == null || constructor.IsPrivate) + { + ThrowInvalidBaseType(type, "it does not have accessible parameterless constructor"); + } + } + + private void ThrowInvalidBaseType(Type type, string doesNotHaveAccessibleParameterlessConstructor) + { + var format = "Type {0} is not valid base type for interface proxy, because {1}. Only a non-sealed class with non-private default constructor can be used as base type for interface proxy. Please use some other valid type."; + throw new ArgumentException(string.Format(format, type, doesNotHaveAccessibleParameterlessConstructor)); + } + + protected virtual Type GenerateType(string typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope) + { + IEnumerable contributors; + var allInterfaces = GetTypeImplementerMapping(interfaces, proxyTargetType, out contributors, namingScope); + + ClassEmitter emitter; + FieldReference interceptorsField; + Type baseType = Init(typeName, out emitter, proxyTargetType, out interceptorsField, allInterfaces); + + var model = new MetaType(); + // Collect methods + foreach (var contributor in contributors) + { + contributor.CollectElementsToProxy(ProxyGenerationOptions.Hook, model); + } + + ProxyGenerationOptions.Hook.MethodsInspected(); + + // Constructor + + var cctor = GenerateStaticConstructor(emitter); + var ctorArguments = new List(); + + foreach (var contributor in contributors) + { + contributor.Generate(emitter, ProxyGenerationOptions); + + // TODO: redo it + if (contributor is MixinContributor) + { + ctorArguments.AddRange((contributor as MixinContributor).Fields); + + } + } + + ctorArguments.Add(interceptorsField); + ctorArguments.Add(targetField); + var selector = emitter.GetField("__selector"); + if (selector != null) + { + ctorArguments.Add(selector); + } + + GenerateConstructors(emitter, baseType, ctorArguments.ToArray()); + + // Complete type initializer code body + CompleteInitCacheMethod(cctor.CodeBuilder); + + // Crosses fingers and build type + Type generatedType = emitter.BuildType(); + + InitializeStaticFields(generatedType); + return generatedType; + } + + protected virtual Type Init(string typeName, out ClassEmitter emitter, Type proxyTargetType, out FieldReference interceptorsField, IEnumerable interfaces) + { + Type baseType = ProxyGenerationOptions.BaseTypeForInterfaceProxy; + + emitter = BuildClassEmitter(typeName, baseType, interfaces); + + CreateFields(emitter, proxyTargetType); + CreateTypeAttributes(emitter); + + interceptorsField = emitter.GetField("__interceptors"); + return baseType; + } + + private void CreateFields(ClassEmitter emitter, Type proxyTargetType) + { + base.CreateFields(emitter); + targetField = emitter.CreateField("__target", proxyTargetType); + + emitter.DefineCustomAttributeFor(targetField); + } + + protected override void CreateTypeAttributes(ClassEmitter emitter) + { + base.CreateTypeAttributes(emitter); +#if (!SILVERLIGHT) + emitter.DefineCustomAttribute(); +#endif + } + + protected virtual string GeneratorType + { + get { return ProxyTypeConstants.InterfaceWithTarget; } + } + + protected virtual bool AllowChangeTarget + { + get { return false; } + } + + protected virtual IEnumerable GetTypeImplementerMapping(Type[] interfaces, Type proxyTargetType, out IEnumerable contributors, INamingScope namingScope) + { + IDictionary typeImplementerMapping = new Dictionary(); + var mixins = new MixinContributor(namingScope, AllowChangeTarget) { Logger = Logger }; + // Order of interface precedence: + // 1. first target + ICollection targetInterfaces = proxyTargetType.GetAllInterfaces(); + ICollection additionalInterfaces = TypeUtil.GetAllInterfaces(interfaces); + var target = AddMappingForTargetType(typeImplementerMapping, proxyTargetType, targetInterfaces, additionalInterfaces,namingScope); + + // 2. then mixins + if (ProxyGenerationOptions.HasMixins) + { + foreach (var mixinInterface in ProxyGenerationOptions.MixinData.MixinInterfaces) + { + if (targetInterfaces.Contains(mixinInterface)) + { + // OK, so the target implements this interface. We now do one of two things: + if(additionalInterfaces.Contains(mixinInterface)) + { + // we intercept the interface, and forward calls to the target type + AddMapping(mixinInterface, target, typeImplementerMapping); + } + // we do not intercept the interface + mixins.AddEmptyInterface(mixinInterface); + } + else + { + if (!typeImplementerMapping.ContainsKey(mixinInterface)) + { + mixins.AddInterfaceToProxy(mixinInterface); + typeImplementerMapping.Add(mixinInterface, mixins); + } + } + } + } + + var additionalInterfacesContributor = GetContributorForAdditionalInterfaces(namingScope); + // 3. then additional interfaces + foreach (var @interface in additionalInterfaces) + { + if(typeImplementerMapping.ContainsKey(@interface)) continue; + if(ProxyGenerationOptions.MixinData.ContainsMixin(@interface)) continue; + + additionalInterfacesContributor.AddInterfaceToProxy(@interface); + AddMappingNoCheck(@interface, additionalInterfacesContributor, typeImplementerMapping); + } + + // 4. plus special interfaces + var instance = new InterfaceProxyInstanceContributor(targetType, GeneratorType, interfaces); + AddMappingForISerializable(typeImplementerMapping, instance); + try + { + AddMappingNoCheck(typeof(IProxyTargetAccessor), instance, typeImplementerMapping); + } + catch (ArgumentException) + { + HandleExplicitlyPassedProxyTargetAccessor(targetInterfaces, additionalInterfaces); + } + + contributors = new List + { + target, + additionalInterfacesContributor, + mixins, + instance + }; + return typeImplementerMapping.Keys; + } + + protected virtual InterfaceProxyWithoutTargetContributor GetContributorForAdditionalInterfaces(INamingScope namingScope) + { + return new InterfaceProxyWithoutTargetContributor(namingScope, (c, m) => NullExpression.Instance) { Logger = Logger }; + } + + protected virtual ITypeContributor AddMappingForTargetType(IDictionary typeImplementerMapping, Type proxyTargetType, ICollection targetInterfaces, ICollection additionalInterfaces,INamingScope namingScope) + { + var contributor = new InterfaceProxyTargetContributor(proxyTargetType, AllowChangeTarget, namingScope) + { Logger = Logger }; + ICollection proxiedInterfaces = targetType.GetAllInterfaces(); + foreach (var @interface in proxiedInterfaces) + { + contributor.AddInterfaceToProxy(@interface); + AddMappingNoCheck(@interface, contributor, typeImplementerMapping); + } + + foreach (var @interface in additionalInterfaces) + { + if (!ImplementedByTarget(targetInterfaces, @interface) || proxiedInterfaces.Contains(@interface)) + { + continue; + } + + contributor.AddInterfaceToProxy(@interface); + AddMappingNoCheck(@interface, contributor, typeImplementerMapping); + } + return contributor; + } + + private bool ImplementedByTarget(ICollection targetInterfaces, Type @interface) + { + return targetInterfaces.Contains(@interface); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetInterfaceGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetInterfaceGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetInterfaceGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InterfaceProxyWithTargetInterfaceGenerator.cs Sun Feb 13 20:07:55 2011 @@ -0,0 +1,74 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Reflection; + + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Serialization; + + internal class InterfaceProxyWithTargetInterfaceGenerator : InterfaceProxyWithTargetGenerator + { + + public InterfaceProxyWithTargetInterfaceGenerator(ModuleScope scope, Type @interface) + : base(scope, @interface) + { + } + + protected override ITypeContributor AddMappingForTargetType(IDictionary typeImplementerMapping, Type proxyTargetType, ICollection targetInterfaces, ICollection additionalInterfaces, INamingScope namingScope) + { + var contributor = new InterfaceProxyWithTargetInterfaceTargetContributor( + proxyTargetType, + AllowChangeTarget, + namingScope) { Logger = Logger }; + foreach (var @interface in targetType.GetAllInterfaces()) + { + contributor.AddInterfaceToProxy(@interface); + AddMappingNoCheck(@interface, contributor, typeImplementerMapping); + } + + return contributor; + } + + protected override InterfaceProxyWithoutTargetContributor GetContributorForAdditionalInterfaces(INamingScope namingScope) + { + return new InterfaceProxyWithOptionalTargetContributor(namingScope, GetTargetExpression, GetTarget) + { Logger = Logger }; + } + + private Reference GetTarget(ClassEmitter @class, MethodInfo method) + { + return new AsTypeReference(@class.GetField("__target"), method.DeclaringType); + } + private Expression GetTargetExpression(ClassEmitter @class, MethodInfo method) + { + return GetTarget(@class, method).ToExpression(); + } + + protected override bool AllowChangeTarget + { + get { return true; } + } + + protected override string GeneratorType + { + get { return ProxyTypeConstants.InterfaceWithTargetInterface; } + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InvocationTypeGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InvocationTypeGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\InvocationTypeGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\InvocationTypeGenerator.cs Sun Feb 13 20:09:01 2011 @@ -0,0 +1,299 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.CodeBuilders; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + internal abstract class InvocationTypeGenerator : IGenerator + { + protected readonly Type targetType; + protected readonly MetaMethod method; + private readonly MethodInfo callback; + private readonly bool canChangeTarget; + private readonly IInvocationCreationContributor contributor; + + protected InvocationTypeGenerator(Type targetType, MetaMethod method, MethodInfo callback, bool canChangeTarget, IInvocationCreationContributor contributor) + { + this.targetType = targetType; + this.method = method; + this.callback = callback; + this.canChangeTarget = canChangeTarget; + this.contributor = contributor; + } + + public AbstractTypeEmitter Generate(ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) + { + var methodInfo = method.Method; + + var interfaces = new Type[0]; + + if (canChangeTarget) + { + interfaces = new[] { typeof(IChangeProxyTarget) }; + } + var invocation = GetEmitter(@class, interfaces, namingScope, methodInfo); + + // invocation only needs to mirror the generic parameters of the MethodInfo + // targetType cannot be a generic type definition (YET!) + invocation.CopyGenericParametersFromMethod(methodInfo); + + CreateConstructor(invocation, options); + + var targetField = GetTargetReference(); + if (canChangeTarget) + { + ImplementChangeProxyTargetInterface(@class, invocation, targetField); + } + + ImplemementInvokeMethodOnTarget(invocation, methodInfo.GetParameters(), targetField, callback); + +#if !SILVERLIGHT + invocation.DefineCustomAttribute(); +#endif + + return invocation; + } + + private void CreateConstructor(AbstractTypeEmitter invocation, ProxyGenerationOptions options) + { + ConstructorInfo baseConstructor; + var baseCtorArguments = GetBaseCtorArguments(targetType, options, out baseConstructor); + + var constructor = CreateConstructor(invocation, baseCtorArguments); + constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, baseCtorArguments); + constructor.CodeBuilder.AddStatement(new ReturnStatement()); + } + + private ConstructorEmitter CreateConstructor(AbstractTypeEmitter invocation, ArgumentReference[] baseCtorArguments) + { + if (contributor == null) + { + return invocation.CreateConstructor(baseCtorArguments); + } + return contributor.CreateConstructor(baseCtorArguments, invocation); + } + + protected abstract FieldReference GetTargetReference(); + + private AbstractTypeEmitter GetEmitter(ClassEmitter @class, Type[] interfaces, INamingScope namingScope, + MethodInfo methodInfo) + { + var suggestedName = string.Format("Castle.Proxies.Invocations.{0}_{1}", methodInfo.DeclaringType.Name, + methodInfo.Name); + var uniqueName = namingScope.ParentScope.GetUniqueName(suggestedName); + return new ClassEmitter(@class.ModuleScope, uniqueName, GetBaseType(), interfaces); + } + + protected abstract Type GetBaseType(); + + private void ImplementChangeProxyTargetInterface(ClassEmitter @class, AbstractTypeEmitter invocation, FieldReference targetField) + { + ImplementChangeInvocationTarget(invocation, targetField); + + ImplementChangeProxyTarget(invocation, @class); + } + + private void ImplementChangeProxyTarget(AbstractTypeEmitter invocation, ClassEmitter @class) + { + var changeInvocationTarget = invocation.CreateMethod("ChangeProxyTarget", typeof(void), new[] { typeof(object) }); + changeInvocationTarget.CodeBuilder.AddStatement( + new ExpressionStatement( + new ConvertExpression(@class.TypeBuilder, new FieldReference(InvocationMethods.ProxyObject).ToExpression()))); + + var field = @class.GetField("__target"); + changeInvocationTarget.CodeBuilder.AddStatement( + new AssignStatement( + new FieldReference(field.Reference) { OwnerReference = null }, + new ConvertExpression(field.Fieldbuilder.FieldType, changeInvocationTarget.Arguments[0].ToExpression()))); + + changeInvocationTarget.CodeBuilder.AddStatement(new ReturnStatement()); + } + + private void ImplementChangeInvocationTarget(AbstractTypeEmitter invocation, FieldReference targetField) + { + var changeInvocationTarget = invocation.CreateMethod("ChangeInvocationTarget", typeof(void), new[] { typeof(object) }); + changeInvocationTarget.CodeBuilder.AddStatement( + new AssignStatement(targetField, + new ConvertExpression(targetType, changeInvocationTarget.Arguments[0].ToExpression()))); + changeInvocationTarget.CodeBuilder.AddStatement(new ReturnStatement()); + } + + private void ImplemementInvokeMethodOnTarget(AbstractTypeEmitter invocation, ParameterInfo[] parameters, FieldReference targetField, MethodInfo callbackMethod) + { + var invokeMethodOnTarget = invocation.CreateMethod("InvokeMethodOnTarget", typeof(void)); + ImplementInvokeMethodOnTarget(invocation, parameters, invokeMethodOnTarget, targetField); + } + + protected virtual void ImplementInvokeMethodOnTarget(AbstractTypeEmitter invocation, ParameterInfo[] parameters, + MethodEmitter invokeMethodOnTarget, + Reference targetField) + { + var callbackMethod = GetCallbackMethod(invocation); + if (callbackMethod == null) + { + EmitCallThrowOnNoTarget(invokeMethodOnTarget); + return; + } + + if (canChangeTarget) + { + EmitCallEnsureValidTarget(invokeMethodOnTarget); + } + + Expression[] args = new Expression[parameters.Length]; + + // Idea: instead of grab parameters one by one + // we should grab an array + Dictionary byRefArguments = new Dictionary(); + + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo param = parameters[i]; + + Type paramType = invocation.GetClosedParameterType(param.ParameterType); + if (paramType.IsByRef) + { + LocalReference localReference = invokeMethodOnTarget.CodeBuilder.DeclareLocal(paramType.GetElementType()); + invokeMethodOnTarget.CodeBuilder + .AddStatement( + new AssignStatement(localReference, + new ConvertExpression(paramType.GetElementType(), + new MethodInvocationExpression(SelfReference.Self, + InvocationMethods.GetArgumentValue, + new LiteralIntExpression(i))))); + ByRefReference byRefReference = new ByRefReference(localReference); + args[i] = new ReferenceExpression(byRefReference); + byRefArguments[i] = localReference; + } + else + { + args[i] = + new ConvertExpression(paramType, + new MethodInvocationExpression(SelfReference.Self, + InvocationMethods.GetArgumentValue, + new LiteralIntExpression(i))); + } + } + + var methodOnTargetInvocationExpression = GetCallbackMethodInvocation(invocation, args, callbackMethod, targetField, + invokeMethodOnTarget); + + LocalReference returnValue = null; + if (callbackMethod.ReturnType != typeof(void)) + { + Type returnType = invocation.GetClosedParameterType(callbackMethod.ReturnType); + returnValue = invokeMethodOnTarget.CodeBuilder.DeclareLocal(returnType); + invokeMethodOnTarget.CodeBuilder.AddStatement(new AssignStatement(returnValue, methodOnTargetInvocationExpression)); + } + else + { + invokeMethodOnTarget.CodeBuilder.AddStatement(new ExpressionStatement(methodOnTargetInvocationExpression)); + } + + foreach (KeyValuePair byRefArgument in byRefArguments) + { + int index = byRefArgument.Key; + LocalReference localReference = byRefArgument.Value; + invokeMethodOnTarget.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression(SelfReference.Self, + InvocationMethods.SetArgumentValue, + new LiteralIntExpression(index), + new ConvertExpression(typeof(object), + localReference. + Type, + new ReferenceExpression + (localReference))) + )); + } + + if (callbackMethod.ReturnType != typeof(void)) + { + var setRetVal = + new MethodInvocationExpression(SelfReference.Self, + InvocationMethods.SetReturnValue, + new ConvertExpression(typeof(object), returnValue.Type, returnValue.ToExpression())); + + invokeMethodOnTarget.CodeBuilder.AddStatement(new ExpressionStatement(setRetVal)); + } + + invokeMethodOnTarget.CodeBuilder.AddStatement(new ReturnStatement()); + } + + private void EmitCallThrowOnNoTarget(MethodEmitter invokeMethodOnTarget) + { + var throwOnNoTarget = new ExpressionStatement(new MethodInvocationExpression(InvocationMethods.ThrowOnNoTarget)); + + invokeMethodOnTarget.CodeBuilder.AddStatement(throwOnNoTarget); + invokeMethodOnTarget.CodeBuilder.AddStatement(new ReturnStatement()); + } + + private AbstractCodeBuilder EmitCallEnsureValidTarget(MethodEmitter invokeMethodOnTarget) + { + return invokeMethodOnTarget.CodeBuilder.AddStatement( + new ExpressionStatement( + new MethodInvocationExpression(SelfReference.Self, InvocationMethods.EnsureValidTarget))); + } + + protected virtual MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, Expression[] args, MethodInfo callbackMethod, Reference targetField, MethodEmitter invokeMethodOnTarget) + { + if (contributor != null) + { + return contributor.GetCallbackMethodInvocation(invocation, args, targetField, invokeMethodOnTarget); + } + var methodOnTargetInvocationExpression = new MethodInvocationExpression( + new AsTypeReference(targetField, callbackMethod.DeclaringType), + callbackMethod, + args) { VirtualCall = true }; + return methodOnTargetInvocationExpression; + } + + /// + /// Generates the constructor for the class that extends + /// + /// + /// + /// + /// + protected abstract ArgumentReference[] GetBaseCtorArguments(Type targetFieldType, ProxyGenerationOptions proxyGenerationOptions, out ConstructorInfo baseConstructor); + + private MethodInfo GetCallbackMethod( AbstractTypeEmitter invocation) + { + if(contributor!=null) + { + return contributor.GetCallbackMethod(); + } + var callbackMethod = callback; + if (callbackMethod == null) + { + return null; + } + + if (!callbackMethod.IsGenericMethod) + { + return callbackMethod; + } + + return callbackMethod.MakeGenericMethod(invocation.GetGenericArgumentsFor(callbackMethod)); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaEvent.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaEvent.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaEvent.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaEvent.cs Sun Feb 13 20:12:19 2011 @@ -0,0 +1,153 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters; + + internal class MetaEvent : MetaTypeElement, IEquatable + { + private string name; + private readonly Type type; + private EventEmitter emitter; + private readonly MetaMethod adder; + private readonly MetaMethod remover; + + public bool Equals(MetaEvent other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (!type.Equals(other.type)) + { + return false; + } + + if (!StringComparer.OrdinalIgnoreCase.Equals(name, other.name)) + { + return false; + } + + return true; + } + + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + if (ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != typeof(MetaEvent)) + { + return false; + } + return Equals((MetaEvent)obj); + } + + public override int GetHashCode() + { + unchecked + { + int result = (adder.Method != null ? adder.Method.GetHashCode() : 0); + result = (result * 397) ^ (remover.Method != null ? remover.Method.GetHashCode() : 0); + result = (result * 397) ^ Attributes.GetHashCode(); + return result; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The name. + /// Type declaring the original event being overriten, or null. + /// + /// The add method. + /// The remove method. + /// The attributes. + public MetaEvent(string name, Type declaringType, Type eventDelegateType, MetaMethod adder, MetaMethod remover, EventAttributes attributes) + : base(declaringType) + { + if (adder == null) + { + throw new ArgumentNullException("adder"); + } + if (remover == null) + { + throw new ArgumentNullException("remover"); + } + this.name = name; + this.type = eventDelegateType; + this.adder = adder; + this.remover = remover; + this.Attributes = attributes; + } + + public EventAttributes Attributes { get; private set; } + + public EventEmitter Emitter + { + get + { + if (emitter != null) + { + return emitter; + } + + throw new InvalidOperationException( + "Emitter is not initialized. You have to initialize it first using 'BuildEventEmitter' method"); + } + } + + public MetaMethod Adder + { + get { return adder; } + } + + public MetaMethod Remover + { + get { return remover; } + } + + public void BuildEventEmitter(ClassEmitter classEmitter) + { + if (emitter != null) + { + throw new InvalidOperationException(); + } + emitter = classEmitter.CreateEvent(name, Attributes, type); + } + + internal override void SwitchToExplicitImplementation() + { + name = string.Format("{0}.{1}", sourceType.Name, name); + adder.SwitchToExplicitImplementation(); + remover.SwitchToExplicitImplementation(); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaMethod.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaMethod.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaMethod.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaMethod.cs Sun Feb 13 20:37:22 2011 @@ -0,0 +1,151 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Diagnostics; + using System.Reflection; + + [DebuggerDisplay("{Method}")] + internal class MetaMethod : MetaTypeElement, IEquatable + { + private string name; + + private const MethodAttributes ExplicitImplementationAttributes = MethodAttributes.Virtual | + MethodAttributes.Public | + MethodAttributes.HideBySig | + MethodAttributes.NewSlot | + MethodAttributes.Final; + + public MetaMethod(MethodInfo method, MethodInfo methodOnTarget, bool standalone, bool proxyable, bool hasTarget) + : base(method.DeclaringType) + { + Method = method; + name = method.Name; + MethodOnTarget = methodOnTarget; + Standalone = standalone; + Proxyable = proxyable; + HasTarget = hasTarget; + Attributes = ObtainAttributes(); + } + + private MethodAttributes ObtainAttributes() + { + var methodInfo = Method; + var attributes = MethodAttributes.Virtual; + + if (methodInfo.IsFinal||Method.DeclaringType.IsInterface) + { + attributes |= MethodAttributes.NewSlot; + } + + if (methodInfo.IsPublic) + { + attributes |= MethodAttributes.Public; + } + + if (methodInfo.IsHideBySig) + { + attributes |= MethodAttributes.HideBySig; + } + if (InternalsHelper.IsInternal(methodInfo) && + InternalsHelper.IsInternalToDynamicProxy(methodInfo.DeclaringType.Assembly)) + { + attributes |= MethodAttributes.Assembly; + } + if (methodInfo.IsFamilyAndAssembly) + { + attributes |= MethodAttributes.FamANDAssem; + } + else if (methodInfo.IsFamilyOrAssembly) + { + attributes |= MethodAttributes.FamORAssem; + } + else if (methodInfo.IsFamily) + { + attributes |= MethodAttributes.Family; + } + + if (Standalone == false) + { + attributes |= MethodAttributes.SpecialName; + } + return attributes; + } + + public bool Proxyable { get; private set; } + + public MethodInfo MethodOnTarget { get; private set; } + + public bool Standalone { get; private set; } + + public MethodInfo Method { get; private set; } + + public bool HasTarget { get; private set; } + + public bool Equals(MetaMethod other) + { + if (ReferenceEquals(null,other)) + { + return false; + } + if (ReferenceEquals(this,other)) + { + return true; + } + + if (!StringComparer.OrdinalIgnoreCase.Equals(name, other.name)) + { + return false; + } + + var comparer = MethodSignatureComparer.Instance; + if (!comparer.EqualSignatureTypes(Method.ReturnType, other.Method.ReturnType)) + { + return false; + } + + if (!comparer.EqualGenericParameters(Method, other.Method)) + { + return false; + } + + if(!comparer.EqualParameters(Method,other.Method)) + { + return false; + } + + return true; + } + + internal override void SwitchToExplicitImplementation() + { + Attributes = ExplicitImplementationAttributes; + if (Standalone == false) + { + Attributes |= MethodAttributes.SpecialName; + } + + name = string.Format("{0}.{1}", Method.DeclaringType.Name, Method.Name); + } + + public MethodAttributes Attributes { get; private set; } + + public string Name + { + get { return name; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaProperty.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaProperty.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaProperty.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaProperty.cs Sun Feb 13 20:14:14 2011 @@ -0,0 +1,191 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Reflection; + using System.Reflection.Emit; + using Castle.DynamicProxy.Generators.Emitters; + + internal class MetaProperty : MetaTypeElement, IEquatable + { + private string name; + private readonly Type type; + private readonly MetaMethod getter; + private readonly MetaMethod setter; + private readonly PropertyAttributes attributes; + private readonly IEnumerable customAttributes; + private readonly Type[] arguments; + private PropertyEmitter emitter; + + public MetaProperty(string name, Type propertyType, Type declaringType, MetaMethod getter, MetaMethod setter, IEnumerable customAttributes,Type[] arguments) + :base(declaringType) + { + this.name = name; + this.type = propertyType; + this.getter = getter; + this.setter = setter; + this.attributes = PropertyAttributes.None; + this.customAttributes = customAttributes; + this.arguments = arguments ?? Type.EmptyTypes; + } + + public bool CanRead + { + get { return getter != null; } + } + + public bool CanWrite + { + get { return setter != null; } + } + + public MethodInfo GetMethod + { + get + { + if(!CanRead) + { + throw new InvalidOperationException(); + } + return getter.Method; + } + } + + public MethodInfo SetMethod + { + get + { + if(!CanWrite) + { + throw new InvalidOperationException(); + } + return setter.Method; + } + } + + public PropertyEmitter Emitter + { + get { + if (emitter == null) + throw new InvalidOperationException( + "Emitter is not initialized. You have to initialize it first using 'BuildPropertyEmitter' method"); + return emitter; + } + } + + public MetaMethod Getter + { + get { return getter; } + } + + public MetaMethod Setter + { + get { return setter; } + } + + public bool Equals(MetaProperty other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (!type.Equals(other.type)) + { + return false; + } + + if (!StringComparer.OrdinalIgnoreCase.Equals(name, other.name)) + { + return false; + } + if (Arguments.Length != other.Arguments.Length) + { + return false; + } + for (int i = 0; i < Arguments.Length; i++) + { + if (Arguments[i].Equals(other.Arguments[i]) == false) + { + return false; + } + } + + return true; + } + + public Type[] Arguments + { + get { return arguments; } + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + if (ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != typeof(MetaProperty)) + { + return false; + } + return Equals((MetaProperty) obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((GetMethod != null ? GetMethod.GetHashCode() : 0) * 397) ^ (SetMethod != null ? SetMethod.GetHashCode() : 0); + } + } + + public void BuildPropertyEmitter(ClassEmitter classEmitter) + { + if (emitter != null) + throw new InvalidOperationException("Emitter is already created. It is illegal to invoke this method twice."); + + emitter = classEmitter.CreateProperty(name, attributes, type, arguments); + foreach (var attribute in customAttributes) + { + emitter.DefineCustomAttribute(attribute); + } + } + + internal override void SwitchToExplicitImplementation() + { + name = string.Format("{0}.{1}", sourceType.Name, name); + if(setter!=null) + { + setter.SwitchToExplicitImplementation(); + } + if(getter!=null) + { + getter.SwitchToExplicitImplementation(); + } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaType.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaType.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaType.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaType.cs Sun Feb 13 20:12:33 2011 @@ -0,0 +1,60 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System.Collections.Generic; + + internal class MetaType + { + private readonly ICollection properties = new TypeElementCollection(); + private readonly ICollection events = new TypeElementCollection(); + private readonly ICollection methods = new TypeElementCollection(); + + public MetaType() + { + } + + public IEnumerable Methods + { + get { return methods; // NOTE: should be readonly + } + } + + public IEnumerable Properties + { + get { return properties; } + } + + public IEnumerable Events + { + get { return events; } + } + + public void AddMethod(MetaMethod method) + { + methods.Add(method); + } + + public void AddEvent(MetaEvent @event) + { + events.Add(@event); + } + + public void AddProperty(MetaProperty property) + { + properties.Add(property); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaTypeElement.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaTypeElement.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MetaTypeElement.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MetaTypeElement.cs Sun Feb 13 20:37:32 2011 @@ -0,0 +1,38 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + + internal abstract class MetaTypeElement + { + protected readonly Type sourceType; + + protected MetaTypeElement(Type sourceType) + { + this.sourceType = sourceType; + } + + internal bool CanBeImplementedExplicitly + { + get + { + return sourceType != null && sourceType.IsInterface; + } + } + + internal abstract void SwitchToExplicitImplementation(); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodFinder.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodFinder.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodFinder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodFinder.cs Sun Feb 13 20:37:37 2011 @@ -0,0 +1,90 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections.Generic; + using System.Reflection; + + /// + /// Returns the methods implemented by a type. Use this instead of Type.GetMethods() to work around a CLR issue + /// where duplicate MethodInfos are returned by Type.GetMethods() after a token of a generic type's method was loaded. + /// + internal class MethodFinder + { + private static readonly Dictionary cachedMethodInfosByType = new Dictionary(); + private static readonly object lockObject = new object(); + + public static MethodInfo[] GetAllInstanceMethods(Type type, BindingFlags flags) + { + if ((flags & ~(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) != 0) + throw new ArgumentException("MethodFinder only supports the Public, NonPublic, and Instance binding flags.", "flags"); + + MethodInfo[] methodsInCache; + + lock (lockObject) + { + if (!cachedMethodInfosByType.ContainsKey(type)) + { + // We always load all instance methods into the cache, we will filter them later + cachedMethodInfosByType.Add( + type, + RemoveDuplicates(type.GetMethods( + BindingFlags.Public | BindingFlags.NonPublic + | BindingFlags.Instance))); + } + methodsInCache = (MethodInfo[])cachedMethodInfosByType[type]; + } + return MakeFilteredCopy(methodsInCache, flags & (BindingFlags.Public | BindingFlags.NonPublic)); + } + + private static object RemoveDuplicates(MethodInfo[] infos) + { + Dictionary uniqueInfos = new Dictionary(MethodSignatureComparer.Instance); + foreach (MethodInfo info in infos) + { + if (!uniqueInfos.ContainsKey(info)) + uniqueInfos.Add(info, null); + } + MethodInfo[] result = new MethodInfo[uniqueInfos.Count]; + uniqueInfos.Keys.CopyTo(result, 0); + return result; + } + + private static MethodInfo[] MakeFilteredCopy(MethodInfo[] methodsInCache, BindingFlags visibilityFlags) + { + if ((visibilityFlags & ~(BindingFlags.Public | BindingFlags.NonPublic)) != 0) + { + throw new ArgumentException("Only supports BindingFlags.Public and NonPublic.", "visibilityFlags"); + } + + bool includePublic = (visibilityFlags & BindingFlags.Public) == BindingFlags.Public; + bool includeNonPublic = (visibilityFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic; + + // Return a copy of the cached array, only returning the public methods unless requested otherwise + List result = new List(methodsInCache.Length); + + foreach (MethodInfo method in methodsInCache) + { + if ((method.IsPublic && includePublic) || (!method.IsPublic && includeNonPublic)) + { + result.Add(method); + } + } + + return result.ToArray(); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodGenerator.cs Sun Feb 13 20:08:53 2011 @@ -0,0 +1,57 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System.Reflection; + + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + + internal abstract class MethodGenerator : IGenerator + { + protected MethodInfo MethodToOverride + { + get { return method.Method; } + } + protected MethodInfo MethodOnTarget + { + get { return method.MethodOnTarget; } + } + + protected MethodGenerator(MetaMethod method, OverrideMethodDelegate overrideMethod) + { + this.method = method; + this.overrideMethod = overrideMethod; + } + + private readonly MetaMethod method; + private readonly OverrideMethodDelegate overrideMethod; + + public MethodEmitter Generate(ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) + { + var methodEmitter = overrideMethod(method.Name, method.Attributes, MethodToOverride); + var proxiedMethod = BuildProxiedMethodBody(methodEmitter, @class, options, namingScope); + + if (MethodToOverride.DeclaringType.IsInterface) + { + @class.TypeBuilder.DefineMethodOverride(proxiedMethod.MethodBuilder, MethodToOverride); + } + + return proxiedMethod; + } + + protected abstract MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodSignatureComparer.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodSignatureComparer.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodSignatureComparer.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodSignatureComparer.cs Sun Feb 13 20:37:45 2011 @@ -0,0 +1,132 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Reflection; + using System.Collections.Generic; + + internal class MethodSignatureComparer : IEqualityComparer + { + public static readonly MethodSignatureComparer Instance = new MethodSignatureComparer(); + + public bool Equals(MethodInfo x, MethodInfo y) + { + if (x == null && y == null) + { + return true; + } + + if (x == null || y == null) + { + return false; + } + + return EqualNames(x, y) && + EqualGenericParameters(x, y) && + EqualSignatureTypes(x.ReturnType, y.ReturnType) && + EqualParameters(x, y); + } + + private bool EqualNames(MethodInfo x, MethodInfo y) + { + return x.Name == y.Name; + } + + public bool EqualGenericParameters(MethodInfo x, MethodInfo y) + { + if (x.IsGenericMethod != y.IsGenericMethod) + { + return false; + } + + if (x.IsGenericMethod) + { + Type[] xArgs = x.GetGenericArguments(); + Type[] yArgs = y.GetGenericArguments(); + + if (xArgs.Length != yArgs.Length) + { + return false; + } + + for (int i = 0; i < xArgs.Length; ++i) + { + if (xArgs[i].IsGenericParameter != yArgs[i].IsGenericParameter) + { + return false; + } + + if (!xArgs[i].IsGenericParameter && !xArgs[i].Equals(yArgs[i])) + { + return false; + } + } + } + + return true; + } + + public bool EqualParameters(MethodInfo x, MethodInfo y) + { + ParameterInfo[] xArgs = x.GetParameters(); + ParameterInfo[] yArgs = y.GetParameters(); + + if (xArgs.Length != yArgs.Length) + { + return false; + } + + for (int i = 0; i < xArgs.Length; ++i) + { + if (!EqualSignatureTypes(xArgs[i].ParameterType, yArgs[i].ParameterType)) + { + return false; + } + } + + return true; + } + + public bool EqualSignatureTypes(Type x, Type y) + { + if (x.IsGenericParameter != y.IsGenericParameter) + { + return false; + } + + if (x.IsGenericParameter) + { + if (x.GenericParameterPosition != y.GenericParameterPosition) + { + return false; + } + } + else + { + if (!x.Equals(y)) + { + return false; + } + } + return true; + } + + public int GetHashCode(MethodInfo obj) + { + return obj.Name.GetHashCode() ^ obj.GetParameters().Length; // everything else would be too cumbersome + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodWithInvocationGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodWithInvocationGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\MethodWithInvocationGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\MethodWithInvocationGenerator.cs Sun Feb 13 20:09:06 2011 @@ -0,0 +1,182 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; +#if !SILVERLIGHT + using System.Xml.Serialization; +#endif + using Castle.DynamicProxy.Contributors; + using Castle.DynamicProxy.Generators.Emitters; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; + using Castle.DynamicProxy.Tokens; + + + internal class MethodWithInvocationGenerator : MethodGenerator + { + private readonly Reference interceptors; + private readonly GetTargetExpressionDelegate getTargetExpression; + private readonly Type invocation; + private readonly IInvocationCreationContributor contributor; + + public MethodWithInvocationGenerator(MetaMethod method, Reference interceptors, Type invocation, GetTargetExpressionDelegate getTargetExpression, OverrideMethodDelegate createMethod, IInvocationCreationContributor contributor) + : base(method, createMethod) + { + this.invocation = invocation; + this.getTargetExpression = getTargetExpression; + this.interceptors = interceptors; + this.contributor = contributor; + } + + protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) + { + var invocationType = invocation; + + Trace.Assert(MethodToOverride.IsGenericMethod == invocationType.IsGenericTypeDefinition); + var genericArguments = Type.EmptyTypes; + + var constructor = invocation.GetConstructors()[0]; + + + Expression proxiedMethodTokenExpression; + if (MethodToOverride.IsGenericMethod) + { + // bind generic method arguments to invocation's type arguments + genericArguments = emitter.MethodBuilder.GetGenericArguments(); + invocationType = invocationType.MakeGenericType(genericArguments); + constructor = TypeBuilder.GetConstructor(invocationType, constructor); + + // Not in the cache: generic method + proxiedMethodTokenExpression = new MethodTokenExpression(MethodToOverride.MakeGenericMethod(genericArguments)); + } + else + { + var proxiedMethodToken = @class.CreateStaticField(namingScope.GetUniqueName("token_" + MethodToOverride.Name), + typeof(MethodInfo)); + @class.ClassConstructor.CodeBuilder.AddStatement(new AssignStatement(proxiedMethodToken, + new MethodTokenExpression(MethodToOverride))); + + proxiedMethodTokenExpression = proxiedMethodToken.ToExpression(); + } + + var dereferencedArguments = IndirectReference.WrapIfByRef(emitter.Arguments); + var arguments = GetCtorArguments(@class, namingScope, proxiedMethodTokenExpression, + dereferencedArguments); + var ctorArguments = ModifyArguments(@class, arguments); + + var invocationLocal = emitter.CodeBuilder.DeclareLocal(invocationType); + emitter.CodeBuilder.AddStatement(new AssignStatement(invocationLocal, + new NewInstanceExpression(constructor, ctorArguments))); + + if (MethodToOverride.ContainsGenericParameters) + { + EmitLoadGenricMethodArguments(emitter, MethodToOverride.MakeGenericMethod(genericArguments), invocationLocal); + } + + var proceed = new ExpressionStatement(new MethodInvocationExpression(invocationLocal, InvocationMethods.Proceed)); + emitter.CodeBuilder.AddStatement(proceed); + + GeneratorUtil.CopyOutAndRefParameters(dereferencedArguments, invocationLocal, MethodToOverride, emitter); + + if (MethodToOverride.ReturnType != typeof(void)) + { + // Emit code to return with cast from ReturnValue + var getRetVal = new MethodInvocationExpression(invocationLocal, InvocationMethods.GetReturnValue); + emitter.CodeBuilder.AddStatement(new ReturnStatement(new ConvertExpression(emitter.ReturnType, getRetVal))); + } + else + { + emitter.CodeBuilder.AddStatement(new ReturnStatement()); + } + + return emitter; + } + + private Expression[] ModifyArguments(ClassEmitter @class, Expression[] arguments) + { + if (contributor == null) + { + return arguments; + } + + return contributor.GetConstructorInvocationArguments(arguments, @class); + } + + private Expression[] GetCtorArguments(ClassEmitter @class, INamingScope namingScope, Expression proxiedMethodTokenExpression, TypeReference[] dereferencedArguments) + { + var selector = @class.GetField("__selector"); + if (selector != null) + { + return new[] + { + getTargetExpression(@class, MethodToOverride), + SelfReference.Self.ToExpression(), + interceptors.ToExpression(), + proxiedMethodTokenExpression, + new ReferencesToObjectArrayExpression(dereferencedArguments), + selector.ToExpression(), + new AddressOfReferenceExpression(BuildMethodInterceptorsField(@class, MethodToOverride, namingScope)) + }; + } + return new[] + { + getTargetExpression(@class, MethodToOverride), + SelfReference.Self.ToExpression(), + interceptors.ToExpression(), + proxiedMethodTokenExpression, + new ReferencesToObjectArrayExpression(dereferencedArguments) + }; + } + + protected FieldReference BuildMethodInterceptorsField(ClassEmitter @class, MethodInfo method, INamingScope namingScope) + { + var methodInterceptors = @class.CreateField( + namingScope.GetUniqueName(string.Format("interceptors_{0}", method.Name)), + typeof(IInterceptor[]), + false); +#if !SILVERLIGHT + @class.DefineCustomAttributeFor(methodInterceptors); +#endif + return methodInterceptors; + } + + private void EmitLoadGenricMethodArguments(MethodEmitter methodEmitter, MethodInfo method, Reference invocationLocal) + { +#if SILVERLIGHT + Type[] genericParameters = + Castle.Core.Extensions.SilverlightExtensions.FindAll(method.GetGenericArguments(), t => t.IsGenericParameter); +#else + Type[] genericParameters = Array.FindAll(method.GetGenericArguments(), t => t.IsGenericParameter); +#endif + LocalReference genericParamsArrayLocal = methodEmitter.CodeBuilder.DeclareLocal(typeof(Type[])); + methodEmitter.CodeBuilder.AddStatement( + new AssignStatement(genericParamsArrayLocal, new NewArrayExpression(genericParameters.Length, typeof(Type)))); + + for (int i = 0; i < genericParameters.Length; ++i) + { + methodEmitter.CodeBuilder.AddStatement( + new AssignArrayStatement(genericParamsArrayLocal, i, new TypeTokenExpression(genericParameters[i]))); + } + methodEmitter.CodeBuilder.AddStatement(new ExpressionStatement( + new MethodInvocationExpression(invocationLocal, + InvocationMethods.SetGenericMethodArguments, + new ReferenceExpression( + genericParamsArrayLocal)))); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\NamingScope.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\NamingScope.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\NamingScope.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\NamingScope.cs Sun Feb 13 20:38:02 2011 @@ -0,0 +1,61 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System.Collections.Generic; + using System.Diagnostics; + + internal class NamingScope : INamingScope + { + private readonly IDictionary names = new Dictionary(); + private readonly INamingScope parentScope; + + public NamingScope() + { + } + + private NamingScope(INamingScope parent) + { + parentScope = parent; + } + + public string GetUniqueName(string suggestedName) + { + Debug.Assert(string.IsNullOrEmpty(suggestedName) == false, + "string.IsNullOrEmpty(suggestedName) == false"); + + int counter; + if (!names.TryGetValue(suggestedName, out counter)) + { + names.Add(suggestedName, 0); + return suggestedName; + } + + counter++; + names[suggestedName] = counter; + return suggestedName + "_" + counter.ToString(); + } + + public INamingScope SafeSubScope() + { + return new NamingScope(this); + } + + public INamingScope ParentScope + { + get { return parentScope;} + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\TypeElementCollection.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\TypeElementCollection.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Generators\TypeElementCollection.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Generators\TypeElementCollection.cs Sun Feb 13 20:37:57 2011 @@ -0,0 +1,90 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators +{ + using System; + using System.Collections; + using System.Collections.Generic; + + internal class TypeElementCollection : ICollection where TElement : MetaTypeElement, IEquatable + { + private readonly ICollection items = new List(); + + public IEnumerator GetEnumerator() + { + return items.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(TElement item) + { + if (item.CanBeImplementedExplicitly == false) + { + items.Add(item); + return; + } + if(Contains(item)) + { + item.SwitchToExplicitImplementation(); + if(Contains(item)) + { + // there is something reaaaly wrong going on here + throw new ProxyGenerationException("Duplicate element: " + item.ToString()); + } + } + items.Add(item); + } + + void ICollection.Clear() + { + throw new NotSupportedException(); + } + + public bool Contains(TElement item) + { + foreach (var element in items) + { + if(element.Equals(item)) + return true; + } + + return false; + } + + void ICollection.CopyTo(TElement[] array, int arrayIndex) + { + throw new NotSupportedException(); + } + + bool ICollection.Remove(TElement item) + { + throw new NotSupportedException(); + } + + public int Count + { + get { return items.Count; } + } + + bool ICollection.IsReadOnly + { + get { return false; } + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IAttributeDisassembler.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IAttributeDisassembler.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IAttributeDisassembler.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IAttributeDisassembler.cs Sun Feb 13 21:03:22 2011 @@ -0,0 +1,39 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Reflection.Emit; + + /// + /// Provides functionality for disassembling instances of attributes to CustomAttributeBuilder form, during the process of emiting new types by Dynamic Proxy. + /// + internal interface IAttributeDisassembler + { + /// + /// Disassembles given attribute instance back to corresponding CustomAttributeBuilder. + /// + /// An instance of attribute to disassemble + /// corresponding 1 to 1 to given attribute instance, or null reference. + /// + /// Implementers should return that corresponds to given attribute instance 1 to 1, + /// that is after calling specified constructor with specified arguments, and setting specified properties and fields with values specified + /// we should be able to get an attribute instance identical to the one passed in . Implementer can return null + /// if it wishes to opt out of replicating the attribute. Notice however, that for some cases, like attributes passed explicitly by the user + /// it is illegal to return null, and doing so will result in exception. + /// + CustomAttributeBuilder Disassemble(Attribute attribute); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IChangeProxyTarget.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IChangeProxyTarget.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IChangeProxyTarget.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IChangeProxyTarget.cs Sun Feb 13 21:03:27 2011 @@ -0,0 +1,51 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + /// + /// Exposes means to change target objects of proxies and invocations + /// + internal interface IChangeProxyTarget + { + /// + /// Changes the target object () of current . + /// + /// The new value of target of invocation. + /// + /// Although the method takes the actual instance must be of type assignable to , otherwise an will be thrown. + /// Also while it's technically legal to pass null reference (Nothing in Visual Basic) as , for obvious reasons Dynamic Proxy will not be able to call the intercepted method on such target. + /// In this case last interceptor in the pipeline mustn't call or a will be throws. + /// Also while it's technically legal to pass proxy itself as , this would create stack overflow. + /// In this case last interceptor in the pipeline mustn't call or a will be throws. + /// + /// Thrown when is not assignable to the proxied type. + void ChangeInvocationTarget(object target); + + + /// + /// Permanently changes the target object of the proxy. This does not affect target of the current invocation. + /// + /// The new value of target of the proxy. + /// + /// Although the method takes the actual instance must be of type assignable to proxy's target type, otherwise an will be thrown. + /// Also while it's technically legal to pass null reference (Nothing in Visual Basic) as , for obvious reasons Dynamic Proxy will not be able to call the intercepted method on such target. + /// In this case last interceptor in the pipeline mustn't call or a will be throws. + /// Also while it's technically legal to pass proxy itself as , this would create stack overflow. + /// In this case last interceptor in the pipeline mustn't call or a will be throws. + /// + /// Thrown when is not assignable to the proxied type. + void ChangeProxyTarget(object target); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IInterceptor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IInterceptor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IInterceptor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IInterceptor.cs Mon Feb 14 13:25:10 2011 @@ -0,0 +1,25 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + /// + /// New interface that is going to be used by DynamicProxy 2 + /// + // [ILMergeExclude] + internal interface IInterceptor + { + void Intercept(IInvocation invocation); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IInterceptorSelector.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IInterceptorSelector.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IInterceptorSelector.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IInterceptorSelector.cs Mon Feb 14 13:25:18 2011 @@ -0,0 +1,43 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Reflection; + + /// + /// Provides an extension point that allows proxies to choose specific interceptors on + /// a per method basis. + /// + // [ILMergeExclude] + internal interface IInterceptorSelector + { + /// + /// Selects the interceptors that should intercept calls to the given . + /// + /// The type declaring the method to intercept. + /// The method that will be intercepted. + /// All interceptors registered with the proxy. + /// An array of interceptors to invoke upon calling the . + /// + /// This method is called only once per proxy instance, upon the first call to the + /// . Either an empty array or null are valid return values to indicate + /// that no interceptor should intercept calls to the method. Although it is not advised, it is + /// legal to return other implementations than these provided in + /// . + /// + IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IInvocation.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IInvocation.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IInvocation.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IInvocation.cs Mon Feb 14 13:25:32 2011 @@ -0,0 +1,126 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Reflection; + + /// + /// Encapsulates an invocation of a proxied method. + /// + // [ILMergeExclude] + internal interface IInvocation + { + /// + /// Gets the proxy object on which the intercepted method is invoked. + /// + /// Proxy object on which the intercepted method is invoked. + object Proxy { get; } + + /// + /// Gets the object on which the invocation is performed. This is different from proxy object + /// because most of the time this will be the proxy target object. + /// + /// + /// The invocation target. + object InvocationTarget { get; } + + /// + /// Gets the type of the target object for the intercepted method. + /// + /// The type of the target object. + Type TargetType { get; } + + /// + /// Gets the arguments that the has been invoked with. + /// + /// The arguments the method was invoked with. + object[] Arguments { get; } + + /// + /// Overrides the value of an argument at the given with the + /// new provided. + /// + /// + /// This method accepts an , however the value provided must be compatible + /// with the type of the argument defined on the method, otherwise an exception will be thrown. + /// + /// The index of the argument to override. + /// The new value for the argument. + void SetArgumentValue(int index, object value); + + /// + /// Gets the value of the argument at the specified . + /// + /// The index. + /// The value of the argument at the specified . + object GetArgumentValue(int index); + + /// + /// Gets the generic arguments of the method. + /// + /// The generic arguments, or null if not a generic method. + Type[] GenericArguments { get; } + + /// + /// Gets the representing the method being invoked on the proxy. + /// + /// The representing the method being invoked. + MethodInfo Method { get; } + + /// + /// Returns the concrete instantiation of the on the proxy, with any generic + /// parameters bound to real types. + /// + /// + /// The concrete instantiation of the on the proxy, or the if + /// not a generic method. + /// + /// Can be slower than calling . + MethodInfo GetConcreteMethod(); + + /// + /// For interface proxies, this will point to the on the target class. + /// + /// The method invocation target. + MethodInfo MethodInvocationTarget { get; } + + /// + /// Returns the concrete instantiation of , with any + /// generic parameters bound to real types. + /// For interface proxies, this will point to the on the target class. + /// + /// The concrete instantiation of , or + /// if not a generic method. + /// In debug builds this can be slower than calling . + MethodInfo GetConcreteMethodInvocationTarget(); + + /// + /// Gets or sets the return value of the method. + /// + /// The return value of the method. + object ReturnValue { get; set; } + + /// + /// Proceeds the call to the next interceptor in line, and ultimately to the target method. + /// + /// + /// Since interface proxies without a target don't have the target implementation to proceed to, + /// it is important, that the last interceptor does not call this method, otherwise a + /// will be thrown. + /// + void Proceed(); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InheritanceInvocation.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\InheritanceInvocation.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InheritanceInvocation.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\InheritanceInvocation.cs Mon Feb 14 13:25:41 2011 @@ -0,0 +1,66 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Reflection; + + // [ILMergeExclude] + internal abstract class InheritanceInvocation : AbstractInvocation + { + private readonly Type targetType; + + protected InheritanceInvocation( + Type targetType, + object proxy, + IInterceptor[] interceptors, + MethodInfo proxiedMethod, + object[] arguments) + : base(proxy, interceptors, proxiedMethod, arguments) + { + this.targetType = targetType; + } + + protected InheritanceInvocation( + Type targetType, + object proxy, + IInterceptor[] interceptors, + MethodInfo proxiedMethod, + object[] arguments, + IInterceptorSelector selector, + ref IInterceptor[] methodInterceptors) + : base(proxy, targetType, interceptors, proxiedMethod, arguments, selector, ref methodInterceptors) + { + this.targetType = targetType; + } + + public override object InvocationTarget + { + get { return Proxy; } + } + + public override Type TargetType + { + get { return targetType; } + } + + public override MethodInfo MethodInvocationTarget + { + get { return InvocationHelper.GetMethodOnType(targetType, Method); } + } + + protected abstract override void InvokeMethodOnTarget(); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InternalsHelper.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\InternalsHelper.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InternalsHelper.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\InternalsHelper.cs Sun Feb 13 21:04:07 2011 @@ -0,0 +1,81 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System.Collections.Generic; + using System.Reflection; + using System.Runtime.CompilerServices; + using Castle.Core.Internal; + + internal class InternalsHelper + { + private static readonly Lock internalsToDynProxyLock = Lock.Create(); + private static readonly IDictionary internalsToDynProxy = new Dictionary(); + + /// + /// Determines whether this assembly has internals visible to dynamic proxy. + /// + /// The assembly to inspect. + public static bool IsInternalToDynamicProxy(Assembly asm) + { + using (var locker = internalsToDynProxyLock.ForReadingUpgradeable()) + { + if (internalsToDynProxy.ContainsKey(asm)) + { + return internalsToDynProxy[asm]; + } + + locker.Upgrade(); + + if (internalsToDynProxy.ContainsKey(asm)) + { + return internalsToDynProxy[asm]; + } + + InternalsVisibleToAttribute[] atts = (InternalsVisibleToAttribute[]) + asm.GetCustomAttributes(typeof(InternalsVisibleToAttribute), false); + + bool found = false; + + foreach (InternalsVisibleToAttribute internals in atts) + { + if (internals.AssemblyName.Contains(ModuleScope.DEFAULT_ASSEMBLY_NAME)) + { + found = true; + break; + } + } + + internalsToDynProxy.Add(asm, found); + + return found; + + } + } + + /// + /// Determines whether the specified method is internal. + /// + /// The method. + /// + /// true if the specified method is internal; otherwise, false. + /// + public static bool IsInternal(MethodInfo method) + { + return method.IsAssembly || (method.IsFamilyAndAssembly + && !method.IsFamilyOrAssembly); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InvalidMixinConfigurationException.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\InvalidMixinConfigurationException.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InvalidMixinConfigurationException.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\InvalidMixinConfigurationException.cs Sun Feb 13 21:04:16 2011 @@ -0,0 +1,40 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Runtime.Serialization; + +#if !SILVERLIGHT + [Serializable] +#endif + internal class InvalidMixinConfigurationException : Exception + { + public InvalidMixinConfigurationException(string message) + : base (message) + { + } + + public InvalidMixinConfigurationException(string message, Exception innerException) : base (message, innerException) + { + } + +#if !SILVERLIGHT + protected InvalidMixinConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +#endif + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InvocationHelper.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\InvocationHelper.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\InvocationHelper.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\InvocationHelper.cs Sun Feb 13 18:56:56 2011 @@ -0,0 +1,131 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + + using Castle.Core.Internal; + using Castle.DynamicProxy.Generators; + + internal static class InvocationHelper + { + private static readonly Dictionary, MethodInfo> cache = + new Dictionary, MethodInfo>(); + + private static readonly Lock @lock = Lock.Create(); + + public static MethodInfo GetMethodOnObject(object target, MethodInfo proxiedMethod) + { + if (target == null) + { + return null; + } + + return GetMethodOnType(target.GetType(), proxiedMethod); + } + + public static MethodInfo GetMethodOnType(Type type, MethodInfo proxiedMethod) + { + if (type == null) + { + throw new ArgumentNullException("type"); + } + + Debug.Assert(proxiedMethod.DeclaringType.IsAssignableFrom(type), + "proxiedMethod.DeclaringType.IsAssignableFrom(type)"); + using (var locker = @lock.ForReadingUpgradeable()) + { + MethodInfo methodOnTarget = GetFromCache(proxiedMethod, type); + if (methodOnTarget != null) + { + return methodOnTarget; + } + locker.Upgrade(); + + methodOnTarget = GetFromCache(proxiedMethod, type); + if (methodOnTarget != null) + { + return methodOnTarget; + } + methodOnTarget = ObtainMethod(proxiedMethod, type); + PutToCache(proxiedMethod, type, methodOnTarget); + return methodOnTarget; + + } + } + + private static MethodInfo ObtainMethod(MethodInfo proxiedMethod, Type type) + { + Type[] genericArguments = null; + if (proxiedMethod.IsGenericMethod) + { + genericArguments = proxiedMethod.GetGenericArguments(); + proxiedMethod = proxiedMethod.GetGenericMethodDefinition(); + } + Type declaringType = proxiedMethod.DeclaringType; + MethodInfo methodOnTarget = null; + if (declaringType.IsInterface) + { + var mapping = type.GetInterfaceMap(declaringType); + int index = Array.IndexOf(mapping.InterfaceMethods, proxiedMethod); + Debug.Assert(index != -1); + methodOnTarget = mapping.TargetMethods[index]; + } + else + { + // NOTE: this implementation sucks, feel free to improve it. + var methods = MethodFinder.GetAllInstanceMethods(type, BindingFlags.Public | BindingFlags.NonPublic); + foreach (var method in methods) + { + + if (MethodSignatureComparer.Instance.Equals(method.GetBaseDefinition(), proxiedMethod)) + { + methodOnTarget = method; + break; + } + } + } + if (methodOnTarget == null) + { + throw new ArgumentException( + string.Format("Could not find method overriding {0} on type {1}. This is most likely a bug. Please report it.", + proxiedMethod, type)); + } + + if (genericArguments == null) + { + return methodOnTarget; + } + return methodOnTarget.MakeGenericMethod(genericArguments); + } + + private static void PutToCache(MethodInfo methodInfo, Type type, MethodInfo value) + { + var key = new KeyValuePair(methodInfo, type); + cache.Add(key, value); + } + + private static MethodInfo GetFromCache(MethodInfo methodInfo, Type type) + { + var key = new KeyValuePair(methodInfo, type); + MethodInfo method; + cache.TryGetValue(key, out method); + return method; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IProxyBuilder.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IProxyBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IProxyBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IProxyBuilder.cs Sun Feb 13 20:09:33 2011 @@ -0,0 +1,148 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Runtime.CompilerServices; + + using Castle.Core.Logging; + using Castle.DynamicProxy.Generators; + + /// + /// Abstracts the implementation of proxy type construction. + /// + internal interface IProxyBuilder + { + /// + /// Gets or sets the that this logs to. + /// + ILogger Logger { get; set; } + + /// + /// Gets the associated with this builder. + /// + /// The module scope associated with this builder. + ModuleScope ModuleScope { get; } + + /// + /// Creates a proxy type for given , using provided. + /// + /// The class type to proxy. + /// The proxy generation options. + /// The generated proxy type. + /// Thrown when is a generic type definition. + /// Thrown when is not public. + /// Note that to avoid this exception, you can mark offending type internal, and define + /// pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + /// + [Obsolete("Use CreateClassProxyType method instead.")] + Type CreateClassProxy(Type classToProxy, ProxyGenerationOptions options); + + /// + /// Creates a proxy type for given , implementing , using provided. + /// + /// The class type to proxy. + /// Additional interface types to proxy. + /// The proxy generation options. + /// The generated proxy type. + /// + /// Implementers should return a proxy type for the specified class and interfaces. + /// Additional interfaces should be only 'mark' interfaces, that is, they should work like interface proxy without target. (See method.) + /// + /// Thrown when or any of is a generic type definition. + /// Thrown when or any of is not public. + /// Note that to avoid this exception, you can mark offending type internal, and define + /// pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + /// + [Obsolete("Use CreateClassProxyType method instead.")] + Type CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options); + + /// + /// Creates a proxy type for given , implementing , using provided. + /// + /// The class type to proxy. + /// Additional interface types to proxy. + /// The proxy generation options. + /// The generated proxy type. + /// + /// Implementers should return a proxy type for the specified class and interfaces. + /// Additional interfaces should be only 'mark' interfaces, that is, they should work like interface proxy without target. (See method.) + /// + /// Thrown when or any of is a generic type definition. + /// Thrown when or any of is not public. + /// Note that to avoid this exception, you can mark offending type internal, and define + /// pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + /// + Type CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options); + + /// + /// Creates a proxy type that proxies calls to members on , implementing , using provided. + /// + /// The interface type to proxy. + /// Additional interface types to proxy. + /// Type implementing on which calls to the interface members should be intercepted. + /// The proxy generation options. + /// The generated proxy type. + /// + /// Implementers should return a proxy type for the specified interface that 'proceeds' executions to the specified target. + /// Additional interfaces should be only 'mark' interfaces, that is, they should work like interface proxy without target. (See method.) + /// + /// Thrown when or any of is a generic type definition. + /// Thrown when or any of is not public. + /// Note that to avoid this exception, you can mark offending type internal, and define + /// pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + /// + Type CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Type targetType, + ProxyGenerationOptions options); + + /// + /// Creates a proxy type for given that delegates all calls to the provided interceptors. + /// + /// The interface type to proxy. + /// Additional interface types to proxy. + /// The proxy generation options. + /// The generated proxy type. + /// + /// Implementers should return a proxy type for the specified interface and additional interfaces that delegate all executions to the specified interceptors. + /// + /// Thrown when or any of is a generic type definition. + /// Thrown when or any of is not public. + /// Note that to avoid this exception, you can mark offending type internal, and define + /// pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + /// + Type CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options); + + /// + /// Creates a proxy type for given and that delegates all calls to the provided interceptors and allows interceptors to switch the actual target of invocation. + /// + /// The interface type to proxy. + /// Additional interface types to proxy. + /// The proxy generation options. + /// The generated proxy type. + /// + /// Implementers should return a proxy type for the specified interface(s) that delegate all executions to the specified interceptors + /// and uses an instance of the interface as their targets (i.e. ), rather than a class. All classes should then implement interface, + /// to allow interceptors to switch invocation target with instance of another type implementing called interface. + /// + /// Thrown when or any of is a generic type definition. + /// Thrown when or any of is not public. + /// Note that to avoid this exception, you can mark offending type internal, and define + /// pointing to Castle Dynamic Proxy assembly, in assembly containing that type, if this is appropriate. + /// + Type CreateInterfaceProxyTypeWithTargetInterface(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options); + + Type CreateClassProxyTypeWithTarget(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IProxyGenerationHook.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IProxyGenerationHook.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IProxyGenerationHook.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IProxyGenerationHook.cs Sun Feb 13 22:20:50 2011 @@ -0,0 +1,50 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Reflection; + + /// + /// Used during the target type inspection process. Implementors have a chance to customize the + /// proxy generation process. + /// + internal interface IProxyGenerationHook + { + /// + /// Invoked by the generation process to determine if the specified method should be proxied. + /// + /// The type which declares the given method. + /// The method to inspect. + /// True if the given method should be proxied; false otherwise. + bool ShouldInterceptMethod(Type type, MethodInfo methodInfo); + + /// + /// Invoked by the generation process to notify that a member was not marked as virtual. + /// + /// The type which declares the non-virtual member. + /// The non-virtual member. + /// + /// This method gives an opportunity to inspect any non-proxyable member of a type that has + /// been requested to be proxied, and if appropriate - throw an exception to notify the caller. + /// + void NonProxyableMemberNotification(Type type, MemberInfo memberInfo); + + /// + /// Invoked by the generation process to notify that the whole process has completed. + /// + void MethodsInspected(); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IProxyTargetAccessor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\IProxyTargetAccessor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\IProxyTargetAccessor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\IProxyTargetAccessor.cs Mon Feb 14 13:24:06 2011 @@ -0,0 +1,32 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + // [ILMergeExclude] + internal interface IProxyTargetAccessor + { + /// + /// Get the proxy target (note that null is a valid target!) + /// + /// + object DynProxyGetTarget(); + + /// + /// Gets the interceptors for the proxy + /// + /// + IInterceptor[] GetInterceptors(); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\MixinData.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\MixinData.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\MixinData.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\MixinData.cs Sun Feb 13 21:01:58 2011 @@ -0,0 +1,133 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Collections.Generic; + +namespace Castle.DynamicProxy +{ + internal class MixinData + { + private readonly List mixinsImpl = new List(); + private readonly Dictionary mixinPositions = new Dictionary(); + + /// + /// Because we need to cache the types based on the mixed in mixins, we do the following here: + /// - Get all the mixin interfaces + /// - Sort them by full name + /// - Return them by position + /// + /// The idea is to have reproducable behavior for the case that mixins are registered in different orders. + /// This method is here because it is required + /// + public MixinData(IEnumerable mixinInstances) + { + if (mixinInstances != null) + { + List sortedMixedInterfaceTypes = new List(); + Dictionary interface2Mixin = new Dictionary(); + + foreach (object mixin in mixinInstances) + { + Type[] mixinInterfaces = mixin.GetType().GetInterfaces(); + + foreach (Type inter in mixinInterfaces) + { + sortedMixedInterfaceTypes.Add(inter); + + if (interface2Mixin.ContainsKey(inter)) + { + string message = string.Format( + "The list of mixins contains two mixins implementing the same interface '{0}': {1} and {2}. An interface cannot be added by more than one mixin.", + inter.FullName, + interface2Mixin[inter].GetType().Name, + mixin.GetType().Name); + throw new ArgumentException(message, "mixinInstances"); + } + + interface2Mixin[inter] = mixin; + } + } + sortedMixedInterfaceTypes.Sort( + delegate (Type x, Type y) { return x.FullName.CompareTo (y.FullName); }); + + for (int i = 0; i < sortedMixedInterfaceTypes.Count; i++) + { + Type mixinInterface = sortedMixedInterfaceTypes[i]; + object mixin = interface2Mixin[mixinInterface]; + + mixinPositions[mixinInterface] = i; + mixinsImpl.Add (mixin); + } + } + } + + public IEnumerable Mixins + { + get { return mixinsImpl; } + } + + public IEnumerable MixinInterfaces + { + get { return mixinPositions.Keys; } + } + + public int GetMixinPosition(Type mixinInterfaceType) + { + return mixinPositions[mixinInterfaceType]; + } + + public bool ContainsMixin(Type mixinInterfaceType) + { + return mixinPositions.ContainsKey(mixinInterfaceType); + } + + public object GetMixinInstance(Type mixinInterfaceType) + { + return mixinsImpl[mixinPositions[mixinInterfaceType]]; + } + + // For two MixinData objects being regarded equal, only the sorted mixin types are considered, not the actual instances. + public override bool Equals(object obj) + { + if (object.ReferenceEquals(this, obj)) + return true; + + MixinData other = obj as MixinData; + if (object.ReferenceEquals(other, null)) + return false; + + if (mixinsImpl.Count != other.mixinsImpl.Count) + return false; + + for (int i = 0; i < mixinsImpl.Count; ++i) + { + if (mixinsImpl[i].GetType() != other.mixinsImpl[i].GetType()) + return false; + } + + return true; + } + + // For two MixinData objects being regarded equal, only the mixin types are considered, not the actual instances. + public override int GetHashCode() + { + int hashCode = 0; + foreach (object mixinImplementation in mixinsImpl) + hashCode = 29*hashCode + mixinImplementation.GetType().GetHashCode(); + + return hashCode; + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ModuleScope.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\ModuleScope.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ModuleScope.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\ModuleScope.cs Mon Feb 14 13:19:24 2011 @@ -0,0 +1,537 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Reflection; + using System.Reflection.Emit; + using System.Resources; + using Castle.DynamicProxy.Generators; + using Castle.Core.Internal; + +#if SILVERLIGHT + using Castle.DynamicProxy.SilverlightExtensions; +#endif + + /// + /// Summary description for ModuleScope. + /// + internal class ModuleScope + { + /// + /// The default file name used when the assembly is saved using . + /// + public static readonly String DEFAULT_FILE_NAME = "CastleDynProxy2.dll"; + + /// + /// The default assembly (simple) name used for the assemblies generated by a instance. + /// + public static readonly String DEFAULT_ASSEMBLY_NAME = "DynamicProxyGenAssembly2"; + + private ModuleBuilder moduleBuilderWithStrongName; + private ModuleBuilder moduleBuilder; + + // The names to use for the generated assemblies and the paths (including the names) of their manifest modules + private readonly string strongAssemblyName; + private readonly string weakAssemblyName; + private readonly string strongModulePath; + private readonly string weakModulePath; + + // Keeps track of generated types + private readonly Dictionary typeCache = new Dictionary(); + + // Users of ModuleScope should use this lock when accessing the cache + private readonly Lock cacheLock = Lock.Create(); + + // Used to lock the module builder creation + private readonly object moduleLocker = new object(); + + // Specified whether the generated assemblies are intended to be saved + private readonly bool savePhysicalAssembly; + private readonly bool disableSignedModule; + private readonly INamingScope namingScope; + + /// + /// Initializes a new instance of the class; assemblies created by this instance will not be saved. + /// + public ModuleScope() : this(false, false) + { + } + + /// + /// Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + /// should be saved. + /// + /// If set to true saves the generated module. + public ModuleScope(bool savePhysicalAssembly) + : this(savePhysicalAssembly, false) + { + } + + /// + /// Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + /// should be saved. + /// + /// If set to true saves the generated module. + /// If set to true disables ability to generate signed module. This should be used in cases where ran under constrained permissions. + public ModuleScope(bool savePhysicalAssembly, bool disableSignedModule) + : this(savePhysicalAssembly, disableSignedModule, DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME, DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME) + { + } + + /// + /// Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + /// should be saved and what simple names are to be assigned to them. + /// + /// If set to true saves the generated module. + /// If set to true disables ability to generate signed module. This should be used in cases where ran under constrained permissions. + /// The simple name of the strong-named assembly generated by this . + /// The path and file name of the manifest module of the strong-named assembly generated by this . + /// The simple name of the weak-named assembly generated by this . + /// The path and file name of the manifest module of the weak-named assembly generated by this . + public ModuleScope(bool savePhysicalAssembly, bool disableSignedModule, string strongAssemblyName, string strongModulePath, + string weakAssemblyName, string weakModulePath) : this(savePhysicalAssembly, disableSignedModule, new NamingScope(), strongAssemblyName, strongModulePath, weakAssemblyName, weakModulePath) + { + } + + /// + /// Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance + /// should be saved and what simple names are to be assigned to them. + /// + /// If set to true saves the generated module. + /// If set to true disables ability to generate signed module. This should be used in cases where ran under constrained permissions. + /// Naming scope used to provide unique names to generated types and their members (usually via sub-scopes). + /// The simple name of the strong-named assembly generated by this . + /// The path and file name of the manifest module of the strong-named assembly generated by this . + /// The simple name of the weak-named assembly generated by this . + /// The path and file name of the manifest module of the weak-named assembly generated by this . + public ModuleScope(bool savePhysicalAssembly, bool disableSignedModule, INamingScope namingScope, string strongAssemblyName, string strongModulePath, + string weakAssemblyName, string weakModulePath) + { + this.savePhysicalAssembly = savePhysicalAssembly; + this.disableSignedModule = disableSignedModule; + this.namingScope = namingScope; + this.strongAssemblyName = strongAssemblyName; + this.strongModulePath = strongModulePath; + this.weakAssemblyName = weakAssemblyName; + this.weakModulePath = weakModulePath; + } + + public INamingScope NamingScope + { + get { return namingScope; } + } + + /// + /// Users of this should use this lock when accessing the cache. + /// + public Lock Lock + { + get { return cacheLock; } + } + + /// + /// Returns a type from this scope's type cache, or null if the key cannot be found. + /// + /// The key to be looked up in the cache. + /// The type from this scope's type cache matching the key, or null if the key cannot be found + public Type GetFromCache(CacheKey key) + { + Type type; + typeCache.TryGetValue(key, out type); + return type; + } + + /// + /// Registers a type in this scope's type cache. + /// + /// The key to be associated with the type. + /// The type to be stored in the cache. + public void RegisterInCache(CacheKey key, Type type) + { + typeCache[key] = type; + } + + /// + /// Gets the key pair used to sign the strong-named assembly generated by this . + /// + /// + public static byte[] GetKeyPair() + { + + using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("NMock.Castle.DynamicProxy.DynProxy.snk")) + { + if (stream == null) + throw new MissingManifestResourceException( + "Should have a NMock.Castle.DynamicProxy.DynProxy.snk as an embedded resource, so Dynamic Proxy could sign generated assembly"); + + var length = (int)stream.Length; + var keyPair = new byte[length]; + stream.Read(keyPair, 0, length); + return keyPair; + } + } + + /// + /// Gets the strong-named module generated by this scope, or if none has yet been generated. + /// + /// The strong-named module generated by this scope, or if none has yet been generated. + public ModuleBuilder StrongNamedModule + { + get { return moduleBuilderWithStrongName; } + } + + /// + /// Gets the file name of the strongly named module generated by this scope. + /// + /// The file name of the strongly named module generated by this scope. + public string StrongNamedModuleName + { + get { return Path.GetFileName(strongModulePath); } + } + +#if !SILVERLIGHT + /// + /// Gets the directory where the strongly named module generated by this scope will be saved, or if the current directory + /// is used. + /// + /// The directory where the strongly named module generated by this scope will be saved when is called + /// (if this scope was created to save modules). + public string StrongNamedModuleDirectory + { + get + { + var directory = Path.GetDirectoryName(strongModulePath); + if (string.IsNullOrEmpty(directory)) + { + return null; + } + return directory; + } + } +#endif + + /// + /// Gets the weak-named module generated by this scope, or if none has yet been generated. + /// + /// The weak-named module generated by this scope, or if none has yet been generated. + public ModuleBuilder WeakNamedModule + { + get { return moduleBuilder; } + } + + /// + /// Gets the file name of the weakly named module generated by this scope. + /// + /// The file name of the weakly named module generated by this scope. + public string WeakNamedModuleName + { + get { return Path.GetFileName(weakModulePath); } + } + +#if !SILVERLIGHT + /// + /// Gets the directory where the weakly named module generated by this scope will be saved, or if the current directory + /// is used. + /// + /// The directory where the weakly named module generated by this scope will be saved when is called + /// (if this scope was created to save modules). + public string WeakNamedModuleDirectory + { + get + { + string directory = Path.GetDirectoryName(weakModulePath); + if (directory == string.Empty) + { + return null; + } + return directory; + } + } +#endif + + /// + /// Gets the specified module generated by this scope, creating a new one if none has yet been generated. + /// + /// If set to true, a strong-named module is returned; otherwise, a weak-named module is returned. + /// A strong-named or weak-named module generated by this scope, as specified by the parameter. + public ModuleBuilder ObtainDynamicModule(bool isStrongNamed) + { + if (isStrongNamed) + { + return ObtainDynamicModuleWithStrongName(); + } + + return ObtainDynamicModuleWithWeakName(); + } + + /// + /// Gets the strong-named module generated by this scope, creating a new one if none has yet been generated. + /// + /// A strong-named module generated by this scope. + public ModuleBuilder ObtainDynamicModuleWithStrongName() + { + if(disableSignedModule) + { + throw new InvalidOperationException( + "Usage of signed module has been disabled. Use unsigned module or enable signed module."); + } + lock (moduleLocker) + { + if (moduleBuilderWithStrongName == null) + { + moduleBuilderWithStrongName = CreateModule(true); + } + return moduleBuilderWithStrongName; + } + } + + /// + /// Gets the weak-named module generated by this scope, creating a new one if none has yet been generated. + /// + /// A weak-named module generated by this scope. + public ModuleBuilder ObtainDynamicModuleWithWeakName() + { + lock (moduleLocker) + { + if (moduleBuilder == null) + { + moduleBuilder = CreateModule(false); + } + return moduleBuilder; + } + } + + private ModuleBuilder CreateModule(bool signStrongName) + { + AssemblyName assemblyName = GetAssemblyName(signStrongName); + + var moduleName = signStrongName ? StrongNamedModuleName : WeakNamedModuleName; +#if !SILVERLIGHT + var moduleDirectory = signStrongName ? StrongNamedModuleDirectory : WeakNamedModuleDirectory; + + if (savePhysicalAssembly) + { + AssemblyBuilder assemblyBuilder; + try + { + assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( + assemblyName, AssemblyBuilderAccess.RunAndSave, moduleDirectory); + } + catch (ArgumentException e) + { + if (signStrongName == false && e.StackTrace.Contains("ComputePublicKey") == false) + { + // I have no idea what that could be + throw; + } + string message = + string.Format( + "There was an error creating dynamic assembly for your proxies - you don't have permissions required to sing the assembly. To workaround it you can enfornce generating non-signed assembly only when creating {0}. ALternatively ensure that your account has all the required permissions.", + GetType()); + throw new ArgumentException(message, e); + } + var module = assemblyBuilder.DefineDynamicModule(moduleName, moduleName, false); + return module; + } + else +#endif + { + AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( + assemblyName, + AssemblyBuilderAccess.Run); + + var module = assemblyBuilder.DefineDynamicModule(moduleName, false); + return module; + } + } + + private AssemblyName GetAssemblyName(bool signStrongName) + { + var assemblyName = new AssemblyName + { + Name = signStrongName ? strongAssemblyName : weakAssemblyName + }; + +#if !SILVERLIGHT + if (signStrongName) + { + byte[] keyPairStream = GetKeyPair(); + if (keyPairStream != null) + { + assemblyName.KeyPair = new StrongNameKeyPair(keyPairStream); + } + } +#endif + return assemblyName; + } + +#if !SILVERLIGHT + /// + /// Saves the generated assembly with the name and directory information given when this instance was created (or with + /// the and current directory if none was given). + /// + /// + /// + /// This method stores the generated assembly in the directory passed as part of the module information specified when this instance was + /// constructed (if any, else the current directory is used). If both a strong-named and a weak-named assembly + /// have been generated, it will throw an exception; in this case, use the overload. + /// + /// + /// If this was created without indicating that the assembly should be saved, this method does nothing. + /// + /// Both a strong-named and a weak-named assembly have been generated. + /// The path of the generated assembly file, or null if no file has been generated. + public string SaveAssembly() + { + if (!savePhysicalAssembly) + return null; + + if (StrongNamedModule != null && WeakNamedModule != null) + throw new InvalidOperationException("Both a strong-named and a weak-named assembly have been generated."); + + if (StrongNamedModule != null) + return SaveAssembly(true); + + if (WeakNamedModule != null) + return SaveAssembly(false); + + return null; + } + + /// + /// Saves the specified generated assembly with the name and directory information given when this instance was created + /// (or with the and current directory if none was given). + /// + /// True if the generated assembly with a strong name should be saved (see ); + /// false if the generated assembly without a strong name should be saved (see . + /// + /// + /// This method stores the specified generated assembly in the directory passed as part of the module information specified when this instance was + /// constructed (if any, else the current directory is used). + /// + /// + /// If this was created without indicating that the assembly should be saved, this method does nothing. + /// + /// + /// No assembly has been generated that matches the parameter. + /// + /// The path of the generated assembly file, or null if no file has been generated. + public string SaveAssembly(bool strongNamed) + { + if (!savePhysicalAssembly) + return null; + + AssemblyBuilder assemblyBuilder; + string assemblyFileName; + string assemblyFilePath; + + if (strongNamed) + { + if (StrongNamedModule == null) + { + throw new InvalidOperationException("No strong-named assembly has been generated."); + } + assemblyBuilder = (AssemblyBuilder)StrongNamedModule.Assembly; + assemblyFileName = StrongNamedModuleName; + assemblyFilePath = StrongNamedModule.FullyQualifiedName; + } + else + { + if (WeakNamedModule == null) + { + throw new InvalidOperationException("No weak-named assembly has been generated."); + } + assemblyBuilder = (AssemblyBuilder)WeakNamedModule.Assembly; + assemblyFileName = WeakNamedModuleName; + assemblyFilePath = WeakNamedModule.FullyQualifiedName; + } + + if (File.Exists(assemblyFilePath)) + { + File.Delete(assemblyFilePath); + } + + AddCacheMappings(assemblyBuilder); + assemblyBuilder.Save(assemblyFileName); + return assemblyFilePath; + } +#endif + +#if !SILVERLIGHT + private void AddCacheMappings(AssemblyBuilder builder) + { + Dictionary mappings; + + using (Lock.ForReading()) + { + mappings = new Dictionary(); + foreach (KeyValuePair cacheEntry in typeCache) + { + mappings.Add(cacheEntry.Key, cacheEntry.Value.FullName); + } + } + + CacheMappingsAttribute.ApplyTo(builder, mappings); + } +#endif + +#if !SILVERLIGHT + /// + /// Loads the generated types from the given assembly into this 's cache. + /// + /// The assembly to load types from. This assembly must have been saved via or + /// , or it must have the manually applied. + /// + /// This method can be used to load previously generated and persisted proxy types from disk into this scope's type cache, eg. in order + /// to avoid the performance hit associated with proxy generation. + /// + public void LoadAssemblyIntoCache(Assembly assembly) + { + if (assembly == null) + throw new ArgumentNullException("assembly"); + + CacheMappingsAttribute[] cacheMappings = + (CacheMappingsAttribute[])assembly.GetCustomAttributes(typeof(CacheMappingsAttribute), false); + + if (cacheMappings.Length == 0) + { + string message = string.Format( + "The given assembly '{0}' does not contain any cache information for generated types.", + assembly.FullName); + throw new ArgumentException(message, "assembly"); + } + + foreach (KeyValuePair mapping in cacheMappings[0].GetDeserializedMappings()) + { + Type loadedType = assembly.GetType(mapping.Value); + + if (loadedType != null) + { + RegisterInCache(mapping.Key, loadedType); + } + } + } +#endif + + public TypeBuilder DefineType(bool inSignedModulePreferably, string name, TypeAttributes flags) + { + var module = ObtainDynamicModule(disableSignedModule == false && inSignedModulePreferably); + return module.DefineType(name, flags); + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\PersistentProxyBuilder.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\PersistentProxyBuilder.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\PersistentProxyBuilder.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\PersistentProxyBuilder.cs Sun Feb 13 20:06:15 2011 @@ -0,0 +1,45 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ +#if !SILVERLIGHT + /// + /// ProxyBuilder that persists the generated type. + /// + /// + /// The saved assembly contains just the last generated type. + /// + internal class PersistentProxyBuilder : DefaultProxyBuilder + { + /// + /// Initializes a new instance of the class. + /// + public PersistentProxyBuilder() : base(new ModuleScope(true)) + { + } + + /// + /// Saves the generated assembly to a physical file. Note that this renders the unusable. + /// + /// The path of the generated assembly file, or null if no assembly has been generated. + /// This method does not support saving multiple files. If both a signed and an unsigned module have been generated, use the + /// respective methods of the . + public string SaveAssembly() + { + return ModuleScope.SaveAssembly(); + } + } +#endif +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ProxyGenerationException.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\ProxyGenerationException.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ProxyGenerationException.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\ProxyGenerationException.cs Sun Feb 13 20:06:09 2011 @@ -0,0 +1,29 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + + internal class ProxyGenerationException : Exception + { + public ProxyGenerationException(string message) : base(message) + { + } + + public ProxyGenerationException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ProxyGenerationOptions.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\ProxyGenerationOptions.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ProxyGenerationOptions.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\ProxyGenerationOptions.cs Sun Feb 13 20:06:02 2011 @@ -0,0 +1,186 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + using System.Reflection.Emit; + using System.Runtime.Serialization; +#if DOTNET40 + using System.Security; +#endif + +#if SILVERLIGHT + internal class ProxyGenerationOptions +#else + [Serializable] + internal class ProxyGenerationOptions : ISerializable +#endif + { + public static readonly ProxyGenerationOptions Default = new ProxyGenerationOptions(); + + private List mixins; + internal readonly IList attributesToAddToGeneratedTypes = new List(); + private readonly IList additionalAttributes = new List(); + +#if SILVERLIGHT +#else + [NonSerialized] +#endif + private MixinData mixinData; // this is calculated dynamically on proxy type creation + + /// + /// Initializes a new instance of the class. + /// + /// The hook. + public ProxyGenerationOptions(IProxyGenerationHook hook) + { + BaseTypeForInterfaceProxy = typeof(object); + Hook = hook; + } + + /// + /// Initializes a new instance of the class. + /// + public ProxyGenerationOptions() + : this(new AllMethodsHook()) + { + } + +#if !SILVERLIGHT + private ProxyGenerationOptions(SerializationInfo info, StreamingContext context) + { + Hook = (IProxyGenerationHook)info.GetValue("hook", typeof(IProxyGenerationHook)); + Selector = (IInterceptorSelector)info.GetValue("selector", typeof(IInterceptorSelector)); + mixins = (List)info.GetValue("mixins", typeof(List)); + BaseTypeForInterfaceProxy = Type.GetType(info.GetString("baseTypeForInterfaceProxy.AssemblyQualifiedName")); + } +#endif + + public void Initialize() + { + if (mixinData == null) + { + try + { + mixinData = new MixinData(mixins); + } + catch (ArgumentException ex) + { + throw new InvalidMixinConfigurationException("There is a problem with the mixins added to this ProxyGenerationOptions: " + ex.Message, ex); + } + } + } + +#if !SILVERLIGHT +#if DOTNET40 + [SecurityCritical] +#endif + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("hook", Hook); + info.AddValue("selector", Selector); + info.AddValue("mixins", mixins); + info.AddValue("baseTypeForInterfaceProxy.AssemblyQualifiedName", BaseTypeForInterfaceProxy.AssemblyQualifiedName); + } +#endif + + public IProxyGenerationHook Hook { get; set; } + + public IInterceptorSelector Selector { get; set; } + + public Type BaseTypeForInterfaceProxy { get; set; } + + [Obsolete("This property is obsolete and will be removed in future versions. Use AdditionalAttributes property instead. " + + "You can use AttributeUtil class to simplify creating CustomAttributeBuilder instances for common cases.")] + public IList AttributesToAddToGeneratedTypes + { + get { return attributesToAddToGeneratedTypes; } + } + + public IList AdditionalAttributes + { + get { return additionalAttributes; } + } + + public MixinData MixinData + { + get + { + if (mixinData == null) + throw new InvalidOperationException("Call Initialize before accessing the MixinData property."); + return mixinData; + } + } + + public void AddMixinInstance(object instance) + { + if (instance == null) + { + throw new ArgumentNullException("instance"); + } + + if (mixins == null) + { + mixins = new List(); + } + + mixins.Add(instance); + mixinData = null; + } + + public object[] MixinsAsArray() + { + if (mixins == null) return new object[0]; + + return mixins.ToArray(); + } + + public bool HasMixins + { + get { return mixins == null ? false : mixins.Count != 0; } + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) return true; + + var proxyGenerationOptions = obj as ProxyGenerationOptions; + if (ReferenceEquals(proxyGenerationOptions, null)) return false; + + // ensure initialization before accessing MixinData + Initialize(); + proxyGenerationOptions.Initialize(); + + if (!Equals(Hook, proxyGenerationOptions.Hook)) return false; + if (!Equals(Selector == null, proxyGenerationOptions.Selector == null )) return false; + if (!Equals(MixinData, proxyGenerationOptions.MixinData)) return false; + if (!Equals(BaseTypeForInterfaceProxy, proxyGenerationOptions.BaseTypeForInterfaceProxy)) return false; + return true; + } + + public override int GetHashCode() + { + // ensure initialization before accessing MixinData + Initialize(); + + int result = Hook != null ? Hook.GetType().GetHashCode() : 0; + result = 29 * result + (Selector != null ? 1 : 0); + result = 29 * result + MixinData.GetHashCode(); + result = 29 * result + (BaseTypeForInterfaceProxy != null ? BaseTypeForInterfaceProxy.GetHashCode() : 0); + return result; + } + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ProxyGenerator.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\ProxyGenerator.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\ProxyGenerator.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\ProxyGenerator.cs Sun Feb 13 20:05:55 2011 @@ -0,0 +1,1487 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; +#if !SILVERLIGHT + using System.Runtime.InteropServices; + using System.Runtime.Remoting; + using System.Security; + using System.Security.Permissions; +#endif + using System.Text; + using Castle.Core.Internal; + using Castle.Core.Logging; + + /// + /// Provides proxy objects for classes and interfaces. + /// + [CLSCompliant(true)] + internal class ProxyGenerator + { + private ILogger logger = NullLogger.Instance; + private readonly IProxyBuilder proxyBuilder; + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Proxy types builder. + public ProxyGenerator(IProxyBuilder builder) + { + proxyBuilder = builder; + +#if !SILVERLIGHT + if (HasSecurityPermission()) + { + Logger = new TraceLogger("Castle.DynamicProxy", LoggerLevel.Warn); + } +#endif + } + +#if !SILVERLIGHT + private bool HasSecurityPermission() + { + const SecurityPermissionFlag flag = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy; + return new SecurityPermission(flag).IsGranted(); + } +#endif + + /// + /// Initializes a new instance of the class. + /// + public ProxyGenerator() : this(new DefaultProxyBuilder()) + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets the that this log to. + /// + public ILogger Logger + { + get { return logger; } + set + { + logger = value; + proxyBuilder.Logger = value; + } + } + + /// + /// Gets the proxy builder instance used to generate proxy types. + /// + /// The proxy builder. + public IProxyBuilder ProxyBuilder + { + get { return proxyBuilder; } + } + + #endregion + + #region CreateInterfaceProxyWithTarget + +#if MONO +#pragma warning disable 1584 // Mono chokes on cref with generic arguments +#endif + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The interceptors called during the invocation of proxied methods. + /// Object proxying calls to members of on object. + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is not an interface type. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + /// use method. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TInterface CreateInterfaceProxyWithTarget(TInterface target, params IInterceptor[] interceptors) + where TInterface : class + { + // NOTE: we don't need to document exception case where interface type is null, since it can never be for a generic method. + // If we leave target as being of type TInterface we also have covered exception where target does not implement TInterface. + + // NOTE: Can any other Activator.CreateInstance exception be thrown in this context? + + return + (TInterface) + CreateInterfaceProxyWithTarget(typeof (TInterface), target, ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of on object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is not an interface type. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + /// use method. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TInterface CreateInterfaceProxyWithTarget(TInterface target, ProxyGenerationOptions options, + params IInterceptor[] interceptors) + where TInterface : class + { + return (TInterface) CreateInterfaceProxyWithTarget(typeof (TInterface), target, options, interceptors); + } + +#if MONO +#pragma warning restore 1584 +#endif + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + /// use method. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithTarget(Type interfaceToProxy, object target, params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithTarget(interfaceToProxy, target, ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + /// use method. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithTarget(Type interfaceToProxy, object target, ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithTarget(interfaceToProxy, null, target, options, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// Additional interface types. Calls to their members will be proxied as well. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of and types on object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + /// use method. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, object target, + params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithTarget(interfaceToProxy, additionalInterfacesToProxy, target, + ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// Additional interface types. Calls to their members will be proxied as well. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of and types on object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method generates new proxy type for each type of , which affects performance. If you don't want to proxy types differently depending on the type of the target + /// use method. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public virtual object CreateInterfaceProxyWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + object target, + ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + if (interfaceToProxy == null) + { + throw new ArgumentNullException("interfaceToProxy"); + } + if (target == null) + { + throw new ArgumentNullException("target"); + } + if (interceptors == null) + { + throw new ArgumentNullException("interceptors"); + } + + if (!interfaceToProxy.IsInterface) + { + throw new ArgumentException("Specified type is not an interface", "interfaceToProxy"); + } + + var targetType = target.GetType(); + if (!interfaceToProxy.IsAssignableFrom(targetType)) + { + throw new ArgumentException("Target does not implement interface " + interfaceToProxy.FullName, "target"); + } + + CheckNotGenericTypeDefinition(interfaceToProxy, "interfaceToProxy"); + CheckNotGenericTypeDefinitions(additionalInterfacesToProxy, "additionalInterfacesToProxy"); + + var generatedType = CreateInterfaceProxyTypeWithTarget(interfaceToProxy, additionalInterfacesToProxy, targetType, + options); + + var arguments = GetConstructorArguments(target, interceptors, options); + return Activator.CreateInstance(generatedType, arguments.ToArray()); + } + + protected List GetConstructorArguments(object target, IInterceptor[] interceptors, + ProxyGenerationOptions options) + { + // create constructor arguments (initialized with mixin implementations, interceptors and target type constructor arguments) + var arguments = new List(options.MixinData.Mixins) {interceptors, target}; + if (options.Selector != null) + { + arguments.Add(options.Selector); + } + return arguments; + } + + #endregion + + #region CreateInterfaceProxyWithTargetInterface + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// Interceptors can use interface to provide other target for method invocation than default . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithTargetInterface(Type interfaceToProxy, object target, + params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithTargetInterface(interfaceToProxy, target, ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// Interceptors can use interface to provide other target for method invocation than default . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is not an interface type. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TInterface CreateInterfaceProxyWithTargetInterface(TInterface target, + params IInterceptor[] interceptors) + where TInterface : class + { + return (TInterface) CreateInterfaceProxyWithTargetInterface(typeof (TInterface), + target, + ProxyGenerationOptions.Default, + interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// Interceptors can use interface to provide other target for method invocation than default . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is not an interface type. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TInterface CreateInterfaceProxyWithTargetInterface(TInterface target, + ProxyGenerationOptions options, + params IInterceptor[] interceptors) + where TInterface : class + { + return (TInterface) CreateInterfaceProxyWithTargetInterface(typeof (TInterface), + target, + options, + interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// Interceptors can use interface to provide other target for method invocation than default . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// Additional interface types. Calls to their members will be proxied as well. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of and types on object or alternative implementation swapped at runtime by an interceptor. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithTargetInterface(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + object target, params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithTargetInterface(interfaceToProxy, additionalInterfacesToProxy, target, + ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// Interceptors can use interface to provide other target for method invocation than default . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on object or alternative implementation swapped at runtime by an interceptor. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithTargetInterface(Type interfaceToProxy, object target, + ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithTargetInterface(interfaceToProxy, null, target, options, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on object with given . + /// Interceptors can use interface to provide other target for method invocation than default . + /// + /// Type of the interface implemented by which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// Additional interface types. Calls to their members will be proxied as well. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of and types on object or alternative implementation swapped at runtime by an interceptor. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not an interface type. + /// Thrown when given does not implement interface. + /// Thrown when no default constructor exists on actual type of object. + /// Thrown when default constructor of actual type of throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// +#if DOTNET40 + [SecuritySafeCritical] +#endif + public virtual object CreateInterfaceProxyWithTargetInterface(Type interfaceToProxy, + Type[] additionalInterfacesToProxy, + object target, ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + //TODO: add to xml comments to show how to use IChangeProxyTarget + + if (target != null && interfaceToProxy.IsInstanceOfType(target) == false) + { + throw new ArgumentException("targetType"); + } + if (interfaceToProxy == null) + { + throw new ArgumentNullException("interfaceToProxy"); + } + if (interceptors == null) + { + throw new ArgumentNullException("interceptors"); + } + + if (!interfaceToProxy.IsInterface) + { + throw new ArgumentException("Specified type is not an interface", "interfaceToProxy"); + } + + var isRemotingProxy = false; + if (target != null && interfaceToProxy.IsAssignableFrom(target.GetType()) == false) + { +#if !SILVERLIGHT + //check if we have remoting proxy at hand... + if (RemotingServices.IsTransparentProxy(target)) + { + var info = (RemotingServices.GetRealProxy(target) as IRemotingTypeInfo); + if (info != null) + { + if (!info.CanCastTo(interfaceToProxy, target)) + { + throw new ArgumentException("Target does not implement interface " + interfaceToProxy.FullName, "target"); + } + isRemotingProxy = true; + } + } + else if (Marshal.IsComObject(target)) + { + var interfaceId = interfaceToProxy.GUID; + if (interfaceId != Guid.Empty) + { + var iUnknown = Marshal.GetIUnknownForObject(target); + var interfacePointer = IntPtr.Zero; + var result = Marshal.QueryInterface(iUnknown, ref interfaceId, out interfacePointer); + if (result == 0 && interfacePointer == IntPtr.Zero) + { + throw new ArgumentException("Target COM object does not implement interface " + interfaceToProxy.FullName, + "target"); + } + } + } + else + { +#endif + throw new ArgumentException("Target does not implement interface " + interfaceToProxy.FullName, "target"); + +#if !SILVERLIGHT + } +#endif + } + + CheckNotGenericTypeDefinition(interfaceToProxy, "interfaceToProxy"); + CheckNotGenericTypeDefinitions(additionalInterfacesToProxy, "additionalInterfacesToProxy"); + + var generatedType = CreateInterfaceProxyTypeWithTargetInterface(interfaceToProxy, additionalInterfacesToProxy, + options); + var arguments = GetConstructorArguments(target, interceptors, options); + if (isRemotingProxy) + { + var constructors = generatedType.GetConstructors(); + + // one .ctor to rule them all + Debug.Assert(constructors.Length == 1, "constructors.Length == 1"); + return constructors[0].Invoke(arguments.ToArray()); + } + return Activator.CreateInstance(generatedType, arguments.ToArray()); + } + + #endregion + + #region CreateInterfaceProxyWithoutTarget + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of types on generated target object. + /// + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is not an interface type. + /// + /// Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// As a result of that also at least one implementation must be provided. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TInterface CreateInterfaceProxyWithoutTarget(IInterceptor interceptor) where TInterface : class + { + return (TInterface) CreateInterfaceProxyWithoutTarget(typeof (TInterface), interceptor); + } + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of types on generated target object. + /// + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is not an interface type. + /// + /// Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// As a result of that also at least one implementation must be provided. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TInterface CreateInterfaceProxyWithoutTarget(params IInterceptor[] interceptors) + where TInterface : class + { + return (TInterface) CreateInterfaceProxyWithoutTarget(typeof (TInterface), interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of types on generated target object. + /// + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is not an interface type. + /// + /// Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// As a result of that also at least one implementation must be provided. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TInterface CreateInterfaceProxyWithoutTarget(ProxyGenerationOptions options, + params IInterceptor[] interceptors) + where TInterface : class + { + return (TInterface) CreateInterfaceProxyWithoutTarget(typeof (TInterface), Type.EmptyTypes, options, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on generated target object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not an interface type. + /// + /// Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, IInterceptor interceptor) + { + return CreateInterfaceProxyWithoutTarget(interfaceToProxy, Type.EmptyTypes, ProxyGenerationOptions.Default, + interceptor); + } + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of type on generated target object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not an interface type. + /// + /// Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithoutTarget(interfaceToProxy, Type.EmptyTypes, ProxyGenerationOptions.Default, + interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// Additional interface types. Calls to their members will be proxied as well. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of and types on generated target object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not an interface type. + /// + /// Since this method uses an empty-shell implementation of interfaces to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithoutTarget(interfaceToProxy, additionalInterfacesToProxy, + ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of on generated target object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not an interface type. + /// + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + return CreateInterfaceProxyWithoutTarget(interfaceToProxy, Type.EmptyTypes, options, interceptors); + } + + /// + /// Creates proxy object intercepting calls to members of interface on target object generated at runtime with given . + /// + /// Type of the interface which will be proxied. + /// The proxy generation options used to influence generated proxy type and object. + /// Additional interface types. Calls to their members will be proxied as well. + /// The interceptors called during the invocation of proxied methods. + /// + /// Object proxying calls to members of and types on generated target object. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given array is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not an interface type. + /// + /// Since this method uses an empty-shell implementation of to proxy generated at runtime, the actual implementation of proxied methods must be provided by given implementations. + /// They are responsible for setting return value (and out parameters) on proxied methods. It is also illegal for an interceptor to call , since there's no actual implementation to proceed with. + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public virtual object CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + if (interfaceToProxy == null) + { + throw new ArgumentNullException("interfaceToProxy"); + } + if (interceptors == null) + { + throw new ArgumentNullException("interceptors"); + } + + if (!interfaceToProxy.IsInterface) + { + throw new ArgumentException("Specified type is not an interface", "interfaceToProxy"); + } + + CheckNotGenericTypeDefinition(interfaceToProxy, "interfaceToProxy"); + CheckNotGenericTypeDefinitions(additionalInterfacesToProxy, "additionalInterfacesToProxy"); + + var generatedType = CreateInterfaceProxyTypeWithoutTarget(interfaceToProxy, additionalInterfacesToProxy, options); + var arguments = GetConstructorArguments(null, interceptors, options); + return Activator.CreateInstance(generatedType, arguments.ToArray()); + } + + #endregion + + #region CreateClassProxy + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The target object, calls to which will be intercepted. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TClass CreateClassProxyWithTarget(TClass target, params IInterceptor[] interceptors) + where TClass : class + { + return (TClass) CreateClassProxyWithTarget(typeof (TClass), + Type.EmptyTypes, + target, + ProxyGenerationOptions.Default, + new object[0], + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TClass CreateClassProxyWithTarget(TClass target, ProxyGenerationOptions options, + params IInterceptor[] interceptors) where TClass : class + { + return (TClass) CreateClassProxyWithTarget(typeof (TClass), + Type.EmptyTypes, + target, + options, + new object[0], + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// Additional interface types. Calls to their members will be proxied as well. + /// The target object, calls to which will be intercepted. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of and types. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxyWithTarget(Type classToProxy, Type[] additionalInterfacesToProxy, object target, + params IInterceptor[] interceptors) + { + return CreateClassProxyWithTarget(classToProxy, + additionalInterfacesToProxy, + target, + ProxyGenerationOptions.Default, + new object[0], + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// Arguments of constructor of type which should be used to create a new instance of that type. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no constructor exists on type with parameters matching . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxyWithTarget(Type classToProxy, object target, ProxyGenerationOptions options, + object[] constructorArguments, params IInterceptor[] interceptors) + { + return CreateClassProxyWithTarget(classToProxy, + Type.EmptyTypes, + target, + options, + constructorArguments, + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The target object, calls to which will be intercepted. + /// Arguments of constructor of type which should be used to create a new instance of that type. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no constructor exists on type with parameters matching . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxyWithTarget(Type classToProxy, object target, object[] constructorArguments, + params IInterceptor[] interceptors) + { + return CreateClassProxyWithTarget(classToProxy, + Type.EmptyTypes, + target, + ProxyGenerationOptions.Default, + constructorArguments, + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The target object, calls to which will be intercepted. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no parameterless constructor exists on type . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxyWithTarget(Type classToProxy, object target, params IInterceptor[] interceptors) + { + return CreateClassProxyWithTarget(classToProxy, + Type.EmptyTypes, + target, + ProxyGenerationOptions.Default, + new object[0], + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxyWithTarget(Type classToProxy, object target, ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + return CreateClassProxyWithTarget(classToProxy, + Type.EmptyTypes, + target, + options, + new object[0], + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// Additional interface types. Calls to their members will be proxied as well. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of and types. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxyWithTarget(Type classToProxy, Type[] additionalInterfacesToProxy, object target, + ProxyGenerationOptions options, params IInterceptor[] interceptors) + { + return CreateClassProxyWithTarget(classToProxy, + additionalInterfacesToProxy, + target, + options, + new object[0], + interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// Additional interface types. Calls to their members will be proxied as well. + /// The target object, calls to which will be intercepted. + /// The proxy generation options used to influence generated proxy type and object. + /// Arguments of constructor of type which should be used to create a new instance of that type. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of and types. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no constructor exists on type with parameters matching . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public virtual object CreateClassProxyWithTarget(Type classToProxy, Type[] additionalInterfacesToProxy, object target, + ProxyGenerationOptions options, object[] constructorArguments, + params IInterceptor[] interceptors) + { + if (classToProxy == null) + { + throw new ArgumentNullException("classToProxy"); + } + if (options == null) + { + throw new ArgumentNullException("options"); + } + if (!classToProxy.IsClass) + { + throw new ArgumentException("'classToProxy' must be a class", "classToProxy"); + } + + CheckNotGenericTypeDefinition(classToProxy, "classToProxy"); + CheckNotGenericTypeDefinitions(additionalInterfacesToProxy, "additionalInterfacesToProxy"); + + var proxyType = CreateClassProxyTypeWithTarget(classToProxy, additionalInterfacesToProxy, options); + + // create constructor arguments (initialized with mixin implementations, interceptors and target type constructor arguments) + var arguments = BuildArgumentListForClassProxyWithTarget(target, options, interceptors); + if (constructorArguments != null && constructorArguments.Length != 0) + { + arguments.AddRange(constructorArguments); + } + return CreateClassProxyInstance(proxyType, arguments, classToProxy, constructorArguments); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TClass CreateClassProxy(params IInterceptor[] interceptors) where TClass : class + { + return (TClass) CreateClassProxy(typeof (TClass), ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public TClass CreateClassProxy(ProxyGenerationOptions options, params IInterceptor[] interceptors) + where TClass : class + { + return (TClass) CreateClassProxy(typeof (TClass), options, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// Additional interface types. Calls to their members will be proxied as well. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of and types. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, + params IInterceptor[] interceptors) + { + return CreateClassProxy(classToProxy, additionalInterfacesToProxy, ProxyGenerationOptions.Default, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The proxy generation options used to influence generated proxy type and object. + /// Arguments of constructor of type which should be used to create a new instance of that type. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no constructor exists on type with parameters matching . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxy(Type classToProxy, ProxyGenerationOptions options, object[] constructorArguments, + params IInterceptor[] interceptors) + { + return CreateClassProxy(classToProxy, null, options, constructorArguments, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// Arguments of constructor of type which should be used to create a new instance of that type. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no constructor exists on type with parameters matching . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxy(Type classToProxy, object[] constructorArguments, params IInterceptor[] interceptors) + { + return CreateClassProxy(classToProxy, null, ProxyGenerationOptions.Default, constructorArguments, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no parameterless constructor exists on type . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxy(Type classToProxy, params IInterceptor[] interceptors) + { + return CreateClassProxy(classToProxy, null, ProxyGenerationOptions.Default, + null, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of type. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxy(Type classToProxy, ProxyGenerationOptions options, params IInterceptor[] interceptors) + { + return CreateClassProxy(classToProxy, null, options, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// Additional interface types. Calls to their members will be proxied as well. + /// The proxy generation options used to influence generated proxy type and object. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of and types. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no default constructor exists on type . + /// Thrown when default constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public object CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, + params IInterceptor[] interceptors) + { + return CreateClassProxy(classToProxy, additionalInterfacesToProxy, options, null, interceptors); + } + + /// + /// Creates proxy object intercepting calls to virtual members of type on newly created instance of that type with given . + /// + /// Type of class which will be proxied. + /// Additional interface types. Calls to their members will be proxied as well. + /// The proxy generation options used to influence generated proxy type and object. + /// Arguments of constructor of type which should be used to create a new instance of that type. + /// The interceptors called during the invocation of proxied methods. + /// + /// New object of type proxying calls to virtual members of and types. + /// + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given object is a null reference (Nothing in Visual Basic). + /// Thrown when given or any of is a generic type definition. + /// Thrown when given is not a class type. + /// Thrown when no constructor exists on type with parameters matching . + /// Thrown when constructor of type throws an exception. + /// + /// This method uses implementation to generate a proxy type. + /// As such caller should expect any type of exception that given implementation may throw. + /// + public virtual object CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options, + object[] constructorArguments, params IInterceptor[] interceptors) + { + if (classToProxy == null) + { + throw new ArgumentNullException("classToProxy"); + } + if (options == null) + { + throw new ArgumentNullException("options"); + } + if (!classToProxy.IsClass) + { + throw new ArgumentException("'classToProxy' must be a class", "classToProxy"); + } + + CheckNotGenericTypeDefinition(classToProxy, "classToProxy"); + CheckNotGenericTypeDefinitions(additionalInterfacesToProxy, "additionalInterfacesToProxy"); + + var proxyType = CreateClassProxyType(classToProxy, additionalInterfacesToProxy, options); + + // create constructor arguments (initialized with mixin implementations, interceptors and target type constructor arguments) + var arguments = BuildArgumentListForClassProxy(options, interceptors); + if (constructorArguments != null && constructorArguments.Length != 0) + { + arguments.AddRange(constructorArguments); + } + return CreateClassProxyInstance(proxyType, arguments, classToProxy, constructorArguments); + } + + protected object CreateClassProxyInstance(Type proxyType, List proxyArguments, Type classToProxy, + object[] constructorArguments) + { + try + { + return Activator.CreateInstance(proxyType, proxyArguments.ToArray()); + } + catch (MissingMethodException) + { + var message = new StringBuilder(); + message.AppendFormat("Can not instantiate proxy of class: {0}.", classToProxy.FullName); + message.AppendLine(); + if (constructorArguments == null || constructorArguments.Length == 0) + { + message.Append("Could not find a parameterless constructor."); + } + else + { + message.AppendLine("Could not find a constructor that would match given arguments:"); + foreach (var argument in constructorArguments) + { + message.AppendLine(argument.GetType().ToString()); + } + } + throw new ArgumentException(message.ToString(), "constructorArguments"); + } + } + + protected void CheckNotGenericTypeDefinition(Type type, string argumentName) + { + if (type != null && type.IsGenericTypeDefinition) + { + throw new ArgumentException("You can't specify a generic type definition.", argumentName); + } + } + + protected void CheckNotGenericTypeDefinitions(IEnumerable types, string argumentName) + { + if (types == null) return; + foreach (var t in types) + { + CheckNotGenericTypeDefinition(t, argumentName); + } + } + + protected List BuildArgumentListForClassProxyWithTarget(object target, ProxyGenerationOptions options, + IInterceptor[] interceptors) + { + var arguments = new List(); + arguments.Add(target); + arguments.AddRange(options.MixinData.Mixins); + arguments.Add(interceptors); + if (options.Selector != null) + { + arguments.Add(options.Selector); + } + return arguments; + } + + protected List BuildArgumentListForClassProxy(ProxyGenerationOptions options, IInterceptor[] interceptors) + { + var arguments = new List(options.MixinData.Mixins) {interceptors}; + if (options.Selector != null) + { + arguments.Add(options.Selector); + } + return arguments; + } + + #endregion + + /// + /// Creates the proxy type for class proxy with given class, implementing given and using provided . + /// + /// The base class for proxy type. + /// The interfaces that proxy type should implement. + /// The options for proxy generation process. + /// of proxy. + protected Type CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options) + { + // create proxy + return ProxyBuilder.CreateClassProxyType(classToProxy, additionalInterfacesToProxy, options); + } + + /// + /// Creates the proxy type for interface proxy with target for given interface, implementing given on given and using provided . + /// + /// The interface proxy type should implement. + /// The additional interfaces proxy type should implement. + /// Actual type that the proxy type will encompass. + /// The options for proxy generation process. + /// of proxy. + protected Type CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + Type targetType, + ProxyGenerationOptions options) + { + // create proxy + return ProxyBuilder.CreateInterfaceProxyTypeWithTarget(interfaceToProxy, additionalInterfacesToProxy, targetType, + options); + } + + /// + /// Creates the proxy type for interface proxy with target interface for given interface, implementing given on given and using provided . + /// + /// The interface proxy type should implement. + /// The additional interfaces proxy type should implement. + /// The options for proxy generation process. + /// of proxy. + protected Type CreateInterfaceProxyTypeWithTargetInterface(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options) + { + // create proxy + return ProxyBuilder.CreateInterfaceProxyTypeWithTargetInterface(interfaceToProxy, additionalInterfacesToProxy, + options); + } + + /// + /// Creates the proxy type for interface proxy without target for given interface, implementing given and using provided . + /// + /// The interface proxy type should implement. + /// The additional interfaces proxy type should implement. + /// The options for proxy generation process. + /// of proxy. + protected Type CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options) + { + // create proxy + return ProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(interfaceToProxy, additionalInterfacesToProxy, options); + } + + protected Type CreateClassProxyTypeWithTarget(Type classToProxy, Type[] additionalInterfacesToProxy, + ProxyGenerationOptions options) + { + // create proxy + return ProxyBuilder.CreateClassProxyTypeWithTarget(classToProxy, additionalInterfacesToProxy, options); + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\RemotableInvocation.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\RemotableInvocation.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\RemotableInvocation.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\RemotableInvocation.cs Sun Feb 13 20:05:48 2011 @@ -0,0 +1,128 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT +namespace Castle.DynamicProxy +{ + using System; + using System.Reflection; + using System.Runtime.Serialization; +#if DOTNET40 + using System.Security; +#endif + + [Serializable] + internal class RemotableInvocation : MarshalByRefObject, IInvocation, ISerializable + { + private readonly IInvocation parent; + + public RemotableInvocation(IInvocation parent) + { + this.parent = parent; + } + + protected RemotableInvocation(SerializationInfo info, StreamingContext context) + { + parent = (IInvocation) info.GetValue("invocation", typeof (IInvocation)); + } + + + public void SetArgumentValue(int index, object value) + { + parent.SetArgumentValue(index, value); + } + + public object GetArgumentValue(int index) + { + return parent.GetArgumentValue(index); + } + + public Type[] GenericArguments + { + get { return parent.GenericArguments; } + } + + /// + /// + /// + /// + public void Proceed() + { + parent.Proceed(); + } + + public object Proxy + { + get { return parent.Proxy; } + } + + public object InvocationTarget + { + get { return parent.InvocationTarget; } + } + + public Type TargetType + { + get { return parent.TargetType; } + } + + public object[] Arguments + { + get { return parent.Arguments; } + } + + /// + /// + /// + public MethodInfo Method + { + get { return parent.Method; } + } + + public MethodInfo GetConcreteMethod() + { + return parent.GetConcreteMethod(); + } + + /// + /// For interface proxies, this will point to the + /// on the target class + /// + public MethodInfo MethodInvocationTarget + { + get { return parent.MethodInvocationTarget; } + } + + public MethodInfo GetConcreteMethodInvocationTarget() + { + return parent.GetConcreteMethodInvocationTarget(); + } + + public object ReturnValue + { + get { return parent.ReturnValue; } + set { parent.ReturnValue = value; } + } + +#if DOTNET40 + [SecurityCritical] +#endif + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof (RemotableInvocation)); + info.AddValue("invocation", new RemotableInvocation(this)); + } + } +} +#endif diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyObjectReference.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyObjectReference.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyObjectReference.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyObjectReference.cs Sun Feb 13 20:11:01 2011 @@ -0,0 +1,320 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT +namespace Castle.DynamicProxy.Serialization +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + using System.Runtime.Serialization; +#if DOTNET40 + using System.Security; +#endif + + using Castle.DynamicProxy; + using Castle.DynamicProxy.Generators; + using Castle.DynamicProxy.Generators.Emitters; + + /// + /// Handles the deserialization of proxies. + /// + [Serializable] + internal class ProxyObjectReference : IObjectReference, ISerializable, IDeserializationCallback + { + private static ModuleScope scope = new ModuleScope(); + + private readonly SerializationInfo info; + private readonly StreamingContext context; + + private readonly Type baseType; + private readonly Type[] interfaces; + private readonly object proxy; + private readonly ProxyGenerationOptions proxyGenerationOptions; + + private bool isInterfaceProxy; + private bool delegateToBase; + + /// + /// Resets the used for deserialization to a new scope. + /// + /// This is useful for test cases. + public static void ResetScope() + { + SetScope(new ModuleScope()); + } + + /// + /// Resets the used for deserialization to a given . + /// + /// The scope to be used for deserialization. + /// By default, the deserialization process uses a different scope than the rest of the application, which can lead to multiple proxies + /// being generated for the same type. By explicitly setting the deserialization scope to the application's scope, this can be avoided. + public static void SetScope(ModuleScope scope) + { + if (scope == null) + throw new ArgumentNullException("scope"); + ProxyObjectReference.scope = scope; + } + + /// + /// Gets the used for deserialization. + /// + /// As has no way of automatically determining the scope used by the application (and the application + /// might use more than one scope at the same time), uses a dedicated scope instance for deserializing proxy + /// types. This instance can be reset and set to a specific value via and . + public static ModuleScope ModuleScope + { + get { return scope; } + } + +#if DOTNET40 + [SecurityCritical] +#endif + protected ProxyObjectReference(SerializationInfo info, StreamingContext context) + { + this.info = info; + this.context = context; + + baseType = DeserializeTypeFromString("__baseType"); + + String[] _interfaceNames = (String[]) info.GetValue("__interfaces", typeof (String[])); + interfaces = new Type[_interfaceNames.Length]; + + for (int i = 0; i < _interfaceNames.Length; i++) + interfaces[i] = Type.GetType(_interfaceNames[i]); + + proxyGenerationOptions = + (ProxyGenerationOptions) info.GetValue("__proxyGenerationOptions", typeof (ProxyGenerationOptions)); + proxy = RecreateProxy(); + + // We'll try to deserialize as much of the proxy state as possible here. This is just best effort; due to deserialization dependency reasons, + // we need to repeat this in OnDeserialization to guarantee correct state deserialization. + DeserializeProxyState(); + } + + private Type DeserializeTypeFromString(string key) + { + return Type.GetType(info.GetString(key), true, false); + } + +#if DOTNET40 + [SecurityCritical] +#endif + protected virtual object RecreateProxy() + { + var generatorType = GetValue("__proxyTypeId"); + if (generatorType.Equals(ProxyTypeConstants.Class)) + { + isInterfaceProxy = false; + return RecreateClassProxy(); + } + if (generatorType.Equals(ProxyTypeConstants.ClassWithTarget)) + { + isInterfaceProxy = false; + return RecreateClassProxyWithTarget(); + } + isInterfaceProxy = true; + return RecreateInterfaceProxy(generatorType); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private object RecreateClassProxyWithTarget() + { + + var generator = new ClassProxyWithTargetGenerator(scope, baseType, interfaces, proxyGenerationOptions); + var proxyType = generator.GetGeneratedType(); + return InstantiateClassProxy(proxyType); + } + +#if DOTNET40 + [SecurityCritical] +#endif + public object RecreateInterfaceProxy(string generatorType) + { + var @interface = DeserializeTypeFromString("__theInterface"); + var targetType = DeserializeTypeFromString("__targetFieldType"); + + InterfaceProxyWithTargetGenerator generator; + if (generatorType == ProxyTypeConstants.InterfaceWithTarget) + { + generator = new InterfaceProxyWithTargetGenerator(scope, @interface); + } + else if (generatorType == ProxyTypeConstants.InterfaceWithoutTarget) + { + generator = new InterfaceProxyWithoutTargetGenerator(scope, @interface); + } + else if (generatorType == ProxyTypeConstants.InterfaceWithTargetInterface) + { + generator = new InterfaceProxyWithTargetInterfaceGenerator(scope, @interface); + } + else + { + throw new InvalidOperationException( + string.Format( + "Got value {0} for the interface generator type, which is not known for the purpose of serialization.", + generatorType)); + } + + var proxyType = generator.GenerateCode(targetType, interfaces, proxyGenerationOptions); + return FormatterServices.GetSafeUninitializedObject(proxyType); + } + +#if DOTNET40 + [SecurityCritical] +#endif + public object RecreateClassProxy() + { + + var generator = new ClassProxyGenerator(scope, baseType); + var proxyType = generator.GenerateCode(interfaces, proxyGenerationOptions); + return InstantiateClassProxy(proxyType); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private object InstantiateClassProxy(Type proxy_type) + { + delegateToBase = GetValue("__delegateToBase"); + if (delegateToBase) + { + return Activator.CreateInstance(proxy_type, new object[] {info, context}); + } + else + { + return FormatterServices.GetSafeUninitializedObject(proxy_type); + } + } + + protected void InvokeCallback(object target) + { + if (target is IDeserializationCallback) + { + (target as IDeserializationCallback).OnDeserialization(this); + } + } + +#if DOTNET40 + [SecurityCritical] +#endif + public object GetRealObject(StreamingContext context) + { + return proxy; + } + +#if DOTNET40 + [SecurityCritical] +#endif + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + // There is no need to implement this method as + // this class would never be serialized. + } + +#if DOTNET40 + [SecuritySafeCritical] +#endif + public void OnDeserialization(object sender) + { + var interceptors = GetValue("__interceptors"); + SetInterceptors(interceptors); + + DeserializeProxyMembers(); + + // Get the proxy state again, to get all those members we couldn't get in the constructor due to deserialization ordering. + DeserializeProxyState(); + InvokeCallback(proxy); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private void DeserializeProxyMembers() + { + var proxyType = proxy.GetType(); + var members = FormatterServices.GetSerializableMembers(proxyType); + + var deserializedMembers = new List(); + var deserializedValues = new List(); + for (int i = 0; i < members.Length; i++) + { + var member = members[i] as FieldInfo; + // we get some inherited members... + if (member.DeclaringType != proxyType) continue; + + Debug.Assert(member != null); + var value = info.GetValue(member.Name, member.FieldType); + deserializedMembers.Add(member); + deserializedValues.Add(value); + } + FormatterServices.PopulateObjectMembers(proxy, deserializedMembers.ToArray(), deserializedValues.ToArray()); + } + +#if DOTNET40 + [SecurityCritical] +#endif + private void DeserializeProxyState() + { + if (isInterfaceProxy) + { + var target = GetValue("__target"); + SetTarget(target); + } + else if (!delegateToBase) + { + var baseMemberData = GetValue("__data"); + MemberInfo[] members = FormatterServices.GetSerializableMembers(baseType); + + // Sort to keep order on both serialize and deserialize side the same, c.f DYNPROXY-ISSUE-127 + members = TypeUtil.Sort(members); + + FormatterServices.PopulateObjectMembers(proxy, members, baseMemberData); + } + } + + private void SetTarget(object target) + { + FieldInfo targetField = proxy.GetType().GetField("__target"); + if (targetField == null) + { + throw new SerializationException( + "The SerializationInfo specifies an invalid interface proxy type, which has no __target field."); + } + + targetField.SetValue(proxy, target); + } + + private void SetInterceptors(IInterceptor[] interceptors) + { + FieldInfo interceptorField = proxy.GetType().GetField("__interceptors"); + if (interceptorField == null) + { + throw new SerializationException( + "The SerializationInfo specifies an invalid proxy type, which has no __interceptors field."); + } + + interceptorField.SetValue(proxy, interceptors); + } + + private T GetValue(string name) + { + return (T)info.GetValue(name, typeof(T)); + } + } +} +#endif \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyTypeConstants.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyTypeConstants.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyTypeConstants.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Serialization\ProxyTypeConstants.cs Sun Feb 13 18:56:57 2011 @@ -0,0 +1,25 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Serialization +{ + internal static class ProxyTypeConstants + { + public static readonly string InterfaceWithoutTarget = "interface.without.target"; + public static readonly string InterfaceWithTarget = "interface.with.target"; + public static readonly string InterfaceWithTargetInterface = "interface.with.target.interface"; + public static readonly string Class = "class"; + public static readonly string ClassWithTarget = "class.with.target"; + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\StandardInterceptor.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\StandardInterceptor.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\StandardInterceptor.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\StandardInterceptor.cs Sun Feb 13 20:05:41 2011 @@ -0,0 +1,46 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy +{ + using System; + +#if SILVERLIGHT + internal class StandardInterceptor : IInterceptor +#else + [Serializable] + internal class StandardInterceptor : MarshalByRefObject, IInterceptor +#endif + { + public void Intercept(IInvocation invocation) + { + PreProceed(invocation); + PerformProceed(invocation); + PostProceed(invocation); + } + + protected virtual void PerformProceed(IInvocation invocation) + { + invocation.Proceed(); + } + + protected virtual void PreProceed(IInvocation invocation) + { + } + + protected virtual void PostProceed(IInvocation invocation) + { + } + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\DelegateMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\DelegateMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\DelegateMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\DelegateMethods.cs Sun Feb 13 20:27:07 2011 @@ -0,0 +1,11 @@ +namespace Castle.DynamicProxy.Tokens +{ + using System; + using System.Reflection; + + internal static class DelegateMethods + { + public static readonly MethodInfo CreateDelegate = + typeof(Delegate).GetMethod("CreateDelegate", new[] { typeof(Type), typeof(object), typeof(MethodInfo) }); + } +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\FormatterServicesMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\FormatterServicesMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\FormatterServicesMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\FormatterServicesMethods.cs Sun Feb 13 20:27:11 2011 @@ -0,0 +1,31 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT +namespace Castle.DynamicProxy.Tokens +{ + using System; + using System.Reflection; + using System.Runtime.Serialization; + + internal static class FormatterServicesMethods + { + public static readonly MethodInfo GetObjectData = + typeof(FormatterServices).GetMethod("GetObjectData", new[] { typeof(object), typeof(MemberInfo[]) }); + + public static readonly MethodInfo GetSerializableMembers = + typeof(FormatterServices).GetMethod("GetSerializableMembers", new[] { typeof(Type) }); + } +} +#endif diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\InvocationMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\InvocationMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\InvocationMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\InvocationMethods.cs Sun Feb 13 20:27:17 2011 @@ -0,0 +1,110 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Tokens +{ + using System; + using System.Reflection; + + /// + /// Holds objects representing methods of class. + /// + internal static class InvocationMethods + { + public static readonly FieldInfo Target = + typeof(CompositionInvocation).GetField("target", BindingFlags.Instance | BindingFlags.NonPublic); + + public static readonly FieldInfo ProxyObject = + typeof(AbstractInvocation).GetField("proxyObject", BindingFlags.Instance | BindingFlags.NonPublic); + + public static readonly MethodInfo GetArguments = + typeof(AbstractInvocation).GetMethod("get_Arguments"); + + public static readonly MethodInfo GetArgumentValue = + typeof(AbstractInvocation).GetMethod("GetArgumentValue"); + + public static readonly MethodInfo GetReturnValue = + typeof(AbstractInvocation).GetMethod("get_ReturnValue"); + + public static readonly MethodInfo ThrowOnNoTarget = + typeof(AbstractInvocation).GetMethod("ThrowOnNoTarget", BindingFlags.Instance | BindingFlags.NonPublic); + + public static readonly MethodInfo SetArgumentValue = + typeof(AbstractInvocation).GetMethod("SetArgumentValue"); + + public static readonly MethodInfo SetGenericMethodArguments = + typeof(AbstractInvocation).GetMethod("SetGenericMethodArguments", new[] { typeof(Type[]) }); + + public static readonly MethodInfo SetReturnValue = + typeof(AbstractInvocation).GetMethod("set_ReturnValue"); + + public static readonly ConstructorInfo InheritanceInvocationConstructorNoSelector = + typeof(InheritanceInvocation).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, + new[] + { + typeof(Type), + typeof(object), + typeof(IInterceptor[]), + typeof(MethodInfo), + typeof(object[]) + }, + null); + + public static readonly ConstructorInfo InheritanceInvocationConstructorWithSelector = + typeof(InheritanceInvocation).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, + new[] + { + typeof(Type), + typeof(object), + typeof(IInterceptor[]), + typeof(MethodInfo), + typeof(object[]), + typeof(IInterceptorSelector), + typeof(IInterceptor[]).MakeByRefType() + }, + null); + + public static readonly ConstructorInfo CompositionInvocationConstructorNoSelector = + typeof(CompositionInvocation).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, + new[] + { + typeof(object), + typeof(object), + typeof(IInterceptor[]), + typeof(MethodInfo), + typeof(object[]) + }, + null); + + public static readonly ConstructorInfo CompositionInvocationConstructorWithSelector = + typeof(CompositionInvocation).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, + new[] + { + typeof(object), + typeof(object), + typeof(IInterceptor[]), + typeof(MethodInfo), + typeof(object[]), + typeof(IInterceptorSelector), + typeof(IInterceptor[]).MakeByRefType() + }, + null); + + public static readonly MethodInfo Proceed = + typeof(AbstractInvocation).GetMethod("Proceed", BindingFlags.Instance | BindingFlags.Public); + + public static readonly MethodInfo EnsureValidTarget = + typeof(CompositionInvocation).GetMethod("EnsureValidTarget", BindingFlags.Instance | BindingFlags.NonPublic); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\MethodBaseMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\MethodBaseMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\MethodBaseMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\MethodBaseMethods.cs Sun Feb 13 20:27:23 2011 @@ -0,0 +1,30 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Tokens +{ + using System; + using System.Reflection; + + internal static class MethodBaseMethods + { + public static readonly MethodInfo GetMethodFromHandle1 = + typeof(MethodBase).GetMethod("GetMethodFromHandle", BindingFlags.Static | BindingFlags.Public, null, + new Type[] { typeof(RuntimeMethodHandle) }, null); + + public static readonly MethodInfo GetMethodFromHandle2 = + typeof(MethodBase).GetMethod("GetMethodFromHandle", BindingFlags.Static | BindingFlags.Public, null, + new Type[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) }, null); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\SerializationInfoMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\SerializationInfoMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\SerializationInfoMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\SerializationInfoMethods.cs Sun Feb 13 20:27:29 2011 @@ -0,0 +1,58 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if !SILVERLIGHT +namespace Castle.DynamicProxy.Tokens +{ + using System; + using System.Reflection; + using System.Runtime.Serialization; + + /// + /// Holds objects representing methods of class. + /// + internal static class SerializationInfoMethods + { + /// + /// + /// + public static readonly MethodInfo AddValue_Bool = + typeof(SerializationInfo).GetMethod("AddValue", new Type[] { typeof(String), typeof(bool) }); + + /// + /// + /// + public static readonly MethodInfo AddValue_Int32 = + typeof(SerializationInfo).GetMethod("AddValue", new Type[] { typeof(String), typeof(int) }); + + /// + /// + /// + public static readonly MethodInfo AddValue_Object = + typeof(SerializationInfo).GetMethod("AddValue", new Type[] { typeof(String), typeof(Object) }); + + /// + /// + /// + public static readonly MethodInfo GetValue = + typeof(SerializationInfo).GetMethod("GetValue", new Type[] { typeof(String), typeof(Type) }); + + /// + /// + /// + public static readonly MethodInfo SetType = + typeof(SerializationInfo).GetMethod("SetType"); + } +} +#endif diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\TypeBuilderMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\TypeBuilderMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\TypeBuilderMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\TypeBuilderMethods.cs Sun Feb 13 20:27:34 2011 @@ -0,0 +1,30 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Tokens +{ + using System; + using System.Reflection; + using System.Reflection.Emit; + + internal static class TypeBuilderMethods + { + public static readonly MethodInfo DefineProperty = + typeof(TypeBuilder).GetMethod("DefineProperty", + new Type[] { + typeof(string), typeof(PropertyAttributes), typeof(CallingConventions), typeof(Type), + typeof(Type[]), typeof(Type[]), typeof(Type[]), typeof(Type[][]), typeof(Type[][]) + }); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\TypeMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\TypeMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\TypeMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\TypeMethods.cs Sun Feb 13 20:27:41 2011 @@ -0,0 +1,28 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Tokens +{ + using System; + using System.Reflection; + + internal static class TypeMethods + { + public static readonly MethodInfo StaticGetType = + typeof(Type).GetMethod("GetType", new[] { typeof(string), typeof(bool), typeof(bool) }); + + public static readonly MethodInfo GetTypeFromHandle = + typeof(Type).GetMethod("GetTypeFromHandle"); + } +} diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\TypeUtilMethods.cs nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\TypeUtilMethods.cs --- nmock3-62490-original\MAIN\Source\Castle\DynamicProxy\Tokens\TypeUtilMethods.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\DynamicProxy\Tokens\TypeUtilMethods.cs Sun Feb 13 20:27:46 2011 @@ -0,0 +1,27 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Tokens +{ + using System.Reflection; + + using Castle.DynamicProxy.Generators.Emitters; + +#if !SILVERLIGHT + internal static class TypeUtilMethods + { + public static readonly MethodInfo Sort = typeof(TypeUtil).GetMethod("Sort",BindingFlags.Public | BindingFlags.Static); + } +#endif +} \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\Castle\Properties\InternalsVisibleToTests.cs nmock3-62490\MAIN\Source\Castle\Properties\InternalsVisibleToTests.cs --- nmock3-62490-original\MAIN\Source\Castle\Properties\InternalsVisibleToTests.cs Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\Castle\Properties\InternalsVisibleToTests.cs Sun Feb 13 18:56:58 2011 @@ -0,0 +1,17 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] diff -r -u -N -w nmock3-62490-original\MAIN\Source\NMock\NMock (net-4.0).csproj nmock3-62490\MAIN\Source\NMock\NMock (net-4.0).csproj --- nmock3-62490-original\MAIN\Source\NMock\NMock (net-4.0).csproj Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\NMock\NMock (net-4.0).csproj Mon Feb 14 14:15:28 2011 @@ -0,0 +1,1091 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {DE24FFEC-1E5E-4F6C-BCA6-836F26B32900} + Library + Properties + NMock + NMock.StrongNamed + v4.0 + 512 + Client + + + true + full + false + bin\net-4.0\Debug\ + DEBUG;TRACE;PHYSICALASSEMBLY;DOTNET;DOTNET40;CLIENTPROFILE;NETFX40 + prompt + 4 + bin\net-4.0\Debug\NMock.StrongNamed.xml + 1591;3021;3014 + + + pdbonly + true + bin\net-4.0\Release\ + TRACE;PHYSICALASSEMBLY;DOTNET;DOTNET40;CLIENTPROFILE;NETFX40 + prompt + 4 + bin\net-4.0\Release\NMock.StrongNamed.xml + 1591;3021;3014 + + + true + + + ..\Solution Items\NMock.snk + + + + + + + + + + + + + + Castle\Components.DictionaryAdapter\AbstractDictionaryAdapter.cs + + + Castle\Components.DictionaryAdapter\AbstractDictionaryAdapterVisitor.cs + + + Castle\Components.DictionaryAdapter\Attributes\ComponentAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\DictionaryAdapterAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\DictionaryBehaviorAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\FetchAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\GroupAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\KeyAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\KeyPrefixAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\KeySubstitutionAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\MultiLevelEditAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\NewGuidAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\OnDemandAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\PropagateNotificationsAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\StringFormatAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\StringListAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\StringStorageAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\StringValuesAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\SuppressNotificationsAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\TypeKeyPrefixAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\XmlNamespaceAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\XPathAttribute.cs + + + Castle\Components.DictionaryAdapter\Attributes\XPathFunctionAttribute.cs + + + Castle\Components.DictionaryAdapter\CascadingDictionaryAdapter.cs + + + Castle\Components.DictionaryAdapter\DefaultPropertyGetter.cs + + + Castle\Components.DictionaryAdapter\DefaultXmlSerializer.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Create.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterBase.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Edit.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Notify.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterBase.Validate.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterFactory.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterInstance.cs + + + Castle\Components.DictionaryAdapter\DictionaryAdapterMeta.cs + + + Castle\Components.DictionaryAdapter\DictionaryDescriptor.cs + + + Castle\Components.DictionaryAdapter\DictionaryValidateGroup.cs + + + Castle\Components.DictionaryAdapter\GenericDictionaryAdapter.cs + + + Castle\Components.DictionaryAdapter\IDictionaryAdapter.cs + + + Castle\Components.DictionaryAdapter\IDictionaryAdapterFactory.cs + + + Castle\Components.DictionaryAdapter\IDictionaryAdapterVisitor.cs + + + Castle\Components.DictionaryAdapter\IDictionaryBehavior.cs + + + Castle\Components.DictionaryAdapter\IDictionaryBehaviorBuilder.cs + + + Castle\Components.DictionaryAdapter\IDictionaryCreate.cs + + + Castle\Components.DictionaryAdapter\IDictionaryCreateStrategy.cs + + + Castle\Components.DictionaryAdapter\IDictionaryEdit.cs + + + Castle\Components.DictionaryAdapter\IDictionaryEqualityHashCodeStrategy.cs + + + Castle\Components.DictionaryAdapter\IDictionaryInitializer.cs + + + Castle\Components.DictionaryAdapter\IDictionaryKeyBuilder.cs + + + Castle\Components.DictionaryAdapter\IDictionaryMetaInitializer.cs + + + Castle\Components.DictionaryAdapter\IDictionaryNotify.cs + + + Castle\Components.DictionaryAdapter\IDictionaryPropertyGetter.cs + + + Castle\Components.DictionaryAdapter\IDictionaryPropertySetter.cs + + + Castle\Components.DictionaryAdapter\IDictionaryValidate.cs + + + Castle\Components.DictionaryAdapter\IDictionaryValidator.cs + + + Castle\Components.DictionaryAdapter\IPropertyDescriptorInitializer.cs + + + Castle\Components.DictionaryAdapter\IXPathSerializer.cs + + + Castle\Components.DictionaryAdapter\NameValueCollectionAdapter.cs + + + Castle\Components.DictionaryAdapter\PropertyDescriptor.cs + + + Castle\Components.DictionaryAdapter\Util\BehaviorVisitor.cs + + + Castle\Components.DictionaryAdapter\Util\BindingListInitializer.cs + + + Castle\Components.DictionaryAdapter\Util\DynamicValue.cs + + + Castle\Components.DictionaryAdapter\Util\DynamicValueDelegate.cs + + + Castle\Components.DictionaryAdapter\Util\EditableBindingList.cs + + + Castle\Components.DictionaryAdapter\Util\EditableList.cs + + + Castle\Components.DictionaryAdapter\Util\IDynamicValue.cs + + + Castle\Components.DictionaryAdapter\Util\IValueInitializer.cs + + + Castle\Components.DictionaryAdapter\Util\PriorityBehavior.cs + + + Castle\Components.DictionaryAdapter\XPathAdapter.cs + + + Castle\Components.DictionaryAdapter\XPathBehavior.cs + + + Castle\Components.DictionaryAdapter\XPathContext.cs + + + Castle\Components.DictionaryAdapter\XPathExtensions.cs + + + Castle\Components.DictionaryAdapter\XPathResult.cs + + + Castle\Core\CollectionExtensions.cs + + + Castle\Core\Configuration\AbstractConfiguration.cs + + + Castle\Core\Configuration\ConfigurationAttributeCollection.cs + + + Castle\Core\Configuration\ConfigurationCollection.cs + + + Castle\Core\Configuration\IConfiguration.cs + + + Castle\Core\Configuration\MutableConfiguration.cs + + + Castle\Core\Configuration\Xml\XmlConfigurationDeserializer.cs + + + Castle\Core\Extensions\SilverlightExtensions.cs + + + Castle\Core\Extensions\SimpleConverter.cs + + + Castle\Core\Internal\AttributesUtil.cs + + + Castle\Core\Internal\ILockHolder.cs + + + Castle\Core\Internal\InternalsVisible.cs + + + Castle\Core\Internal\IUpgradeableLockHolder.cs + + + Castle\Core\Internal\Lock.cs + + + Castle\Core\Internal\MonitorLock.cs + + + Castle\Core\Internal\MonitorLockHolder.cs + + + Castle\Core\Internal\MonitorUpgradeableLockHolder.cs + + + Castle\Core\Internal\NoOpLock.cs + + + Castle\Core\Internal\NoOpUpgradeableLock.cs + + + Castle\Core\Internal\PermissionUtil.cs + + + Castle\Core\Internal\SlimReadLockHolder.cs + + + Castle\Core\Internal\SlimReadWriteLock.cs + + + Castle\Core\Internal\SlimUpgradeableReadLockHolder.cs + + + Castle\Core\Internal\SlimWriteLockHolder.cs + + + Castle\Core\IServiceEnabledComponent.cs + + + Castle\Core\IServiceProviderEx.cs + + + Castle\Core\IServiceProviderExAccessor.cs + + + Castle\Core\Logging\AbstractExtendedLoggerFactory.cs + + + Castle\Core\Logging\AbstractLoggerFactory.cs + + + Castle\Core\Logging\ConsoleFactory.cs + + + Castle\Core\Logging\ConsoleLogger.cs + + + Castle\Core\Logging\DiagnosticsLogger.cs + + + Castle\Core\Logging\DiagnosticsLoggerFactory.cs + + + Castle\Core\Logging\IContextProperties.cs + + + Castle\Core\Logging\IContextStack.cs + + + Castle\Core\Logging\IContextStacks.cs + + + Castle\Core\Logging\IExtendedLogger.cs + + + Castle\Core\Logging\IExtendedLoggerFactory.cs + + + Castle\Core\Logging\ILogger.cs + + + Castle\Core\Logging\ILoggerFactory.cs + + + Castle\Core\Logging\LevelFilteredLogger.cs + + + Castle\Core\Logging\LoggerException.cs + + + Castle\Core\Logging\NullLogFactory.cs + + + Castle\Core\Logging\NullLogger.cs + + + Castle\Core\Logging\StreamLogger.cs + + + Castle\Core\Logging\StreamLoggerFactory.cs + + + Castle\Core\Logging\TraceLogger.cs + + + Castle\Core\Logging\TraceLoggerFactory.cs + + + Castle\Core\Pair.cs + + + Castle\Core\ProxyServices.cs + + + Castle\Core\ReflectionBasedDictionaryAdapter.cs + + + Castle\Core\Resource\AbstractResource.cs + + + Castle\Core\Resource\AbstractStreamResource.cs + + + Castle\Core\Resource\AssemblyBundleResource.cs + + + Castle\Core\Resource\AssemblyResource.cs + + + Castle\Core\Resource\AssemblyResourceFactory.cs + + + Castle\Core\Resource\ConfigResource.cs + + + Castle\Core\Resource\ConfigResourceFactory.cs + + + Castle\Core\Resource\CustomUri.cs + + + Castle\Core\Resource\FileResource.cs + + + Castle\Core\Resource\FileResourceFactory.cs + + + Castle\Core\Resource\IResource.cs + + + Castle\Core\Resource\IResourceFactory.cs + + + Castle\Core\Resource\ResourceException.cs + + + Castle\Core\Resource\StaticContentResource.cs + + + Castle\Core\Resource\UncResource.cs + + + Castle\Core\Resource\UncResourceFactory.cs + + + Castle\Core\Smtp\DefaultSmtpSender.cs + + + Castle\Core\Smtp\IEmailSender.cs + + + Castle\Core\StringObjectDictionaryAdapter.cs + + + Castle\DynamicProxy\AbstractInvocation.cs + + + Castle\DynamicProxy\AllMethodsHook.cs + + + Castle\DynamicProxy\AttributeUtil.cs + + + Castle\DynamicProxy\CacheMappingsAttribute.cs + + + Castle\DynamicProxy\CompositionInvocation.cs + + + Castle\DynamicProxy\Contributors\ClassMembersCollector.cs + + + Castle\DynamicProxy\Contributors\ClassProxyInstanceContributor.cs + + + Castle\DynamicProxy\Contributors\ClassProxyTargetContributor.cs + + + Castle\DynamicProxy\Contributors\ClassProxyWithTargetTargetContributor.cs + + + Castle\DynamicProxy\Contributors\CompositeTypeContributor.cs + + + Castle\DynamicProxy\Contributors\DelegateProxyTargetContributor.cs + + + Castle\DynamicProxy\Contributors\Delegates.cs + + + Castle\DynamicProxy\Contributors\DelegateTypeGenerator.cs + + + Castle\DynamicProxy\Contributors\ForwardingMethodGenerator.cs + + + Castle\DynamicProxy\Contributors\InterfaceMembersCollector.cs + + + Castle\DynamicProxy\Contributors\InterfaceMembersOnClassCollector.cs + + + Castle\DynamicProxy\Contributors\InterfaceProxyInstanceContributor.cs + + + Castle\DynamicProxy\Contributors\InterfaceProxyTargetContributor.cs + + + Castle\DynamicProxy\Contributors\InterfaceProxyWithOptionalTargetContributor.cs + + + Castle\DynamicProxy\Contributors\InterfaceProxyWithoutTargetContributor.cs + + + Castle\DynamicProxy\Contributors\InterfaceProxyWithTargetInterfaceTargetContributor.cs + + + Castle\DynamicProxy\Contributors\InvocationWithDelegateContributor.cs + + + Castle\DynamicProxy\Contributors\InvocationWithGenericDelegateContributor.cs + + + Castle\DynamicProxy\Contributors\ITypeContributor.cs + + + Castle\DynamicProxy\Contributors\MembersCollector.cs + + + Castle\DynamicProxy\Contributors\MinimialisticMethodGenerator.cs + + + Castle\DynamicProxy\Contributors\MixinContributor.cs + + + Castle\DynamicProxy\Contributors\OptionallyForwardingMethodGenerator.cs + + + Castle\DynamicProxy\Contributors\ProxyInstanceContributor.cs + + + Castle\DynamicProxy\Contributors\WrappedClassMembersCollector.cs + + + Castle\DynamicProxy\DefaultProxyBuilder.cs + + + Castle\DynamicProxy\Generators\AttributeDisassembler.cs + + + Castle\DynamicProxy\Generators\AttributesToAvoidReplicating.cs + + + Castle\DynamicProxy\Generators\BaseProxyGenerator.cs + + + Castle\DynamicProxy\Generators\CacheKey.cs + + + Castle\DynamicProxy\Generators\ClassProxyGenerator.cs + + + Castle\DynamicProxy\Generators\ClassProxyWithTargetGenerator.cs + + + Castle\DynamicProxy\Generators\CompositionInvocationTypeGenerator.cs + + + Castle\DynamicProxy\Generators\DelegateMembersCollector.cs + + + Castle\DynamicProxy\Generators\DelegateProxyGenerationHook.cs + + + Castle\DynamicProxy\Generators\DelegateProxyGenerator.cs + + + Castle\DynamicProxy\Generators\Emitters\AbstractTypeEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\ArgumentsUtil.cs + + + Castle\DynamicProxy\Generators\Emitters\ClassEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\CodeBuilders\AbstractCodeBuilder.cs + + + Castle\DynamicProxy\Generators\Emitters\CodeBuilders\ConstructorCodeBuilder.cs + + + Castle\DynamicProxy\Generators\Emitters\CodeBuilders\MethodCodeBuilder.cs + + + Castle\DynamicProxy\Generators\Emitters\ConstructorCollection.cs + + + Castle\DynamicProxy\Generators\Emitters\ConstructorEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\EventCollection.cs + + + Castle\DynamicProxy\Generators\Emitters\EventEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\GenericUtil.cs + + + Castle\DynamicProxy\Generators\Emitters\IMemberEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\LdcOpCodesDictionary.cs + + + Castle\DynamicProxy\Generators\Emitters\LdindOpCodesDictionary.cs + + + Castle\DynamicProxy\Generators\Emitters\MethodCollection.cs + + + Castle\DynamicProxy\Generators\Emitters\MethodEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\NestedClassCollection.cs + + + Castle\DynamicProxy\Generators\Emitters\NestedClassEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\OpCodeUtil.cs + + + Castle\DynamicProxy\Generators\Emitters\PropertiesCollection.cs + + + Castle\DynamicProxy\Generators\Emitters\PropertyEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\AddressOfReferenceExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ArgumentReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArgumentStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignArrayStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\AssignStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\AsTypeReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\BindDelegateExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ByRefReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConstructorInvocationStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ConvertExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\DefaultValueExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\Expression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ExpressionStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\FieldReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\IfNullExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\IILEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\IndirectReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\LiteralIntExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadArrayElementExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\LoadRefArrayElementExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\LocalReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodInvocationExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\MethodTokenExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\MultiStatementExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewArrayExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\NewInstanceExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\NopStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullCoalescingOperatorExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\NullExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\Reference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferenceExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReferencesToObjectArrayExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnReferenceExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ReturnStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\SelfReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\Statement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\ThrowStatement.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeReference.cs + + + Castle\DynamicProxy\Generators\Emitters\SimpleAST\TypeTokenExpression.cs + + + Castle\DynamicProxy\Generators\Emitters\StindOpCodesDictionary.cs + + + Castle\DynamicProxy\Generators\Emitters\StrongNameUtil.cs + + + Castle\DynamicProxy\Generators\Emitters\TypeConstructorEmitter.cs + + + Castle\DynamicProxy\Generators\Emitters\TypeUtil.cs + + + Castle\DynamicProxy\Generators\GeneratorException.cs + + + Castle\DynamicProxy\Generators\GeneratorUtil.cs + + + Castle\DynamicProxy\Generators\IGenerator.cs + + + Castle\DynamicProxy\Generators\IInvocationCreationContributor.cs + + + Castle\DynamicProxy\Generators\INamingScope.cs + + + Castle\DynamicProxy\Generators\InheritanceInvocationTypeGenerator.cs + + + Castle\DynamicProxy\Generators\InterfaceProxyWithoutTargetGenerator.cs + + + Castle\DynamicProxy\Generators\InterfaceProxyWithTargetGenerator.cs + + + Castle\DynamicProxy\Generators\InterfaceProxyWithTargetInterfaceGenerator.cs + + + Castle\DynamicProxy\Generators\InvocationTypeGenerator.cs + + + Castle\DynamicProxy\Generators\MetaEvent.cs + + + Castle\DynamicProxy\Generators\MetaMethod.cs + + + Castle\DynamicProxy\Generators\MetaProperty.cs + + + Castle\DynamicProxy\Generators\MetaType.cs + + + Castle\DynamicProxy\Generators\MetaTypeElement.cs + + + Castle\DynamicProxy\Generators\MethodFinder.cs + + + Castle\DynamicProxy\Generators\MethodGenerator.cs + + + Castle\DynamicProxy\Generators\MethodSignatureComparer.cs + + + Castle\DynamicProxy\Generators\MethodWithInvocationGenerator.cs + + + Castle\DynamicProxy\Generators\NamingScope.cs + + + Castle\DynamicProxy\Generators\TypeElementCollection.cs + + + Castle\DynamicProxy\IAttributeDisassembler.cs + + + Castle\DynamicProxy\IChangeProxyTarget.cs + + + Castle\DynamicProxy\IInterceptor.cs + + + Castle\DynamicProxy\IInterceptorSelector.cs + + + Castle\DynamicProxy\IInvocation.cs + + + Castle\DynamicProxy\InheritanceInvocation.cs + + + Castle\DynamicProxy\InternalsHelper.cs + + + Castle\DynamicProxy\InvalidMixinConfigurationException.cs + + + Castle\DynamicProxy\InvocationHelper.cs + + + Castle\DynamicProxy\IProxyBuilder.cs + + + Castle\DynamicProxy\IProxyGenerationHook.cs + + + Castle\DynamicProxy\IProxyTargetAccessor.cs + + + Castle\DynamicProxy\MixinData.cs + + + Castle\DynamicProxy\ModuleScope.cs + + + Castle\DynamicProxy\PersistentProxyBuilder.cs + + + Castle\DynamicProxy\ProxyGenerationException.cs + + + Castle\DynamicProxy\ProxyGenerationOptions.cs + + + Castle\DynamicProxy\ProxyGenerator.cs + + + Castle\DynamicProxy\RemotableInvocation.cs + + + Castle\DynamicProxy\Serialization\ProxyObjectReference.cs + + + Castle\DynamicProxy\Serialization\ProxyTypeConstants.cs + + + Castle\DynamicProxy\StandardInterceptor.cs + + + Castle\DynamicProxy\Tokens\DelegateMethods.cs + + + Castle\DynamicProxy\Tokens\FormatterServicesMethods.cs + + + Castle\DynamicProxy\Tokens\InvocationMethods.cs + + + Castle\DynamicProxy\Tokens\MethodBaseMethods.cs + + + Castle\DynamicProxy\Tokens\SerializationInfoMethods.cs + + + Castle\DynamicProxy\Tokens\TypeBuilderMethods.cs + + + Castle\DynamicProxy\Tokens\TypeMethods.cs + + + Castle\DynamicProxy\Tokens\TypeUtilMethods.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + + + + + + + + + + Castle\DynamicProxy\DynProxy.snk + + + NMock.snk + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + + + \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\NMock\Properties\AssemblyInfo.cs nmock3-62490\MAIN\Source\NMock\Properties\AssemblyInfo.cs --- nmock3-62490-original\MAIN\Source\NMock\Properties\AssemblyInfo.cs Thu Feb 10 09:53:16 2011 +++ nmock3-62490\MAIN\Source\NMock\Properties\AssemblyInfo.cs Mon Feb 14 14:25:00 2011 @@ -21,3 +21,9 @@ [assembly: InternalsVisibleTo("NMockTestsFx40," + NMock.Constants.NMockPublicKey)] [assembly: InternalsVisibleTo("NMockTestsFx35," + NMock.Constants.NMockPublicKey)] [assembly: InternalsVisibleTo("NMockTestsSl40," + NMock.Constants.NMockPublicKey)] \ No newline at end of file + +#if WEAK_NAMED +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] +#else +[assembly: InternalsVisibleTo(Castle.Core.Internal.InternalsVisible.ToDynamicProxyGenAssembly2)] +#endif \ No newline at end of file diff -r -u -N -w nmock3-62490-original\MAIN\Source\NMock (net-4.0).sln nmock3-62490\MAIN\Source\NMock (net-4.0).sln --- nmock3-62490-original\MAIN\Source\NMock (net-4.0).sln Thu Jan 01 01:00:00 1970 +++ nmock3-62490\MAIN\Source\NMock (net-4.0).sln Sun Feb 13 23:51:24 2011 @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C# Express 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NMock (net-4.0)", "NMock\NMock (net-4.0).csproj", "{DE24FFEC-1E5E-4F6C-BCA6-836F26B32900}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DE24FFEC-1E5E-4F6C-BCA6-836F26B32900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE24FFEC-1E5E-4F6C-BCA6-836F26B32900}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE24FFEC-1E5E-4F6C-BCA6-836F26B32900}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE24FFEC-1E5E-4F6C-BCA6-836F26B32900}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal