http://www.codinghorror.com/blog/2007/03/the-works-on-my-machine-certification-program.html
nuff said 😉
Coffee | Coding | Computers | Church | What does it all mean?
Users of some other source control software are used to the fact that, any merge operation requires a workspace and if that workspace is on your local machine then you need to make sure it's up-to-date with the branch it is a workspace for before merging into that branch.
TFS is less up front about this, but it does still use your local workspace as a workspace for merge. Therefore:
Before doing a merge with TFS, get latest of the target branch. Then start your merge.
For the paranoid: get specific version -- Latest Version; and tick both 'overwrite' options.
Boy, was this painful. But there's not much too it when it works. There are several bits of config, 3 classes and some gotchas involved, as follows.
<system.serviceModel> <extensions> <behaviorExtensions> <!-- Gotcha: this element looks so easy but is a pain in the backside. The type element has to *exactly* match the undocumented-and-fussier-than-anywhere-else-in-config required format If it has to change, the best way to do it is to delete the line and then use MS Service Configuration Tool to lookup the assembly and classname See e.g. http://stackoverflow.com/questions/1163996/adding-a-custom-wcf-behavior-extension-causes-a-configurationerrorsexception --> <add name="EnterpriseLibraryClientMessageBodyLogging" type="MyNamespace.MyAppName.Implementation.LoggingServiceClientDecorators.EnterpriseLibraryMessageBodyLoggingClientBehaviorExtension, MyNamespace.MyAppName.Implementation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions> <behaviors> <endpointBehaviors> <behavior name="LogAllMessageBodies"> <EnterpriseLibraryClientMessageBodyLogging /> </behavior> </endpointBehaviors> </behaviors> <client> <!-- Add atrribute behaviorConfiguration="LogAllMessageBodies" to the endpoint element to enable WCF message in-and-out logging e.g.: --> <endpoint address="http://10.1.2.3/CalledServiceName/CalledServiceMethod.asmx" binding="basicHttpBinding" bindingConfiguration="UnsecuredBindingConfiguration" contract="CalledServiceMethod.CalledServiceMethodSoap" behaviorConfiguration="LogAllMessageBodies" name="CalledServiceMethodSoap"/> ... rest of your client section ..... </client ... rest of your system.serviceModel section ... </system.serviceModel>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General"> <listeners> <add name="FullFlatFileTraceListener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging" rollSizeKB="5000" rollFileExistsBehavior="Overwrite" timeStampPattern="yyyy-MM-dd" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging" fileName="FullLog.log" formatter="FullTextFormatter" /> </listeners> <formatters> <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging" template="---------------------------------{newline}Timestamp: {timestamp}{newline}Message: {message}{newline}{newline}Extended Properties: {newline}{dictionary( {key}: {value}{newline})}" name="FullTextFormatter" /> </formatters> <categorySources/> <specialSources> <allEvents switchValue="All" name="All Events"> <listeners> <add name="FullFlatFileTraceListener"/> </listeners> </allEvents> <notProcessed switchValue="Off" name="Unprocessed Category" /> <errors switchValue="Off" name="Logging Errors & Warnings" /> </specialSources> </loggingConfiguration>
using System; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Configuration; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; using Logger=namespaceWhichDefinesYourLoggerInterfaceIfAny; namespace blah.LoggingServiceClientDecorators { public class EnterpriseLibraryMessageBodyLoggingClientBehaviorExtension : BehaviorExtensionElement { protected override object CreateBehavior() { return new EnterpriseLibraryMessageBodyLoggingClientBehavior(); } public override Type BehaviorType { get { return typeof (EnterpriseLibraryMessageBodyLoggingClientBehavior); } } } public class EnterpriseLibraryMessageBodyLoggingClientBehavior : IEndpointBehavior { public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add( new MessageBodyLoggingClientMessageInspector(new EnterpriseLibraryExceptionHandlingLogger()) ); } #region Irrelevant IEndpointBehavior Members public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint,EndpointDispatcher endpointDispatcher){} public void Validate(ServiceEndpoint endpoint){} #endregion } public class MessageBodyLoggingClientMessageInspector : IClientMessageInspector { private readonly ILogger logger; public MessageBodyLoggingClientMessageInspector(ILogger logger) { this.logger = logger; } public void AfterReceiveReply(ref Message reply, object correlationState) { logger.Info("<MessageRecord Direction=\"In\">{0}</MessageRecord>", reply.ToString()); } public object BeforeSendRequest(ref Message request, IClientChannel channel) { logger.Info("<MessageRecord Direction=\"Out\" Endpoint=\"{1}\">{0}</MessageRecord>", request.ToString(), channel.RemoteAddress.Uri); return null; } } }
Update: See Vladimir's comment below for the built in one-liner.
So there you in your code or possible your debugger and immediate window and you have a mock object and realise you want to change the setup but you didn't keep a reference to the Mock<> ...
So your first though is, no problem, you can cast your object to one of type Castle.Proxies.MyStronglyTypedProxyClass and voila you have access to the Mock property. Except that the compiler doesn't recognise Castle.Proxies.MyStronglyTypedProxyClass as real class.
So then you try reflection to get hold of the Mock property. Which nearly works, but you get a System.Reflection.AmbiguousMatchException : Ambiguous match found. because there's more than one property called Mock (one with and one without a generic parameter).
But this worked for me:
public static Mock<T> GetMockFromObject<T>(T mockedObject) where T : class { PropertyInfo[] pis = mockedObject.GetType().GetProperties() .Where( p => p.PropertyType.Name == "Mock`1" ).ToArray(); return pis.First().GetGetMethod().Invoke(mockedObject, null) as Mock<T>; }
hope that helps.