diff --git a/Lib/Castle.Core.dll b/Lib/Castle.Core.dll new file mode 100644 index 000000000..a10d59790 Binary files /dev/null and b/Lib/Castle.Core.dll differ diff --git a/Lib/Castle.Core.xml b/Lib/Castle.Core.xml new file mode 100644 index 000000000..50d649b21 --- /dev/null +++ b/Lib/Castle.Core.xml @@ -0,0 +1,3049 @@ + + + + Castle.Core + + + + + This attribute is usefull only when you want to register all components + on an assembly as a batch process. + By doing so, the batch register will look + for this attribute to distinguish components from other classes. + + + + + Base for Attributes that want to express lifestyle + chosen by the component. + + + + + Initializes a new instance of the class. + + The type. + + + + Gets or sets the lifestyle. + + The lifestyle. + + + + Initializes a new instance of the class. + + The key. + + + + Initializes a new instance of the class. + + The key. + The service. + + + + Initializes a new instance of the class. + + The key. + The service. + The lifestyle. + + + + Gets the service. + + The service. + + + + Gets the key. + + The key. + + + + Associates a custom component with a component + + + + + Initializes a new instance of the class. + + Type of the component activator. + + + + Gets the type of the component activator. + + The type of the component activator. + + + + Specifies the proxying behavior for a component. + + + + + Initializes a new instance of the class. + + + + + Gets or sets a value indicating whether the generated + interface proxy should inherit from . + + + + + Determines if the component requires a single interface proxy. + + true if the component requires a single interface proxy. + + + + Gets or sets the additional interfaces used during proxy generation. + + + + + Marks as property to be skipped and not be wired + by the IoC container + + + + + Used to declare that a component wants interceptors acting on it. + + + + + Constructs the InterceptorAttribute pointing to + a key to a interceptor + + + + + + Constructs the InterceptorAttribute pointing to + a service + + + + + + Indicates that the target components wants a + singleton lifestyle. + + + + + Initializes a new instance of the class. + + + + + Indicates that the target components wants a + transient lifestyle. + + + + + Initializes a new instance of the class. + + + + + Indicates that the target components wants a + per thread lifestyle. + + + + + Initializes a new instance of the class. + + + + + Indicates that the target components wants a + per web request lifestyle. + + + + + Indicates that the target components wants a + pooled lifestyle. + + + + + Initializes a new instance of the class + using the default initial pool size (5) and the max pool size (15). + + + + + Initializes a new instance of the class. + + Initial size of the pool. + Max pool size. + + + + Gets the initial size of the pool. + + The initial size of the pool. + + + + Gets the maximum pool size. + + The size of the max pool. + + + + Indicates that the target components wants a + custom lifestyle. + + + + + Initializes a new instance of the class. + + The lifestyle handler. + + + + Gets the type of the lifestyle handler. + + The type of the lifestyle handler. + + + + New interface that is going to be used by DynamicProxy 2 + + + + + New interface that is going to be used by DynamicProxy 2 + + + + + Returns the concrete instantiation of , with any generic parameters bound to real types. + + The concrete instantiation of , or if not a generic method. + Can be slower than calling . + + + + Returns the concrete instantiation of , with any generic parameters bound to real types. + + The concrete instantiation of , or if not a generic method. + Can be slower than calling . + + + + + + + + + + The generic arguments of the method, or null if not a generic method. + + + + + + + + + + For interface proxies, this will point to the + on the target class + + + + + Interceptors might implement this to receive the + ComponentModel on behalf of the component where the + interceptor is acting. + + + + + Get the proxy target (note that null is a valid target!) + + + + + + Gets the interceptors for the proxy + + + + + + Abstract representation of a vertex. + + + + + The nodes that dependes on this node + + + + + The nodes that this node depends + + + + + The node has not been visited yet + + + + + This node is in the process of being visited + + + + + This now was visited + + + + + Represents a collection of objects + which are guaranted to be unique + and holds a color for them + + + + + Holds a timestamp (integer) + for a given item + + + + + Returns the node at the specified index. + + The lookup index. + The node at the specified index. + + If the specified is greater than the + number of objects within the list. + + + + + Validates the specified index. + + The lookup index. + + If the index is invalid. + + + + + Lifecycle interface. If implemented by a component, + the method Initialized will be invoked by the container + before making the component available to the external world. + + + + + Implementors should perform any initialization logic. + + + + + Only called for components that + belongs to a pool when the component + comes back to the pool. + + + + + Implementors should perform any + initialization/clean up. + + + + + Interface for components that wish to be started by the container + + + + + Starts this instance. + + + + + Stops this instance. + + + + + Provides a factory that can produce either or + classes. + + + + + Manages the instantiation of s. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new extended logger, getting the logger name from the specified type. + + + + + Creates a new extended logger. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Creates a new logger, getting the logger name from the specified type. + + + + + Creates a new logger. + + + + + Gets the configuration file. + + i.e. log4net.config + + + + + Gets the configuration file. + + i.e. log4net.config + + + + + Summary description for ConsoleFactory. + + + + + NullLogFactory used when logging is turned off. + + + + + Creates an instance of ILogger with the specified name. + + Name. + + + + + Creates an instance of ILogger with the specified name and LoggerLevel. + + Name. + Level. + + + + + Creates outputing + to files. The name of the file is derived from the log name + plus the 'log' extension. + + + + + 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. + + + + + The Level Filtered Logger class. This is a base clase which + provides a LogLevel attribute and reroutes all functions into + one Log method. + + + + + 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. + + + + + Logs a debug message. + + The message to log + + + + Logs a debug message. + + The exception to log + The message to log + + + + Logs a debug message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs an info message. + + The message to log + + + + Logs an info message. + + The exception to log + The message to log + + + + Logs an info message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs a warn message. + + The message to log + + + + Logs a warn message. + + The exception to log + The message to log + + + + Logs a warn message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs an error message. + + The message to log + + + + Logs an error message. + + The exception to log + The message to log + + + + Logs an error message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs a fatal message. + + The message to log + + + + Logs a fatal message. + + The exception to log + The message to log + + + + Logs a fatal message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs a fatal error message. + + The Message + + + + Logs a fatal error message. + + The Message + The Exception + + + + Logs a fatal error message. + + Message format + Array of objects to write using format + + + + 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. + + + + Determines if messages of priority "debug" will be logged. + + True if "debug" messages will be logged. + + + + Determines if messages of priority "info" will be logged. + + True if "info" messages will be logged. + + + + Determines if messages of priority "warn" will be logged. + + True if "warn" messages will be logged. + + + + Determines if messages of priority "error" will be logged. + + True if "error" messages will be logged. + + + + Determines if messages of priority "fatal" will be logged. + + True if "fatal" messages will be logged. + + + + Determines if messages of priority "fatalError" will be logged. + + True if "fatalError" messages will be logged. + + + + Creates a new LevelFilteredLogger. + + + + + Keep the instance alive in a remoting scenario + + + + + + Logs a debug message. + + The message to log + + + + Logs a debug message. + + The exception to log + The message to log + + + + Logs a debug message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a debug message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs a debug message. + + Message format + Array of objects to write using format + + + + Logs an info message. + + The message to log + + + + Logs an info message. + + The exception to log + The message to log + + + + Logs an info message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an info message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs an info message. + + Message format + Array of objects to write using format + + + + Logs a warn message. + + The message to log + + + + Logs a warn message. + + The exception to log + The message to log + + + + Logs a warn message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a warn message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs a warn message. + + Message format + Array of objects to write using format + + + + Logs an error message. + + The message to log + + + + Logs an error message. + + The exception to log + The message to log + + + + Logs an error message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs an error message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs an error message. + + Message format + Array of objects to write using format + + + + Logs a fatal message. + + The message to log + + + + Logs a fatal message. + + The exception to log + The message to log + + + + Logs a fatal message. + + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The exception to log + Format string for the message to log + Format arguments for the message to log + + + + Logs a fatal message. + + The format provider to use + Format string for the message to log + Format arguments for the message to log + + + + 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 + + + + Logs a fatal message. + + Message format + Array of objects to write using format + + + + Logs a fatal error message. + + The Message + + + + Logs a fatal error message. + + The Message + The Exception + + + + Logs a fatal error message. + + Message format + Array of objects to write using format + + + + Implementors output the log content by implementing this method only. + Note that exception can be null + + + + + + + + + The LoggerLevel that this logger + will be using. Defaults to LoggerLevel.Off + + + + + The name that this logger will be using. + Defaults to String.Empty + + + + + Determines if messages of priority "debug" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "info" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "warn" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "error" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "fatal" will be logged. + + true if log level flags include the bit + + + + Determines if messages of priority "fatal" will be logged. + + true if log level flags include the bit + + + + Creates a new ConsoleLogger with the Level + set to LoggerLevel.Debug and the Name + set to String.Empty. + + + + + Creates a new ConsoleLogger with the Name + set to String.Empty. + + The logs Level. + + + + Creates a new ConsoleLogger with the Level + set to LoggerLevel.Debug. + + The logs Name. + + + + Creates a new ConsoleLogger. + + The logs Name. + The logs Level. + + + + A Common method to log. + + The level of logging + The name of the logger + The Message + The Exception + + + + Returns a new ConsoleLogger with the name + added after this loggers name, with a dot in between. + + The added hierarchical name. + A new ConsoleLogger. + + + + The Logger using standart Diagnostics namespace. + + + + + Creates a logger based on . + + + + + + Creates a logger based on . + + + + + + + Creates a logger based on . + + + + + + + + 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. + + + + + Provides an interface that supports and + allows the storage and retrieval of Contexts. These are supported in + both log4net and NLog. + + + + + Exposes the Global Context of the extended logger. + + + + + Exposes the Thread Context of the extended logger. + + + + + Exposes the Thread Stack of the extended logger. + + + + + Creates a new NullLogger. + + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + Ignored + Ignored + + + + No-op. + + Ignored + + + + No-op. + + Ignored + Ignored + + + + No-op. + + Ignored + Ignored + + + + Returns this NullLogger. + + Ignored + This ILogger instance. + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + No-op. + + false + + + + Returns empty context properties. + + + + + Returns empty context properties. + + + + + Returns empty context stacks. + + + + + Interface for Context Properties implementations + + + + This interface defines a basic property get set accessor. + + + Based on the ContextPropertiesBase of log4net, by Nicko Cadell. + + + + + + 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 + + + + + + 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. + + + + + 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 + + + + + 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. + + + + + + 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. + + + + + + Creates a new StreamLogger with + Debug as default Level. + + The name of the log. + The StreamWriter the log will write to. + + + + The WebLogger sends everything to the HttpContext.Trace + + + Trace must be enabled on the Asp.Net configuration file (web.config or machine.config) + + + + + Creates a new WebLogger with the priority set to DEBUG. + + + + + Creates a new WebLogger. + + The Log level typecode. + + + + Creates a new WebLogger. + + The Log name. + + + + Creates a new WebLogger. + + The Log name. + The Log level typecode. + + + + A Common method to log. + + The level of logging + The Log name. + The Message + The Exception + + + + Just returns this logger (WebLogger is not hierarchical). + + Ignored + This ILogger instance. + + + + Supporting Logger levels. + + + + + Logging will be off + + + + + Fatal logging level + + + + + Error logging level + + + + + Warn logging level + + + + + Info logging level + + + + + Debug logging level + + + + + 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 + + + + + Summary description for IConfiguration. + + + is a interface encapsulating a configuration node + used to retrieve configuration values. + + + + + 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. + + + + Gets the name of the node. + + + The Name of the node. + + + + + Gets the value of the node. + + + The Value of the node. + + + + + Gets an of + elements containing all node children. + + The Collection of child nodes. + + + + Gets an of the configuration 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. + + + + Gets the name of the . + + + The Name of the . + + + + + Gets the value of . + + + The Value of the . + + + + + Gets all child nodes. + + The of child nodes. + + + + Gets node attributes. + + + All attributes of the node. + + + + + A collection of objects. + + + + + Creates a new instance of ConfigurationCollection. + + + + + Creates a new instance of ConfigurationCollection. + + + + + Creates a new instance of ConfigurationCollection. + + + + + Adds an . + + The to add. + + The index at which the new element was inserted. + + + + + Adds an array of . + + The Array of to add. + + + + Adds a . + + The to add. + + + + Copies the elements to a one-dimensional instance at the specified index. + + + The one-dimensional must have zero-based indexing. + + The zero-based index in array at which copying begins. + + + + Gets a value indicating whether the contains + in the collection. + + The to locate. + + if the is contained in the collection; + otherwise, . + + + + + Removes a specific from the + collection. + + The to remove from the collection. + + is not found in the collection. + + + + + Represents the entry at the specified index of the . + + + The zero-based index of the entry to locate in the collection. + + + The entry at the specified index of the collection. + + + is outside the valid range of indexes for the collection. + + + + + Summary description for MutableConfiguration. + + + + + Initializes a new instance of the class. + + The name. + + + + Enumeration used to mark the component's lifestyle. + + + + + No lifestyle specified. + + + + + Singleton components are instantiated once, and shared + between all clients. + + + + + Thread components have a unique instance per thread. + + + + + Transient components are created on demand. + + + + + Optimization of transient components that keeps + instance in a pool instead of always creating them. + + + + + Any other logic to create/release components. + + + + + PerWebRequest components are created once per Http Request + + + + + + + + + + Represents the collection of information and + meta information collected about a component. + + + + Name (key) of the component + + + Service exposed + + + Implementation for the service + + + Extended properties + + + Lifestyle for the component + + + Custom lifestyle, if any + + + Custom activator, if any + + + Dependencies the kernel must resolve + + + All available constructors + + + All potential properties that can be setted by the kernel + + + Steps of lifecycle + + + External parameters + + + Configuration node associated + + + Interceptors associated + + + + Constructs a ComponentModel + + + + + Sets or returns the component key + + + + + Gets or sets the service exposed. + + The service. + + + + Gets or sets the component implementation. + + The implementation. + + + + Gets or sets a value indicating whether the component requires generic arguments. + + + true if generic arguments are required; otherwise, false. + + + + + Gets or sets the extended properties. + + The extended properties. + + + + Gets the constructors candidates. + + The constructors. + + + + Gets the properties set. + + The properties. + + + + Gets or sets the configuration. + + The configuration. + + + + Gets the lifecycle steps. + + The lifecycle steps. + + + + Gets or sets the lifestyle type. + + The type of the lifestyle. + + + + Gets or sets the strategy for + inspecting public properties + on the components + + + + + Gets or sets the custom lifestyle. + + The custom lifestyle. + + + + Gets or sets the custom component activator. + + The custom component activator. + + + + Gets the interceptors. + + The interceptors. + + + + Gets the parameter collection. + + The parameters. + + + + Dependencies are kept within constructors and + properties. Others dependencies must be + registered here, so the kernel (as a matter + of fact the handler) can check them + + + + + Represents a constructor of the component + that the container can use to initialize it properly. + + + + + Initializes a new instance of the class. + + The constructor info. + The dependencies. + + + + Gets the ConstructorInfo (from reflection). + + The constructor. + + + + Gets the dependencies this constructor candidate exposes. + + The dependencies. + + + + Collection of + + + + + Adds the specified candidate. + + The candidate. + + + + Clears this instance. + + + + + Gets the fewer arguments candidate. + + The fewer arguments candidate. + + + + Represents a dependency (other component or a + fixed value available through external configuration). + + + + + Initializes a new instance of the class. + + The type. + The dependency key. + Type of the target. + if set to true [is optional]. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Serves as a hash function for a particular type, suitable + for use in hashing algorithms and data structures like a hash table. + + + A hash code for the current . + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + if the specified is equal to the + current ; otherwise, . + + + + + Gets or sets the type of the dependency. + + The type of the dependency. + + + + Gets or sets the dependency key. + + The dependency key. + + + + Gets the type of the target. + + The type of the target. + + + + Gets or sets whether this dependency is optional. + + + true if this dependency is optional; otherwise, false. + + + + + Collection of . + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The dependencies. + + + + Initializes a new instance of the class. + + The dependencies. + + + + Adds the specified model. + + The model. + + + + Removes the specified model. + + The model. + + + + Clears this instance. + + + + + Determines whether this collection contains the the specified model. + + The model. + + true if the collection contains the specified model; otherwise, false. + + + + + Represents an reference to a Interceptor component. + + + + + Initializes a new instance of the class. + + The component key. + + + + Initializes a new instance of the class. + + Type of the service. + + + + Gets the type of the service. + + The type of the service. + + + + Gets the interceptor component key. + + The component key. + + + + Gets the type of the reference. + + The type of the reference. + + + + Collection of + + + + + Adds the specified interceptor. + + The interceptor. + + + + Adds the the specified interceptor as the first. + + The interceptor. + + + + Adds the the specified interceptor as the last. + + The interceptor. + + + + Inserts the specified interceptor at the specified index. + + The index. + The interceptor. + + + + When implemented by a class, 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 . + + 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 . + + + + Returns an enumerator that can iterate through a collection. + + + An + that can be used to iterate through the collection. + + + + + Gets a value indicating whether this instance has interceptors. + + + true if this instance has interceptors; otherwise, false. + + + + + Gets the number of + elements contained in the . + + + + + + Gets an object that + can be used to synchronize access to the . + + + + + + Gets a value + indicating whether access to the is synchronized + (thread-safe). + + + + + + Represents a collection of ordered lifecycle steps. + + + + + Initializes a new instance of the class. + + + + + Returns all steps for the commission phase + + + + + + Returns all steps for the decommission phase + + + + + + Adds a step to the commission or decomission phases. + + + + + + + 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 . + + 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 . + + + + Returns an enumerator that can iterate through a collection. + + + An + that can be used to iterate through the collection. + + + + + Gets a value indicating whether this instance has commission steps. + + + true if this instance has commission steps; otherwise, false. + + + + + Gets a value indicating whether this instance has decommission steps. + + + true if this instance has decommission steps; otherwise, false. + + + + + Gets the number of + elements contained in the . + + + + + + Gets an object that + can be used to synchronize access to the . + + + + + + Gets a value + indicating whether access to the is synchronized + (thread-safe). + + + + + + Represents meta information associated with a method + (not yet defined) + + + + + Initializes a new instance of the class. + + The config node. + + + + Gets the config node. + + The config node. + + + + Collection of + + + + + Adds the specified model. + + The model. + + + + Gets the method info2 model. + + The method info2 model. + + + + Represents a parameter. Usually the parameter + comes from the external world, ie, an external configuration. + + + + + Initializes a new instance of the class. + + The name. + The value. + + + + Initializes a new instance of the class. + + The name. + The value. + + + + Gets the name. + + The name. + + + + Gets the value. + + The value. + + + + Gets the config value. + + The config value. + + + + Collection of + + + + + Initializes a new instance of the class. + + + + + Adds the specified name. + + The name. + The value. + + + + Adds the specified name. + + The name. + The config node. + + + + Determines whether this collection contains the specified key. + + The key. + + true if yes; otherwise, false. + + + + + Adds the specified key. + + + Not implemented + + The key. + The value. + + + + Clears this instance. + + + Not implemented + + + + + Removes the specified key. + + The key. + + Not implemented + + + + + Copy the content to the specified array + + target array + target index + + Not implemented + + + + + Returns an enumerator that can iterate through a collection. + + + An + that can be used to iterate through the collection. + + + + + Gets the keys. + + The keys. + + Not implemented + + + + + Gets the values. + + The values. + + Not implemented + + + + + Gets a value indicating whether this instance is read only. + + + true if this instance is read only; otherwise, false. + + + + + Gets a value indicating whether this instance is fixed size. + + + true if this instance is fixed size; otherwise, false. + + + + + Gets the with the specified key. + + + + + + Gets the count. + + The count. + + + + Gets the sync root. + + The sync root. + + + + Gets a value indicating whether this instance is synchronized. + + + true if this instance is synchronized; otherwise, false. + + + + + Represents a property and the respective dependency. + + + + + Initializes a new instance of the class. + + The property info. + The dependency. + + + + Gets the property. + + The property. + + + + Gets the dependency. + + The dependency. + + + + Collection of + + + + + Adds the specified property. + + The property. + + + + Clears this instance. + + + + + Finds a PropertySet the by PropertyInfo. + + The info. + + + + + Represents a 'streamable' resource. Can + be a file, a resource in an assembly. + + + + + Returns a reader for the stream + + + It's up to the caller to dispose the reader. + + + + + + Returns a reader for the stream + + + It's up to the caller to dispose the reader. + + + + + + + Returns an instance of + created according to the relativePath + using itself as the root. + + + + + + + + + + Only valid for resources that + can be obtained through relative paths + + + + + + + + + + Do not allow closing and disposal of the + underlying . + + + + + + + + + + Depicts the contract for resource factories. + + + + + Used to check whether the resource factory + is able to deal with the given resource + identifier. + + + Implementors should return true + only if the given identificator is supported + by the resource factory + + + + + + + Creates an instance + for the given resource identifier + + + + + + + Creates an instance + for the given resource identifier + + + + + + + + + + + + + + + + + + Adapts a static string content as an + + + + + Enable access to files on network shares + + + + + 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 + + + + + Increments IServiceProvider with a generic service resolution operation. + + + + + 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 + + + + + + General purpose class to represent a standard pair of values. + + Type of the first value + Type of the second value + + + + Constructs a pair with its values + + + + + + diff --git a/Lib/Castle.DynamicProxy2.dll b/Lib/Castle.DynamicProxy2.dll new file mode 100644 index 000000000..44619086e Binary files /dev/null and b/Lib/Castle.DynamicProxy2.dll differ diff --git a/Lib/Castle.DynamicProxy2.xml b/Lib/Castle.DynamicProxy2.xml new file mode 100644 index 000000000..dbaa6bc5a --- /dev/null +++ b/Lib/Castle.DynamicProxy2.xml @@ -0,0 +1,635 @@ + + + + Castle.DynamicProxy2 + + + + + Wraps a reference that is passed + ByRef and provides indirect load/store support. + + + + + Summary description for NewArrayExpression. + + + + + + + + + + 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). + + + + + 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. + + + + + 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). + + + + + Provides appropriate Ldc.X opcode for the type of primitive value to be loaded. + + + + + Provides appropriate Ldind.X opcode for + the type of primitive value to be loaded indirectly. + + + + + Inspect the base method for generic definitions + and set the return type and the parameters + accordingly + + + + + Emits a load opcode of the appropriate kind for a constant string or + primitive value. + + + + + + + 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. + + + + + 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. + + + + + + + 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. + + + + + + + Summary description for PropertiesCollection. + + + + + Provides appropriate Stind.X opcode + for the type of primitive value to be stored indirectly. + + + + + Base class that exposes the common functionalities + to proxy generation. + + + TODO: + - Use the interceptor selector if provided + - Add tests and fixes for 'leaking this' problem + - Mixin support + + + + + Used by dinamically implement + + + + + + 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 + + + + + + If callbackMethod is null the InvokeOnTarget implementation + is just the code to throw an exception + + + + + + + + + + + + If callbackMethod is null the InvokeOnTarget implementation + is just the code to throw an exception + + + + + + + + If true the invocation will implement the IChangeProxyTarget interface + + + + + Generates the constructor for the nested class that extends + + + + + + + + + + Improvement: this cache should be static. We should generate a + type constructor instead + + + + + Performs some basic screening and invokes the + to select methods. + + + + + + + + Checks if the method is public or protected. + + + + + + + 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. + + + + + Checks if the method has the same signature as a method that was marked as + one that should generate a new vtable slot. + + + + + Initializes a new instance of the class. + + Type of the target. + The interfaces. + The options. + + + + + + + + + Initializes a new instance of the class. + + The emitter. + The add method. + The remove method. + The attributes. + + + + + + + + + Finds the type of the method on target. + + The method on interface. + Type of the proxy target. + + + + + Checks whether the given types are the same. This is + more complicated than it looks. + + + + + + + + This is used by the ProxyObjectReference class durin de-serialiation, to know + which generator it should use + + + + + 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. + + + + + Handles the deserialization of proxies. + + + + + Usefull for test cases + + + + + Used during the target type inspection process. + Implementors have a chance to interfere in the + proxy generation process + + + + + Invoked by the generation process to know if + the specified member should be proxied + + + + + + + + Invoked by the generation process to notify that a + member wasn't marked as virtual. + + + + + + + Invoked by the generation process to notify + that the whole process is completed. + + + + + Abstracts the implementation of proxy constructions + + + + + Implementors should return a proxy for the specified type. + + The proxy base class. + The proxy generation options. + The generated proxy type. + + + + Implementors should return a proxy for the specified + type and interfaces. The interfaces must be only "mark" interfaces + + + + + + + + + Implementors should return a proxy for the specified + interface that 'proceeds' executions to the + specified target. + + + + + + + + + + Implementors should return a proxy for the specified + interface that delegate all executions to the + specified interceptor(s). + + + + + + + + + Implementors should return a proxy for the specified + interface that delegate all executions to the + specified interceptor(s) and uses an instance of the interface + as their targets, rather than a class. All IInvocation's + should then implement IChangeProxyTarget. + + + + + + + + Gets the module scope used by this builder for generating code. + + The module scope used by this builder. + + + + Determines whether this assembly has internals visisble to dynamic proxy. + + The asm. + + + + Determines whether the specified method is internal. + + The method. + + true if the specified method is internal; otherwise, false. + + + + + Summary description for ModuleScope. + + + + + The default file name used when the assembly is saved using . + + + + + The default assembly (simple) name used for the assemblies generated by a instance. + + + + + Initializes a new instance of the class; assemblies created by this instance will not be saved. + + + + + 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. + + + + 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. + 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 . + + + + 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 + + + + 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. + + + + Gets the key pair used to sign the strong-named assembly generated by this . + + + + + + 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. + + + + 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. + + + + 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. + + + + 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 or no assembly has been + generated. + + + + 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. + + + + + Users of this should use this lock when accessing the cache. + + + + + 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. + + + + 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. + + + + 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). + + + + 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. + + + + 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. + + + + 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). + + + + ProxyBuilder that persists the generated type. + + + The saved assembly contains just the last generated type. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The hook. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The builder. + + + + Initializes a new instance of the class. + + + + + Creates the class proxy. + + Type of the target. + The interfaces. + The interceptors. + + + + + Creates the class proxy. + + Type of the target. + The interceptors. + The constructor args. + + + + + + + + + + + + + + Creates the class proxy. + + Type of the target. + The interfaces. + The options. + The constructor args. + The interceptors. + + + + + Gets the proxy builder instance. + + The proxy builder. + + + + + + + + + + + + + + + For interface proxies, this will point to the + on the target class + + + + diff --git a/Moq.shfb b/Moq.shfb index a18bc6650..26632b1d7 100644 --- a/Moq.shfb +++ b/Moq.shfb @@ -4,13 +4,30 @@ - Root namespace of Moq (pronounced "Mock-you"), the only mocking library for .NET developed from scratch to take full advantage of .NET 3.5 (i.e. Linq expression trees) and C# 3.0 features (i.e. lambda expressions) that make it the most productive, simple and refactoring-friendly mocking library available. + + + + + + + + + + + + + + Root namespace of MoQ (pronounced "Mock-you"), the only mocking library for .NET developed from scratch to take full advantage of .NET 3.5 (i.e. Linq expression trees) and C# 3.0 features (i.e. lambda expressions) that make it the most productive, simple and refactoring-friendly mocking library available. <p> See the <a href="http://code.google.com/p/moq/wiki/QuickStart">online quickstarts</a> for more examples than those available in this code documentation. </p> -The Mock&lt;TInterface&gt; class is the core of the library, so it's a good place to start. +The Mock&lt;TTarget&gt; class is the core of the library, so it's a good place to start. + + + + Moq (pronounced "Mock-you") is the only mocking library for .NET developed from scratch to take full advantage of .NET 3.5 (i.e. Linq expression trees) and C# 3.0 features (i.e. lambda expressions) that make it the most productive, simple and refactoring-friendly mocking library available. Summary, Parameter, AutoDocumentCtors, Namespace InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected @@ -20,22 +37,22 @@ The Mock&lt;TInterface&gt; class is the core of the library, so it's a g True - True + False Help1xAndWebsite True False 3.5 True False - False + True False - Moq - Moq + MoQ + MoQ en-US - + moq@clariusconsulting.net Local @@ -44,7 +61,7 @@ The Mock&lt;TInterface&gt; class is the core of the library, so it's a g vs2005 HashedMemberName CSharp - False + True AboveNamespaces diff --git a/Moq.snk b/Moq.snk new file mode 100644 index 000000000..887afb5a5 Binary files /dev/null and b/Moq.snk differ diff --git a/Source/IProxyCall.cs b/Source/IProxyCall.cs index 7634bfe79..a900d5ba4 100644 --- a/Source/IProxyCall.cs +++ b/Source/IProxyCall.cs @@ -1,10 +1,11 @@ using System.Runtime.Remoting.Messaging; +using Castle.Core.Interceptor; namespace Moq { internal interface IProxyCall { - bool Matches(IMethodCallMessage call); - IMethodReturnMessage Execute(IMethodCallMessage call); + bool Matches(IInvocation call); + void Execute(IInvocation call); } } diff --git a/Source/Interceptor.cs b/Source/Interceptor.cs new file mode 100644 index 000000000..8ac660739 --- /dev/null +++ b/Source/Interceptor.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Castle.Core.Interceptor; + +namespace Moq +{ + class Interceptor : MarshalByRefObject, IInterceptor + { + List calls = new List(); + List objectMethods = new List(new MethodInfo[] { + Reflector.GetMethod(x => x.GetType()), + Reflector.GetMethod(x => x.Equals(null)), + Reflector.GetMethod(x => x.GetHashCode()), + Reflector.GetMethod(x => x.ToString())}); + + public void AddCall(IProxyCall call) + { + calls.Add(call); + } + + public void Intercept(IInvocation invocation) + { + var call = calls.Find(x => x.Matches(invocation)); + if (call != null) + { + call.Execute(invocation); + } + else if (invocation.Method.DeclaringType == typeof(object)) + { + invocation.Proceed(); + } + else if (invocation.TargetType.IsClass && + !invocation.Method.IsAbstract) + { + // For mocked classes, if the target method was not abstract, + // invoke directly. + invocation.Proceed(); + } + else if (invocation.Method != null && invocation.Method.ReturnType != null && + invocation.Method.ReturnType != typeof(void)) + { + // Return default value. + if (invocation.Method.ReturnType.IsValueType) + invocation.ReturnValue = 0; + else + invocation.ReturnValue = null; + //List values = new List(invocation.Arguments.Length); + //// Build arguments + //invocation.Arguments.ForEach( + // x => values.Add(x == null ? "null" : (x is string ? "\"" + (string)x + "\"" : x.ToString()))); + + //throw new InvalidOperationException(String.Format( + // Properties.Resources.UndeterminedReturnValue, + // invocation.Method.DeclaringType.Name, + // invocation.Method.Name, + // String.Join(", ", values.ToArray()))); + } + } + } +} diff --git a/Source/MethodCall.cs b/Source/MethodCall.cs index 65532cc8b..52b012925 100644 --- a/Source/MethodCall.cs +++ b/Source/MethodCall.cs @@ -3,6 +3,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Runtime.Remoting.Messaging; +using Castle.Core.Interceptor; namespace Moq { @@ -31,14 +32,14 @@ public ICall Callback(Action callback) return this; } - public bool Matches(IMethodCallMessage call) + public bool Matches(IInvocation call) { - if (call.MethodBase == method && - argumentMatchers.Length == call.ArgCount) + if (call.Method == method && + argumentMatchers.Length == call.Arguments.Length) { for (int i = 0; i < argumentMatchers.Length; i++) { - if (!argumentMatchers[i].Matches(call.Args[i])) + if (!argumentMatchers[i].Matches(call.Arguments[i])) return false; } @@ -48,20 +49,13 @@ public bool Matches(IMethodCallMessage call) return false; } - public IMethodReturnMessage Execute(IMethodCallMessage call) + public virtual void Execute(IInvocation call) { if (callback != null) callback(); if (exception != null) - return new ReturnMessage(exception, call); - - return GetReturnMessage(call); - } - - protected virtual IMethodReturnMessage GetReturnMessage(IMethodCallMessage call) - { - return new ReturnMessage(null, null, 0, null, call); + throw exception; } } } diff --git a/Source/MethodCallReturn.cs b/Source/MethodCallReturn.cs index b744f07cb..5f7d82c3a 100644 --- a/Source/MethodCallReturn.cs +++ b/Source/MethodCallReturn.cs @@ -2,6 +2,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Runtime.Remoting.Messaging; +using Castle.Core.Interceptor; namespace Moq { @@ -31,12 +32,14 @@ public void Returns(TResult value) return this; } - protected override IMethodReturnMessage GetReturnMessage(IMethodCallMessage call) + public override void Execute(IInvocation call) { + base.Execute(call); + if (valueFunc != null) - return new ReturnMessage(valueFunc(), null, 0, null, call); + call.ReturnValue = valueFunc(); else - return new ReturnMessage(value, null, 0, null, call); + call.ReturnValue = value; } } } diff --git a/Source/Mock.cs b/Source/Mock.cs index 21ef8514b..623025416 100644 --- a/Source/Mock.cs +++ b/Source/Mock.cs @@ -2,13 +2,15 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using Castle.DynamicProxy; +using Castle.Core.Interceptor; namespace Moq { /// - /// Provides a mock implementation of . + /// Provides a mock implementation of . /// - /// Type of the interface to mock. + /// Type of the interface to mock. /// /// The following example shows setting expectations with specific values /// for method invocations: @@ -47,21 +49,60 @@ namespace Moq /// Assert.IsFalse(order.IsFilled); /// /// - public class Mock where TInterface : class + public class Mock where T : class { - MockProxy proxy = new MockProxy(); + static readonly ProxyGenerator generator = new ProxyGenerator(); + Interceptor interceptor = new Interceptor(); + T instance; + RemotingProxy remotingProxy; + + /// + /// Initializes an instance of the mock. + /// + public Mock() + { + if (typeof(MarshalByRefObject).IsAssignableFrom(typeof(T))) + { + remotingProxy = new RemotingProxy(typeof(T), x => interceptor.Intercept(x)); + instance = (T)remotingProxy.GetTransparentProxy(); + } + else if (typeof(T).IsInterface) + { + instance = generator.CreateInterfaceProxyWithoutTarget(interceptor); + } + else + { + try + { + instance = generator.CreateClassProxy(interceptor); + } + catch (TypeLoadException tle) + { + throw new ArgumentException(Properties.Resources.InvalidMockClass, tle); + } + } + } /// /// Exposes the mocked object instance. /// - public TInterface Object + public T Object { get { - return proxy.TransparentProxy; + return instance; } } + /// + /// Called by the when a + /// is the target type. + /// + internal void Intercept(IInvocation invocation) + { + interceptor.Intercept(invocation); + } + /// /// Sets an expectation on the mocked interface for a call to /// to a void-returning method. @@ -73,7 +114,7 @@ public TInterface Object /// mock.Expect(x => x.Execute("ping")); /// /// - public ICall Expect(Expression> expression) + public ICall Expect(Expression> expression) { Guard.ArgumentNotNull(expression, "expression"); @@ -81,7 +122,7 @@ public ICall Expect(Expression> expression) var call = new MethodCallReturn( methodCall.Method, methodCall.Arguments.ToArray()); - proxy.AddCall(call); + interceptor.AddCall(call); return call; } @@ -95,7 +136,7 @@ public ICall Expect(Expression> expression) /// mock.Expect(x => x.HasInventory("Talisker", 50)).Returns(true); /// /// - public ICall Expect(Expression> expression) + public ICall Expect(Expression> expression) { Guard.ArgumentNotNull(expression, "expression"); @@ -108,7 +149,7 @@ public ICall Expect(Expression> expr { var call = new MethodCallReturn( methodCall.Method, methodCall.Arguments.ToArray()); - proxy.AddCall(call); + interceptor.AddCall(call); result = call; } else if (propField != null) @@ -130,7 +171,7 @@ public ICall Expect(Expression> expr } var call = new MethodCallReturn(prop.GetGetMethod()); - proxy.AddCall(call); + interceptor.AddCall(call); result = call; } else if (field != null) diff --git a/Source/MockProxy.cs b/Source/MockProxy.cs deleted file mode 100644 index 7e823531d..000000000 --- a/Source/MockProxy.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.Remoting.Messaging; -using System.Runtime.Remoting.Proxies; - -namespace Moq -{ - internal class MockProxy : RealProxy - where TInterface : class - { - List calls = new List(); - TInterface transparentProxy = null; - static MethodInfo ObjectGetTypeMethod = Reflector.GetMethod(x => x.GetType()); - static MethodInfo ObjectEqualsMethod = Reflector.GetMethod(x => x.Equals(null)); - static MethodInfo ObjectGetHashCodeMethod = Reflector.GetMethod(x => x.GetHashCode()); - static MethodInfo ObjectToStringMethod = Reflector.GetMethod(x => x.ToString()); - - public MockProxy() - : base(typeof(TInterface)) - { - } - - public void AddCall(IProxyCall call) - { - calls.Add(call); - } - - public TInterface TransparentProxy - { - get - { - if (transparentProxy == null) - transparentProxy = (TInterface)this.GetTransparentProxy(); - - return transparentProxy; - } - } - - public override IMessage Invoke(IMessage msg) - { - IMethodCallMessage methodCall = msg as IMethodCallMessage; - if (methodCall != null) - { - var call = calls.Find(x => x.Matches(methodCall)); - if (call != null) - { - return call.Execute(methodCall); - } - - if (methodCall.MethodBase.DeclaringType == typeof(object)) - { - return ExecuteObjectMethod(methodCall); - } - - MethodInfo method = methodCall.MethodBase as MethodInfo; - if (method != null && method.ReturnType != null && - method.ReturnType != typeof(void)) - { - List values = new List(methodCall.ArgCount); - // Build arguments - methodCall.Args.ForEach( - x => values.Add(x == null ? "null" : (x is string ? "\"" + (string)x + "\"" : x.ToString()))); - - throw new InvalidOperationException(String.Format( - Properties.Resources.UndeterminedReturnValue, - methodCall.MethodBase.DeclaringType.Name, - methodCall.MethodName, - String.Join(", ", values.ToArray()))); - } - } - - return new ReturnMessage(null, null, 0, null, methodCall); - } - - private IMessage ExecuteObjectMethod(IMethodCallMessage methodCall) - { - if (methodCall.MethodBase == ObjectGetTypeMethod) - { - Type type = typeof(TInterface); - return new ReturnMessage(type, null, 0, null, methodCall); - } - else if (methodCall.MethodBase == ObjectEqualsMethod) - { - bool equals = object.ReferenceEquals(transparentProxy, methodCall.Args[0]); - return new ReturnMessage(equals, null, 0, null, methodCall); - } - else if (methodCall.MethodBase == ObjectGetHashCodeMethod) - { - int hashCode = GetHashCode(); - return new ReturnMessage(hashCode, null, 0, null, methodCall); - } - else if (methodCall.MethodBase == ObjectToStringMethod) - { - string toString = ToString(); - return new ReturnMessage(toString, null, 0, null, methodCall); - } - else - { - return new ReturnMessage(null, null, 0, null, methodCall); - } - } - } -} diff --git a/Source/Moq.csproj b/Source/Moq.csproj index 6498b7b44..532920c4f 100644 --- a/Source/Moq.csproj +++ b/Source/Moq.csproj @@ -12,6 +12,8 @@ Moq v3.5 512 + true + ..\Moq.snk true @@ -35,18 +37,18 @@ true - - - 3.5 + + False + ..\Lib\Castle.Core.dll - - 3.5 + + False + ..\Lib\Castle.DynamicProxy2.dll - + + 3.5 - - @@ -55,6 +57,7 @@ + @@ -68,7 +71,7 @@ - + True @@ -85,6 +88,11 @@ Designer + + + Moq.snk + + + + + + + + + \ No newline at end of file diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs index a6619bafc..a6e9b463f 100644 --- a/Source/Properties/AssemblyInfo.cs +++ b/Source/Properties/AssemblyInfo.cs @@ -7,7 +7,7 @@ [assembly: AssemblyProduct("Moq")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.5.*")] -[assembly: AssemblyFileVersion("0.5.0.0")] +[assembly: AssemblyVersion("0.7.*")] +[assembly: AssemblyFileVersion("0.7.0.0")] -//[assembly: InternalsVisibleTo("Moq.Tests")] \ No newline at end of file +[assembly: InternalsVisibleTo("Moq.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001009f7a95086500f8f66d892174803850fed9c22225c2ccfff21f39c8af8abfa5415b1664efd0d8e0a6f7f2513b1c11659bd84723dc7900c3d481b833a73a2bcf1ed94c16c4be64d54352c86956c89930444e9ac15124d3693e3f029818e8410f167399d6b995324b635e95353ba97bfab856abbaeb9b40c9b160070c6325e22ddc")] \ No newline at end of file diff --git a/Source/Properties/Resources.Designer.cs b/Source/Properties/Resources.Designer.cs index 77684c6ad..0387011ff 100644 --- a/Source/Properties/Resources.Designer.cs +++ b/Source/Properties/Resources.Designer.cs @@ -69,6 +69,15 @@ internal static string FieldsNotSupported { } } + /// + /// Looks up a localized string similar to Type to mock be an interface or an abstract or non-sealed class. . + /// + internal static string InvalidMockClass { + get { + return ResourceManager.GetString("InvalidMockClass", resourceCulture); + } + } + /// /// Looks up a localized string similar to Property {0}.{1} is write-only.. /// diff --git a/Source/Properties/Resources.resx b/Source/Properties/Resources.resx index bdf2810be..17133109f 100644 --- a/Source/Properties/Resources.resx +++ b/Source/Properties/Resources.resx @@ -120,6 +120,9 @@ Field calls are not supported. Use interfaces and properties instead. + + Type to mock be an interface or an abstract or non-sealed class. + Property {0}.{1} is write-only. diff --git a/Source/RemotingProxy.cs b/Source/RemotingProxy.cs new file mode 100644 index 000000000..b1270328a --- /dev/null +++ b/Source/RemotingProxy.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Remoting.Messaging; +using System.Runtime.Remoting.Proxies; +using Castle.Core.Interceptor; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Activation; +using System.Security.Permissions; + +namespace Moq +{ + internal class RemotingProxy : RealProxy + { + Action interceptor; + Type targetType; + + public RemotingProxy(Type targetType, Action interceptor) + : base(targetType) + { + this.targetType = targetType; + this.interceptor = interceptor; + } + + public override IMessage Invoke(IMessage msg) + { + var methodCall = msg as IMethodCallMessage; + if (methodCall != null) + { + var invocation = new RemotingInvocation( + targetType, + methodCall, + CallUnderlyingObject); + + interceptor(invocation); + + return ToMessage(invocation, methodCall); + } + + return null; + } + + private IMethodReturnMessage CallUnderlyingObject(IMethodCallMessage methodCall) + { + var realObject = GetUnwrappedServer(); + if (realObject == null) + { + var returnMessage = InitializeServerObject(null); + if (returnMessage.Exception == null) + { + realObject = GetUnwrappedServer(); + SetStubData(this, realObject); + } + else + { + throw returnMessage.Exception; + } + } + + return RemotingServices.ExecuteMessage(realObject, methodCall); + } + + private IMessage ToMessage(IInvocation invocation, IMethodCallMessage original) + { + if (invocation.Method.ReturnType != null && + invocation.Method.ReturnType != typeof(void)) + { + return new ReturnMessage(invocation.ReturnValue, null, 0, original.LogicalCallContext, original); + } + else + { + return new ReturnMessage(null, null, 0, original.LogicalCallContext, original); + } + } + + class RemotingInvocation : IInvocation + { + Type targetType; + IMethodCallMessage call; + Func realCall; + + public RemotingInvocation(Type targetType, IMethodCallMessage call, + Func realCall) + { + this.targetType = targetType; + this.call = call; + this.realCall = realCall; + } + + public object[] Arguments + { + get { return call.Args; } + } + + public MethodInfo Method + { + get { return call.MethodBase as MethodInfo; } + } + + public object ReturnValue { get; set; } + + public Type TargetType + { + get { return targetType; } + } + + public void Proceed() + { + ReturnValue = realCall(call).ReturnValue; + } + + public Type[] GenericArguments + { + get { throw new NotImplementedException(); } + } + + public object GetArgumentValue(int index) + { + throw new NotImplementedException(); + } + + public MethodInfo GetConcreteMethod() + { + throw new NotImplementedException(); + } + + public MethodInfo GetConcreteMethodInvocationTarget() + { + throw new NotImplementedException(); + } + + public object InvocationTarget + { + get { throw new NotImplementedException(); } + } + + public MethodInfo MethodInvocationTarget + { + get { throw new NotImplementedException(); } + } + + public object Proxy + { + get { throw new NotImplementedException(); } + } + + public void SetArgumentValue(int index, object value) + { + throw new NotImplementedException(); + } + } + + + + + + + + private IMessage ExecuteObjectMethod(IMethodCallMessage methodCall) + { + throw new NotImplementedException(); + //if (methodCall.MethodBase == ObjectGetTypeMethod) + //{ + // Type type = typeof(TTarget); + // return new ReturnMessage(type, null, 0, null, methodCall); + //} + //else if (methodCall.MethodBase == ObjectEqualsMethod) + //{ + // bool equals = object.ReferenceEquals(transparentProxy, methodCall.Args[0]); + // return new ReturnMessage(equals, null, 0, null, methodCall); + //} + //else if (methodCall.MethodBase == ObjectGetHashCodeMethod) + //{ + // int hashCode = GetHashCode(); + // return new ReturnMessage(hashCode, null, 0, null, methodCall); + //} + //else if (methodCall.MethodBase == ObjectToStringMethod) + //{ + // string toString = ToString(); + // return new ReturnMessage(toString, null, 0, null, methodCall); + //} + //else + //{ + // return new ReturnMessage(null, null, 0, null, methodCall); + //} + } + } +} diff --git a/Tools/ILMerge.exe b/Tools/ILMerge.exe new file mode 100644 index 000000000..51cbe547e Binary files /dev/null and b/Tools/ILMerge.exe differ diff --git a/UnitTests/Demo.cs b/UnitTests/Demo.cs index 814690bcb..f9954ed79 100644 --- a/UnitTests/Demo.cs +++ b/UnitTests/Demo.cs @@ -45,13 +45,13 @@ public void FillingDoesNotRemoveIfNotEnoughInStock() Assert.IsFalse(order.IsFilled); } - interface IWarehouse + public interface IWarehouse { bool HasInventory(string productName, int quantity); void Remove(string productName, int quantity); } - class Order + public class Order { public string ProductName { get; private set; } public int Quantity { get; private set; } diff --git a/UnitTests/MatcherAttributeFixture.cs b/UnitTests/MatcherAttributeFixture.cs index 169eb5652..129c7d133 100644 --- a/UnitTests/MatcherAttributeFixture.cs +++ b/UnitTests/MatcherAttributeFixture.cs @@ -33,7 +33,6 @@ public void ShouldCreateMatcher() Assert.IsNotNull(matcher); } - class MockMatcher : IMatcher { #region IMatcher Members diff --git a/UnitTests/MockFixture.cs b/UnitTests/MockFixture.cs index ff0350c48..331c70339 100644 --- a/UnitTests/MockFixture.cs +++ b/UnitTests/MockFixture.cs @@ -16,7 +16,7 @@ public class MockFixture public void ShouldCreateMockAndExposeInterface() { var mock = new Mock(); - + ICloneable cloneable = mock.Object; Assert.IsNotNull(cloneable); @@ -48,7 +48,7 @@ public void ShouldExpectCallReturn() mock.Expect(x => x.Clone()).Returns(clone); - Assert.AreSame(clone, mock.Object.Clone()); + Assert.AreEqual(clone, mock.Object.Clone()); } [Test] @@ -124,7 +124,7 @@ public void ShouldExpectReturnPropertyValue() [Test] public void ShouldThrowIfExpectFieldValue() { - var mock = new Mock(); + var mock = new Mock(); mock.Expect(x => x.ValueField); } @@ -207,13 +207,18 @@ public void ShouldNotThowIfUnexpectedCallWithoutReturnValue() mock.Object.Execute(); } - [ExpectedException(typeof(InvalidOperationException))] [Test] - public void ShouldThowIfUnexpectedCallWithReturnValue() + public void ShouldNotThowIfUnexpectedCallWithReturnValue() { var mock = new Mock(); int value = mock.Object.DoArgument("foo"); + string str = mock.Object.Do2(); + AttributeTargets targets = mock.Object.GetTargets(); + + Assert.AreEqual(default(int), value); + Assert.AreEqual(default(string), str); + Assert.AreEqual(default(AttributeTargets), targets); } [ExpectedException(typeof(FormatException))] @@ -265,15 +270,14 @@ public void ShouldExpectRanges() Assert.AreEqual(2, mock.Object.DoInt(9)); } - [ExpectedException(typeof(InvalidOperationException))] [Test] - public void ShouldNotExpectOutOfRange() + public void ShouldOutOfRangeReturnsDefault() { var mock = new Mock(); mock.Expect(x => x.DoInt(It.IsInRange(1, 5, Range.Exclusive))).Returns(1); - Assert.AreEqual(1, mock.Object.DoInt(1)); + Assert.AreEqual(default(int), mock.Object.DoInt(1)); } [Test] @@ -287,7 +291,6 @@ public void ShouldExpectRangeWithVariableAndMethodInvocation() Assert.AreEqual(1, mock.Object.DoInt(1)); } - [ExpectedException(typeof(InvalidOperationException))] [Test] public void ShouldExpectRangeLazyEval() { @@ -301,10 +304,9 @@ public void ShouldExpectRangeLazyEval() from = "c"; - Assert.AreEqual(1, mock.Object.DoArgument("b")); + Assert.AreEqual(default(int), mock.Object.DoArgument("b")); } - [ExpectedException(typeof(InvalidOperationException))] [Test] public void ShouldExpectMatchRegexAndLazyEval() { @@ -321,7 +323,8 @@ public void ShouldExpectMatchRegexAndLazyEval() reg = "[c-d]+"; - Assert.AreEqual(1, mock.Object.DoArgument("b")); + // Will not match neither the 1 and 2 return values we had. + Assert.AreEqual(default(int), mock.Object.DoArgument("b")); } [Test] @@ -338,7 +341,7 @@ public void ShouldReturnService() public void ShouldCallFirstExpectThatMatches() { var mock = new Mock(); - mock.Expect(x => x.Execute("ping")).Returns("I'm alive!"); + mock.Expect(x => x.Execute("ping")).Returns("I'm alive!"); mock.Expect(x => x.Execute(It.IsAny())).Throws(new ArgumentException()); Assert.AreEqual("I'm alive!", mock.Object.Execute("ping")); @@ -397,28 +400,110 @@ public void ShouldToString() Assert.IsFalse(string.IsNullOrEmpty(mock.Object.ToString())); } + [Ignore("Castle.DynamicProxy2 doesn't seem to call interceptors for ToString, GetHashCode")] [Test] public void ShouldOverrideObjectMethods() { var mock = new Mock(); + mock.Expect(x => x.GetHashCode()).Returns(1); mock.Expect(x => x.ToString()).Returns("foo"); Assert.AreEqual("foo", mock.Object.ToString()); + Assert.AreEqual(1, mock.Object.GetHashCode()); + } + + [Test] + public void ShouldMockAbstractClass() + { + var mock = new Mock(); + mock.Expect(x => x.Check("foo")).Returns(false); + + Assert.IsFalse(mock.Object.Check("foo")); + Assert.IsTrue(mock.Object.Check("bar")); + } + + [Ignore("Not implemented yet")] + [ExpectedException(typeof(ArgumentException))] + [Test] + public void ShouldThrowIfExpectOnNonVirtual() + { + var mock = new Mock(); + mock.Expect(x => x.True()).Returns(false); + + Assert.IsFalse(mock.Object.True()); + } + + [Test] + public void ShouldOverrideNonVirtualForMBRO() + { + var mock = new Mock(); + mock.Expect(x => x.True()).Returns(false); + + Assert.IsFalse(mock.Object.True()); + } + + [Test] + public void ShouldCallUnderlyingMBRO() + { + var mock = new Mock(); + + Assert.IsTrue(mock.Object.True()); + } + + [Test] + public void ShouldCallUnderlyingClassEquals() + { + var mock = new Mock(); + var mock2 = new Mock(); + + mock.Object.Name = "Foo"; + mock2.Object.Name = "Foo"; + + Assert.IsTrue(mock.Object.Equals(mock2.Object)); + } + + [ExpectedException(typeof(ArgumentException))] + [Test] + public void ShouldThrowIfSealedClass() + { + var mock = new Mock(); } + // ShouldInterceptPropertySetter + + public sealed class FooSealed { } class FooService : IFooService { } interface IFooService { } - // ShouldAllowDynamicResultThroughFunc - private int GetToRange() { return 5; } - public class Foo : MarshalByRefObject + public class FooOverrideEquals + { + public string Name { get; set; } + + public override bool Equals(object obj) + { + return (obj is FooOverrideEquals) && + ((FooOverrideEquals)obj).Name == this.Name; + } + + public override int GetHashCode() + { + return Name.GetHashCode(); + } + } + + public class FooMBRO : MarshalByRefObject { public int ValueField; + + public bool True() + { + return true; + } } public interface IFoo @@ -430,6 +515,7 @@ public interface IFoo int DoArgument(string arg); int Duplicate(int value); + AttributeTargets GetTargets(); void Execute(); string Execute(string command); @@ -439,5 +525,20 @@ public interface IFoo int WriteOnlyValue { set; } } + + public abstract class FooBase + { + public abstract void Do(int value); + + public virtual bool Check(string value) + { + return true; + } + + public bool True() + { + return true; + } + } } } diff --git a/UnitTests/Moq.Tests.csproj b/UnitTests/Moq.Tests.csproj index 91101570a..350d31832 100644 --- a/UnitTests/Moq.Tests.csproj +++ b/UnitTests/Moq.Tests.csproj @@ -12,6 +12,8 @@ Moq.Tests v3.5 512 + true + ..\Moq.snk true @@ -49,6 +51,7 @@ + @@ -58,6 +61,11 @@ Moq + + + Moq.snk + +