Living in the Tech Avalanche Generation

A practitioner’s introspective on technology

Archive for the 'WCF' Category

This Jumbo Jet needs some fluency - [the new WCF config]

jumbo Ok I am yet again frustrated by having to grapple with WCF configuration. I would love to see someone write us all a really nice fluent interface for WCF configuration so we can all be put out of our misery. As Juval (WCF Uber Meister) has said from time to time, the configuration options in WCF are somewhat akin to the controls on a Jumbo Jet. I suspect that Juval has a photographic memory or perhaps flew Jumbo’s in a previous career; whatever the case, he seems to have all the configuration options and combination scenarios printed on his brain, but Juval is the exception and not the rule.

I would gladly have a go at putting one together myself but I have other projects that sit in front of it in the queue and would be glad to see someone knock one up before I get to it. If anyone knows of one out there that just hasn’t come to my attention, then please point it out and I would be most grateful. Perhaps I can drag a colleague or two into the fray?

Share/Save/Bookmark

No comments

Entity Framework and LINQ To SQL Entities are not Messages!

I’m sorry but I just don’t understand why the idea of serializing domain entities for transmission over the wire is that important. Should we be using the ‘data’ present in entities as messages, regardless of what technology stack and transport protocols are involved, ASMX, WCF, HTTP, TCP etc. Domain entities should live up to their title and be exactly what their name implies and exhibit behaviour, which is something that falls outside the purview of messages. This practice of transporting anemic entities has been fueled by  a plethora of demoware that begat production software, where the data representations of business objects became separated from their behaviours and where behavior got down grounded to lowly ‘Manager’ objects that did their work behind remote endpoints or in some other part of a layered Client Server architecture. We .NET folks can somewhat thank our J2EE brethren in part for popularizing this approach. For example in WCF we often see this kind of RPC Cruddy kind of methods:
 
[OperationContract()]
public Customer UpdateCustomer(Customer _customer)
{
    //update the customer here in the database
    //…………………..
    return _customer;
}
 

What is it about the customer that should be interesting? Some event regarding a customer surely took place? Perhaps that event indicates to us that we should consider a more descriptive name for the message and a less generic data structure as the message? Surely to update a customer we are necessarily updating everything about that customer? Perhaps UpdatingCustomerPersonalDetails would be more appropriate? If I was wearing my publish and subscribe hat, I might think that this method and service are not alone in having an interest in an UpdatingCustomerPersonalDetails message. Perhaps some other business service is interested in specific changes to the state of a customers details? There has been a bit of talk around of late regarding the role of DTO’s and how often and where data representations should or shouldn’t be duplicated. I personally have been an practicing MVC, MVP kinda guy for quite a long time now and this issue always seemed to get a bit of airplay when discussing ‘what goes in the Model‘ and ‘should Models be shared‘. People would ask, why support data structures of two types at different points in my architecture? Simple answer is dependency / coupling. I have yet to come across an instance that supports the notion that my UI is interested in displaying all my Customer data (customer as an example entity). If my Customer data structures change everyone changes with them, regardless of whether my UI or my business layer is concerned with the change. And, this all naturally leads to the question, is the RPC styled UpdateCustomer() method (above) a demonstration in tight coupling? I would say yes it is a fragile dependency and any change to this shared anaemic artifact will ripple through an architecture. If however we consider for a moment that our services should ‘handle‘ messages where they have a registered or known explicit handler for any given messages, then we can quickly dispense with the whole shared anaemic model. In a previous post I highlighted (in somewhat more detail) this approach below.

public class TestHandler : IMessageHandler<TestMessage>
{
    public void HandleMessage(TestMessage message)
    {
        Console.WriteLine(string.Format(“The Test Message name was “ +
            “{0} and it’s ID is {1}”,
            message.NameOfMessage, message.ID));
    }
}

 

Where do my ORM’s come into this?

So when it comes to the common usage or ‘classic‘ approach with ASMX / WCF Service layers, that follow the anaemic anti pattern as described nicely in our UpdateCustomer() example, you may very well encounter a domain entity defined as either an Entity Framework or LINQ To SQL entity. If you have seen the code generated by Entities in both those technologies, you will have noticed that such entities are decorated with appropriate attributes aimed at supporting serialization over the wire (further encouragement to tread that path). Let’s take our customer as an example in both LINQ To SQL and Entity Framework:

LINQ To SQL

[Table(Name="dbo.Customers")]
[DataContract()]
public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged
{
    private string _CustomerID;   

    [Column(Storage="_CustomerID", DbType="NChar(5) NOT NULL",
        CanBeNull=false, IsPrimaryKey=true)]
    [DataMember(Order=1)]
    public string CustomerID
    {
        get
        {
            return this._CustomerID;
        }
        set
        {
            if ((this._CustomerID != value))
            {
                this.OnCustomerIDChanging(value);
                this.SendPropertyChanging();
                this._CustomerID = value;
                this.SendPropertyChanged(“CustomerID”);
                this.OnCustomerIDChanged();
            }
        }
    }
}

Turning on the Serialization Mode to Unidirectional for the LINQ To SQL DataContext and it will add decorate with a DataContract attribute for Entities and the DataMember attribute for their Properties, so we can easily transport these entities over wire with WCF and re-serialize them at the receiving end.

l2s_context_wcf

Entity Framework

[global::System.Data.Objects.DataClasses.
     EdmEntityTypeAttribute(NamespaceName="NorthwindModel", Name="Customer")]
[global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
[global::System.Serializable()]
public partial class Customer :
    global::System.Data.Objects.DataClasses.EntityObject
{
    /// <summary>
    /// Create a new Customer object.
    /// </summary>
    /// <param name=”customerID”>Initial value of CustomerID.</param>
    /// <param name=”companyName”>Initial value of CompanyName.</param>
    public static Customer CreateCustomer(string customerID, string companyName)
    {
        Customer customer = new Customer();
        customer.CustomerID = customerID;
        customer.CompanyName = companyName;
        return customer;
    }
    //…..ETC ETC
}

You can see here too that the Entity Framework has setup Customer as a DataContract (ready for WCF wire serialization) and it’s Orders collection shown below is decorated as a DataMember.

[global::System.Data.Objects.DataClasses.
    EdmRelationshipNavigationPropertyAttribute
    ("NorthwindModel", "FK_Orders_Customers", "Orders")]
[global::System.Xml.Serialization.XmlIgnoreAttribute()]
[global::System.Xml.Serialization.SoapIgnoreAttribute()]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public global::System.Data.Objects.DataClasses.EntityCollection<Order> Orders
{
    get
    {
        return
            ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)
            (this)).RelationshipManager.GetRelatedCollection<Order>
            (“NorthwindModel.FK_Orders_Customers”, “Orders”);
    }
    set
    {
        if ((value != null))
        {
            ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)
                (this)).RelationshipManager.InitializeRelatedCollection<Order>
                (“NorthwindModel.FK_Orders_Customers”, “Orders”, value);
        }
    }
}

Both LINQ To SQL and Entity Framework take this approach expressly to enable us in serializing the data representations of entities across the wire for distributed computing. That’s great if you need to return your entities from your web services and all this makes that simple, but not necessarily good practice nor a coupling price I am prepared to pay.

I will confess that I have been guilty of using this pattern in the past, but for now entities are entities, having taken back the behaviors that rightfully belonged to them before being hijacked.

There seems also to have to been some discussion (worth checking out) on this topic and around DTO’s recently in Seattle.

Share/Save/Bookmark

No comments

Messaging, Azure and RPC CRUDiness.

I haven’t yet had time to look at Azure in too much depth. I do wonder whether or not messages in WCF 4.0 on Azure and in the ISB are going to continue to encourage the RPC CRUD style remote API’s that we have been seeing over the .ASMX and .WCF years? I look forward to the day when the prescribed guidance for service design does not look like this:

[OperationContract()]
public List<Customer> GetCustomer(string customerID)
{
    //look up the customer from your data store
}

I haven’t worked this way in quite some time now, but surely if we are going to move messaging forward with the latest technologies, we are not going to continue to subscribe to this style of working? This no longer demonstrates the concept of a message to me at all - it’s more like a remote low level API call, which should probably exist in a Repository of some kind. When I must use WCF, I have been employing System.ServiceModel.Channels.Message for quite some time now and as a result my applications don’t suffer the proxy coupling syndrome that many WCF applications do. But will Azure and it’s kit bag of tricks encourage pushing the boundaries of our RPC CRUDiness to the cloud and perhaps even go a long way to encourage it?

The approach I am currently employing with WCF is something inspired directly out of the top drawer of NServiceBus.

public interface IMessageHandler<T> where T : IMessage
{
    void HandleMessage(T message);
}

An IMessage is almost a placeholder.

public interface IMessage
{
    Guid ID { get; }
}

And a typical message might look like:

[XmlRoot(Namespace = "org.myco.com.au.test.messages")]
public class TestMessage : IMessage
{
    private Guid _id;
    private string _nameofMessage;

    public TestMessage() { }

    public TestMessage(Guid id)
    {
        _id = id;
    }

    [XmlElement(Order = 1)]
    public Guid ID
    {
        get { return _id; }
        set { _id = value; }
    }

    [XmlElement(Order = 2)]
    public string NameOfMessage
    {
        get { return “Test Message”; }
        set { _nameofMessage = value; }
    }
}

And to handle this kind of message we need a handler:

public class TestHandler : IMessageHandler<TestMessage>
{
    public void HandleMessage(TestMessage message)
    {
        Console.WriteLine(string.Format(“The Test Message name was “ +
            “{0} and it’s ID is {1}”,
            message.NameOfMessage, message.ID));
    }
}

Not a GetCustomer() method in shouting distance. IMessages get placed into the body of System.ServiceModel.Channels.Message and the endpoints check whether they have the appropriate handler available to them. This is how I avoid WSDL and gain the benefit of dropping new handlers in and out if the system needs to change.

Share/Save/Bookmark

1 comment

« Previous PageNext Page »

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia