SharePoint SilverView

23 June 2009

I’ve just seen this up and running – really slick webpart. http://code.msdn.microsoft.com/ssv/



post a comment / view comments   (currently 0 comments)

C#: Generics Equality

23 June 2009

When comparing objects using generics in C#, the behaviour is slightly different to normal comparison behaviour – notably that the compiler will default to using the more generic equals method equals(object obj)) as opposed to specific type based equals that you may have declared in a class. To overcome this, your class must implement the generic IEquatable<T> interface (instead of just overriding / overloading the equals method). A simple example is shown below:

internal class Foo : IEquatable<Foo>
{
    public int Property1 { get; set; }
    public bool Equals(Foo obj)
    {
        if (!this.Property1.Equals(obj.Property1)) return false;
        return true;
    }
}

internal class DoSomething
{
    public void Something()
    {
        var thing1 = new Foo { Property1 = 23 };
        var thing2 = new Foo { Property1 = 23 };
        this.Compare<Foo>(thing1, thing2);
    }

    private void Compare<T>(T expected, T actual) where T : IEquatable<T>
    {
        if (expected.Equals(actual))
            Console.WriteLine("Input was equal");
        else
            Console.WriteLine("Input was not equal");
    }
}

Note that this become more complicated however when comparing an instance of a base class to an instance of a deriving class. Normally you would probably want to do this using the base class implementation of equals, however some extra work is required to achieve the correct behaviour with generics (notably a constraint on your comparison method and a cast to IEquatable<T>.

internal class Foo : IEquatable<Foo>
{
    public int Property1 { get; set; }

    public bool Equals(Foo obj)
    {
        if (!this.Property1.Equals(obj.Property1)) return false;
        return true;
    }
}

internal class Bar : Foo
{
    public string Property2 { get; set; }
}

internal class DoSomething
{
    public void Something()
    {
        var thing1 = new Foo { Property1 = 23 };
        var thing2 = new Bar { Property1 = 23, Property2 = "Hello" };
        this.Compare<Foo, Bar> (thing1, thing2);
    }

    private void Compare<T, V>(T expected, V actual) where V : class, T, IEquatable<T>
    {
        if (((IEquatable<T>)expected).Equals(actual))
            Console.WriteLine("Input was equal");
        else
            Console.WriteLine("Input was not equal");
    }
}

Note that this link discusses this in more detail.



post a comment / view comments   (currently 0 comments)

Linq to SQL: MSLinqToSQLGenerator Failed

23 June 2009

Just a quick note in case i run into this again. To remedy this, you need to move the using statements into the namespace in the partial class.

http://social.msdn.microsoft.com/forums/en-US/linqtosql/thread/6c8d829f-036d-4b0a-a27d-b216482ea047/



post a comment / view comments   (currently 0 comments)

Patterns Examples

18 June 2009

I have recently been brushing up on patterns and have created a solution containing a load of pattern examples (as a learning exercise). I thought I may as well share this and hence have published it on codeplex. 

Codeplex url is: http://patternexamples.codeplex.com/

Please give me a shout if you would like to contribute more patterns or want to comment on what is there.



post a comment / view comments   (currently 0 comments)

WCF: Consuming Xml Rest Service

17 June 2009

Below is an example of how to consume a restful service that returns xml date from wcf client. This example is based on a discography service that returns releases for a specific artist. The name of the artist is passed in the query string.

Example xml returned by service:

<Artist>
  <Name>Example Artist</Name>
  <Genre>Example Genre</Genre>
  <Tracks>
    <Track>
      <Title>Track 1</Title>
      <Released>2008-10-03T00:00:00</Released>
    </Track>
    <Track>
      <Title>Track 2</Title>
      <Released>2008-10-03T00:00:00</Released>
    </Track>
  </Tracks>
</Artist>

To consume this, first declare the bindings and endpoints in the appropriate app.config / web.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="ArtistBinding" maxReceivedMessageSize="65536">
          <!-- Security is integrated auth -->
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <client>
      <endpoint address="
http://localhost"
          binding="webHttpBinding" bindingConfiguration="ArtistBinding"
          contract="RestWcfClient.IArtist"
          name="ArtistService" />
    </client>
  </system.serviceModel>
</configuration>

Define the contract using the the WebGet atrribute. Note the way the artist name is passed through on the query string (ideally a restful service will rely on nouns as opposed to query string verbs), Also note that the type “Artist” is defined later.

using System.ServiceModel;
using System.ServiceModel.Web;

namespace RestWcfClient
{
    [ServiceContract]
    public interface IArtist
    {

        [XmlSerializerFormat]
        [OperationContract]
        [WebGet(
            BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = "RestServiceForWcfExample/Discog.ashx?artist={artistName}")]
        Artist GetDiscography(string artistName);
    }
}

To consume from the method define in the template, use the following code in your client:

// "ArtistService" refers to the named endpoint in the web.config / app.config
using (var cf = new WebChannelFactory<IArtist>("ArtistService"))
{
    try
    {
        var s = cf.CreateChannel();
        var result = s.GetDiscography("An artist");
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        cf.Abort();
        throw;
    }
}

The data types used in this example are shown below (these need only to exist in the client). Note that the name of types should match the name of the xml elements returned from the rest service.

[XmlType(AnonymousType = true, Namespace = "")]
[XmlRoot(Namespace = "", IsNullable = false)]
public class Artist
{
    public string Name { get; set; }
    public string Genre { get; set; }
    public List<Track> Tracks { get; set; }
}

public class Track
{
    public string Title { get; set; }
    public DateTime Released { get; set; }
}



post a comment / view comments   (currently 0 comments)