Sunday, 7 February 2010

If a class implements IDisposable then an instance of that class should be wrapped in a “using” (c# or the vb equivalent) which guarantees dispose… otherwise Dispose should always be called explicitly; if dispose is implemented the developer meant that specific cleanup logic should always execute. Usually Dispose is implemented for cleaning un-managed resources, rather than managed.

Where Close* is also implemented, then Dispose should always call Close as part of the dispose implementation and because we’re all cynics reflector is our friend – see reflected code snippets for SQL Data Reader and SQL Connection below.

Obviously with view of connection pooling, closing a connection doesn’t necessarily mean that the resource is free

Framework2.0 SqlConnection

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        this._userConnectionOptions = null;
        this._poolGroup = null;
        this.Close();
    }
    this.DisposeMe(disposing);
    base.Dispose(disposing);
}


Framework2.0, SqlDataReader

public void Dispose()
{
    this.Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        this.Close();
    }
}


BTW whilst I’m in favour of understanding the inner working of objects that you code against, it’s my opinion that better code is explicit code, so I would be in favour of explicit close() for all instances where close() should be called, even if I know – as a developer – that close() is implicit.

I believe this also guards against future changes to the framework, in later versions.



* Close would usually be implemented because it’s (conceptually) cheaper to re-open a closed connection (for example) than allocate a new one which would also appear to be the consensus.

Friday, 22 January 2010

Testing for default T - Generics

I came accross this SO post after discovering you cannot just write:


if ( T == default(T) ) {}


You actually need either
if ( object.Equals(value, default(T)) ) {}


or (according to the SO post more efficient - though I've not checked this)
if (EqualityComparer.Default.Equals(value,default(T)))  {}



UPDATE:

I was asked the question: “I assume that this is to avoid evaluating the reference (pointer) rather than the value?”

I think that would depend on the implementation of the compare method for the type being used and as the SO post suggests this isn’t the whole story… to take a step back…

The reason for this roundabout way of checking that the value (T) is empty is logically because T could be either value or reference type, so a method is needed which can be made to deal with both value and reference types.

As you suggest Object.Equals() is a compares pointers (references), so if T was a value type it would first need boxing (first needs to be turned into a reference type), you can see this in the IL (example1 below – a contrived and nonsense function!) …

Also note in the IL that “default(T)” statement means that T is boxed too – this will be because T can be either reference or value type, so the IL boxes to force the issue (actually this surprises me a bit, I was thinking the compiler would be able to work this out based on the use, but maybe that’s asking a lot?!).

So to go back to the original post (and a check in MSDN confirms this) the use of “EqualityComparer.Default.Equals(value, default(T))” – because the underlying implementation supports value and reference types [class/struct] - means that the IL generated no longer needs to first box (example2) and I believe that’s why it’s considered more efficient and that’s the jist of the comment in SO.

Note: I haven’t dug down any deeper, it could well be that if the code falls back to Object.Equals for a value type then boxing will still occur.


Examples:

        public static T Foo()
        {
            T r = default(T);
            int x=0;
            string y = "";
            bool result = object.Equals(x, default(T));
            return r;
        } 

(abridged)
IL_0012: box [mscorlib]System.Int32
IL_0017: ldloca.s CS$0$0001
IL_0019: initobj !!T
IL_001f: ldloc.s CS$0$0001
IL_0021: box !!T
IL_0026: call bool [mscorlib]System.Object::Equals(object, object)

        public static T Foo()
        {
            T r = default(T);
            int x=0;
            string y = "";
            bool b = EqualityComparer.Default.Equals(r, default(T));
            return r;
        }


(abridged)
IL_0001: ldloca.s r
IL_0003: initobj !!T
.
.
IL_0019: initobj !!T
IL_001f: ldloc.s CS$0$0001
IL_0021: callvirt instance bool class [mscorlib]System.Collections.Generic.EqualityComparer`1::Equals(!0, !0)

Thursday, 21 January 2010

WCF Basic HTTP, XML Serializer, XmlRoot and namespaces

Example service takes a simple complex type and appends additional data to the string value:

public class TestService : ITestService
    {
        public MyType MyTestMethod(MyType obj)
        {
            obj.StringValue += "Suffix";
            return obj;
        }
    }

…And the interface definition…
[ServiceContract(Namespace = "http://servicecontract"), XmlSerializerFormat()]
    public interface ITestService
    {
        [OperationContract]
        MyType MyTestMethod(MyType obj);
    }
    [Serializable, XmlType, XmlRoot(Namespace = "http://datacontract")] 
    public class MyType
    {
        [XmlAttribute]
        public string StringValue { get; set; }
    }


Notice that the type (defined in the data contract) which is passed through MyTestMethod() has a different namespace from the service.

Also note that the service is decorated with xml serialization attributes and marked explicitly to use XML Serializer rather than the default Data Contract Serializer (DCS).

When this service is consumed within a .net client application the proxy is auto-generated (svcutil.exe), but note that the proxy definition and original definition do not match exactly, there is a subtle difference:

(Abridged definition)
[System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://datacontract")]
    public partial class MyType : object, System.ComponentModel.INotifyPropertyChanged {
        
        private string stringValueField;
        
        /// 
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string StringValue {
            get {
                return this.stringValueField;
            }
            set {
                this.stringValueField = value;
            }
        }
        
    }


The missing attribute is:

[System.Xml.Serialization.XmlRootAttribute(Namespace="http://datacontract")]

This does not stop the proxy from working; you can still send and receive “MyType” through the service, it will be de-serialized at the service and the client correctly:

static void Main(string[] args)
        {
            using (TestServiceClient service = new TestServiceClient())
            {
                MyType t = new MyType();
                t.StringValue = "Prefix:";
                MyType r = service.MyTestMethod(t);
            }
        }


But, if you serialize the type you will notice that the namespace is missing from the request to the service

<mytype StringValue="Prefix:" />

And from the response, from the service

<mytype StringValue="Prefix:Suffix" />


A close look at the wsdl helps to explain why
<xs:schema elementFormDefault="qualified" targetNamespace="http://servicecontract" xmlns:tns="http://servicecontract">
    <xs:import schemaLocation="http://.../?xsd=xsd1" namespace="http://datacontract"/>
    <xs:element name="MyTestMethod">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="obj" type="q1:MyType" xmlns:q1="http://datacontract"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="MyTestMethodResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="MyTestMethodResult" type="q2:MyType" xmlns:q2="http://datacontract"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>


Both the request “obj” and response “MyTestMethodResult” elements belong to the service namespace though the type is defined correctly in the namespace I defined for the data contract.

We understand this behaviour is part of WCF by design; it’s not a bug and should not cause too many problems provided it’s understood.

***

Out of curiosity I tried adding this simple service to BTS 2006 using “add web reference” from the project context menu, but received this error:

ERROR: Failed to add a Web Reference.

I then read this post from Saravana Kumar (with comment from our Jeremy).

I removed the service namespace, rebuilt the service and re-added the service as a “web reference” successfully, I then re-added the service namespace, re-built and tried updating the web reference in my BTS 2006 project (just to see) and got a different error, again noted in Saravana’s post:-

Could Not generate BizTalk files. Index was out of range. Must be non-negative and less than the size of the colleciton. Parameter name: index

I then altered my service definition as per Jeremy’s comments, adding a service behaviour attribute, also with the service namespace:
[ServiceBehavior(Namespace = "http://servicecontract")]
    public class TestService : ITestService
    {
        public MyType MyTestMethod(MyType obj)
        {
            obj.StringValue += "Suffix";
            return obj;
        }
    }


The service Interface stays the same, the service contract attribute stays with the namespace declared.
Important note: The namespaces are the same:

[ServiceContract(Namespace = "http://servicecontract"), XmlSerializerFormat()]
    public interface ITestService
    {
        [OperationContract]
        MyType MyTestMethod(MyType obj);
    }
    [Serializable, XmlType, XmlRoot(Namespace = "http://datacontract")] 
    public class MyType
    {
        [XmlAttribute]
        public string StringValue { get; set; }
    }



This worked OK and I was able to add my web reference to my BTS 2006 project, with the service displaying the correct service namespace.

However, the WSDL differs significantly with this change…

Here’s the WSDL before the change (BizTalk 2006 threw an error when we tried to import from this), note the target namespace of the wsdl is “tempuri”, though I had thought a service namespace had been provided in the service contract (in the service interface definition):

<?xml version="1.0" encoding="utf-8"?>
<!-- without behaviour, BizTalk unhappy!-->
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:i0="http://servicecontract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:tns="http://tempuri.org/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="TestService" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <wsdl:import namespace="http://servicecontract" location="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/?wsdl=wsdl0" />
    <wsdl:types />
    <wsdl:binding name="BasicHttpBinding_ITestService" type="i0:ITestService">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="MyTestMethod">
            <soap:operation soapAction="http://servicecontract/ITestService/MyTestMethod" style="document" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="TestService">
        <wsdl:port name="BasicHttpBinding_ITestService" binding="tns:BasicHttpBinding_ITestService">
            <soap:address location="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>


…And here’s the WSDL with the addition of “service behaviour” attribute and namespace, note that the types are now defined and no import is required to a separately defined wsdl.

<?xml version="1.0" encoding="utf-8"?>
<!-- with behaviour, BizTalk is happy!-->
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:i0="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:tns="http://servicecontract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="TestService" targetNamespace="http://servicecontract" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <wsdl:import namespace="http://tempuri.org/" location="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/?wsdl=wsdl0" />
    <wsdl:types>
        <xsd:schema targetNamespace="http://servicecontract/Imports">
            <xsd:import schemaLocation="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/?xsd=xsd0" namespace="http://servicecontract" />
            <xsd:import schemaLocation="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/?xsd=xsd1" namespace="http://datacontract" />
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="ITestService_MyTestMethod_InputMessage">
        <wsdl:part name="parameters" element="tns:MyTestMethod" />
    </wsdl:message>
    <wsdl:message name="ITestService_MyTestMethod_OutputMessage">
        <wsdl:part name="parameters" element="tns:MyTestMethodResponse" />
    </wsdl:message>
    <wsdl:portType name="ITestService">
        <wsdl:operation name="MyTestMethod">
            <wsdl:input wsaw:Action="http://servicecontract/ITestService/MyTestMethod" message="tns:ITestService_MyTestMethod_InputMessage" />
            <wsdl:output wsaw:Action="http://servicecontract/ITestService/MyTestMethodResponse" message="tns:ITestService_MyTestMethod_OutputMessage" />
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:service name="TestService">
        <wsdl:port name="BasicHttpBinding_ITestService" binding="i0:BasicHttpBinding_ITestService">
            <soap:address location="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

The difference is this: In the first wsdl types tag is empty, the types are defined in imported WSDL0 and this appears to be because the service itself has two namespace, the service namespace (as defined in the service contract) and tempuri.

When the service behaviour attribute is added to the service implementation (and it shares the same namespace as defined on the contract) then the whole service now exists under a single namespace and therefore the WSDL is complete without any imports.

Clearly in this example the type generator in BTS 2006 is seeing the empty types definition and doesn’t know to resolve the imported wsdl (wsdl=0) which would yield the type definitions.

The SOAP adapter would appear to deal with the XML Root issue OK, I believe this is because from Biztalk you pass an instance of the type, and the SOAP adapter builds the SOAP envelope so you do not have to construct the message elements directly (request “obj” and response “MyTestMethodResult, see wsdl extract above).

Here is the xml for the message I sent to the service from Biztalk 2006

<mytype StringValue="somevalue" xmlns="http://datacontract" />

And here is the xml from the message once it’s passed through the service from BTS:-

< mytype StringValue="somevalueSuffix" xmlns="http://datacontract" />


Here is the schema that describes the type (MyType) this is the “Reference.xsd” file which the web message types reference in BTS, note that somehow(?) BTS knows to create the type “properly”

<?xml version="1.0"?>
<xs:schema xmlns:tns="http://datacontract" elementFormDefault="qualified" targetNamespace="http://datacontract" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="MyType" nillable="true" type="tns:MyType" />
  <xs:complexType name="MyType">
    <xs:attribute name="StringValue" type="xs:string" />
  </xs:complexType>
</xs:schema>


The "somehow" is the bit that maybe we should take more time to understand, but there is always a balance in how far to analyze!

Related: Yossi post on SO

Wednesday, 23 December 2009

Coding a class so that a dependancy can be easily injected when the class is tested

This is one example of how Dependancy Injection can be used so a dependancy can be mocked whilst the class is tested

public interface IDependancy { }

public class SomeDependancy : IDependancy {}

public class MockDependancy : IDependancy {}

public class SomeClass
{
    private IDependancy dependancy = null;

    public SomeClass()
        : this(new SomeDependancy())
    {
        //  Do some stuff
    }

    // for testing only
    private SomeClass(IDependancy dependancy)
    {
        this.dependancy = dependancy;
    }
}

public class TestSomeClass
{
    public void Test()
    {
        Type t = Assembly.Load(assemblyFullName).GetType(typeName);

        ConstructorInfo ci = t.GetConstructor(
                BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(IDependancy) }, null);

        SomeClass c = (SomeClass)ci.Invoke(new object[] { new MockDependancy() });
           
        // test

    }
}


Catching the real Exception from a method invoke (through reflection)

Sometimes when invoking a method by reflection the method being invoked might throw an exception, but the reflection framework obscures this by wrapping the thrown exception as

   TargetInvocationException 

This is especially annoying if you have unit tests to excersise private methods of an assembly invoked from the test by reflection, you may be wanting to test a specific exception, here's a useful wrapper function to help out here:

        public void ExpectedExceptionMethodInvokeWrapper(object[] invokeParams, object instance, MethodInfo methodToInvoke)
        {
            try
            {
                methodToInvoke.Invoke(instance, invokeParams);

                // Fail: Expected Exception of T
            }
            catch (TargetInvocationException tie)
            {
                if (tie.InnerException is T)
                {
                    throw tie.InnerException;
                }
                else
                {
                    // Fail: Expected Exception of T
                }
            }
            catch
            {
                // Fail: Expected TargetInvocationException, with valid inner exception
            }
        }

Misc stream / string / serialization helpers

Some useful stream / string / serialization helpers

public string GetStringFromStream(Stream str)
{
    string s = null;

    using (StreamReader sr = new StreamReader(str))
    {
        s = sr.ReadToEnd();
    }

    return s;
}

public Stream GetStreamFromString(string s, out string charset)
{
    Stream str = null;
    charset = string.Empty;

    // Write the data to a new stream...
    using (StreamWriter sw = new StreamWriter(new MemoryStream()))
    {
        sw.Write(s);
        sw.Flush();
        sw.BaseStream.Seek(0, SeekOrigin.Begin);
        charset = sw.Encoding.HeaderName;
        str = sw.BaseStream;
    }
    return str;
}

public Stream GetStreamFromObject(object instance)
{
    Stream str = new MemoryStream();
    XmlSerializer xmlz = new XmlSerializer(instance.GetType());
    xmlz.Serialize(str, instance);

    return str;
}

public string SerializeInstance(object instance, Type t)
{
    MemoryStream ms = new System.IO.MemoryStream();
    XmlSerializer xmlz = new XmlSerializer(t);
    xmlz.Serialize(ms, instance);
    ms.Seek(0, SeekOrigin.Begin);

    using (StreamReader sr = new StreamReader(ms))
    {
        return sr.ReadToEnd();
    }
}

public static T DeserializeInstance(string xml)
{
    XmlSerializer xmlz = new XmlSerializer(typeof(T));
    return (T)xmlz.Deserialize(new XmlTextReader(new StringReader(xml)));
}

public static T DeserializeInstance(System.IO.Stream str)
{
    XmlSerializer xmlz = new XmlSerializer(typeof(T));
    return (T)xmlz.Deserialize(str);
}

Biztalk Catalog Explorer (Microsoft.Biztalk.ExplorerOM)

Ships as a dev tool with BTS and useful alternate to WMI, plenty of code example on the net.