Geek Talk

Bruce Zhang’s Space

Stream operation in WCF

with one comment

WCF provides the support for Stream object. It typically recommends the developer to handle the message which size is too large as Stream object for the sake of high performance.

However, there are some constraints on Stream operation to note:
1. The constraint of Binding

The valid bindings include BasicHttpBinding, NetTcpBinding and NetNamePipeBinding for Stream operation. In addition, we can’t use Reliable Messaging while handling the Stream object. If you are considering about the security of message, this way is not a good choice.

2. The constraint of Stream object

The object, you want to transport as a parameter with WCF Operation, must be serializable. Unfortunately, FileStream class can’t be serialized. We have to use Stream, MemoryStream. The Stream class is the main option for handling a stream object.

It is very interesting of transform between FileStream and Stream class. For example, the following implementation of the operation in a service:
public Stream TransferDocument(Document document)
{
     FileStream stream 
= new FileStream
                             (document.LocalPath, FileMode.Open, FileAccess.Read);
    
return stream;
}

Note, the type of return value of TransferDocument() method is Stream. But the ture type should be FileStream. Due to FileStream is the subclass of Stream, so it is no problem according to polymorphism of OO. When the client want to invoke TransferDocument() method, we can’t assign the return value to FileStream object in fact:
FileStream stream = m_service.TransferDocument(doc);

The value of stream object is null now. So we must do like this:
Stream stream = m_service.TransferDocument(doc);

It is strange that WCF can’t serialize the Length property of Stream object. On the client side, we can not use the Length property. If you want to do, it will throw a NotSupportedException.

3. The constraint of TransferMode

The default value of TransferMode is setted to Buffered. If you want to use Stream operation, you must change the default setting of TransferMode. We can set it to Streamed, StreamedRequest or StreamedResponse according to the different cases.

4. The constraint of MaxReceiveMessage

The default value of MaxReceiveMessage property is 64kb. If the size of transported stream object exceeds the setting value of MaxReceiveMessage, It will throw a CommunicationException during the client invokes the operation of service to handle this stream object. So we should change the value depending on the specific situation. The value ranges from 1 to 9223372036854775807(i.e. Int32.MaxValue). If the setting value is outside the range, the program can not be compiled successfully. Set its value in programmatic:
binding.MaxReceivedMessageSize = 120000;

And set it in administrative:
<binding …… maxReceivedMessageSize=120000/>

5. The constraint of Operation Parameters

WCF applies the strict constraint on the parameters of operation including stream objects. There can be only one stream object as the parameter(in, out, ref parameter or return value) in the method signature. So these definitions of the method are all invalid as below:
void Transfer(Stream s1, Stream s2);
void Transfer(Stream s1, out Stream s2);
void Transfer(Stream s1, ref Stream s2);
Stream Transfer(Stream stream);

If you define the method like above, it will occur the run-time error.

6. The constraint of Instance Activation

Because we can only use the BasicHttpBinding, NetTcpBinding or NetNamedPipeBinding in the stream operaiton, it will impact on the mode of instance activation, in particular Session mode. First, BasicHttpBinding doesn’t support Session mode. Secondly, although the other bindings(NetTcpBinding or NetNamedPipeBinding) support Session mode, we can’t set the value of ReliableSession to the true because the stream operation doesn’t support reliable messaging. So if you set the value of SessionMode to SessionMode.Required for the service, it will throw an exception.

In fact, the stream operation(i.e. the value of TransferMode is not Buffered) itself doesn’t support Session mode. Even we set the value of SessionMode to Allowed, and set the value of InstanceContextMode to PerSession while using NetTcpBinding, the behavior of service is still PerCall mode. And the value of SessionId(get it through by OperationContext.Current.SessionId) should be null at this time.

Finally, I recommend you increase the value of SendTimeOut property because the calling a large stream object will last too long time. For example, set its value to 10 minutes in programmatic:
binding.SendTimeout = TimeSpan.FromMinutes(10);

Or set it in administrative:
<binding …… sendTimeout=00:10:00/>

Note, the configuration of Binding on the service and client side must keep in consistent.

This article on C# Corner.

Written by Bruce Zhang

June 1, 2009 at 5:10 am

Posted in Programming

Tagged with ,

My Son is Swimming

leave a comment »

DSC01089

King, my son, enjoys the feeling in the water. Maybe all kids enjoy it. It was a first time of swimming. But he was joyful instead of scared. His cute little hands were waving, and his feet kicked the water repeatedly. I think, my son must be happy in the water. Look, he is smiling!

DSC01091

Dear son, I love you. I wish you are happy and healthy for ever!

Written by Bruce Zhang

May 20, 2009 at 2:12 pm

Posted in Life

Tagged with

A Common Base Class for LINQ To SQL

leave a comment »

Introduction

Language-Integrated Query (LINQ) is a set of features in Visual Studio 2008 that extends powerful query capabilities to the language syntax of C# and Visual Basic. As a part of LINQ, LINQ to SQL provides a run-time architecture for managing relational data as objects. To some extent, it equals to an ORM tool or framework such as NHibernate and Castle based on the .NET framework. It becomes our preferred choice gradually when we want to access databases.

In LINQ to SQL, all variables in the Data Model of a relational database can be strongly typed, which provides the benefit of compile-time validation and IntelliSense. We can fetch the data from the database using a query expression (it includes query syntax and method syntax).

However, the strongly typed feature is not conducive to abstract the common logic of data operations, so the developer has to define a specific class to handle the entity object. It results in a large number of repeated codes If we can implement the base class which encapsulates common operations such as Select, Where, Add, Update, and Delete, it will be useful for N-tier applications.

Using the Code

Using my base class for LINQ to SQL, you can simply implement the class to access a database without a line of code. What you should do is to let your class derive my base class, like this:

public class EmployeeAccessor : AccessorBase<Employee, NorthwindDataContext>

{

}

 

Now, you can add, update, delete, or select the data object with it. Please refer to the Unit Test Method:

    [TestMethod()]

    public void UpdateEmployee()

    {

        EmployeeAccessor accessor = new EmployeeAccessor();

        IList<Employee> entities = accessor.Where(e => e.EmployeeID == 1);

 

        if (entities != null && entities.Count > 0)

        {

            entities[0].FirstName = “Bruce”;

            entities[0].LastName = “Zhang”;

 

            accessor.Update(entities[0], true, true);

        }

    }

 

You may even let the Employee entity derive my base class directly:

public partial class Employee : AccessorBase<Employee, NorthwindDataContext>

{

}

 

Its behavior is very similar to the Rich Domain Model like Martin Fowler said in his article titled Anemic Domain Model.

 

The implementation of the base class

 

The implementation of the query function is very simple. We can invoke a method called GetTable<TEntity>() in the DataContext of LINQ, then invoke some LINQ operations of the GetTable<TEntity>() method, and pass the Lambda Expression to it:

public IList<TEntity> Where(Func<TEntity, bool> predicate)

{

    InitDataContext();

    return m_context.GetTable<TEntity>().Where(predicate).ToList<TEntity>();

}

 

We can also expose the method which accepts the condition clause using a dynamic query:

public IList<TEntity> Where(string predicate, params object[] values)

{

    InitDataContext();

    return m_context.GetTable<TEntity>().Where(predicate, values).ToList<TEntity>();

}

 

The implementation of the Update method (also the Delete method) is more complex. Though we can use the Attach methods LINQ introduces, there are some constraints for them. So, I have provided a couple of Update methods for different situations.

At first, we must consider whether the entity has relationship with other entities or not. If yes, we have to remove the relationship from it. I have defined a Detach method using Reflection technology, like this:

    private void Detach(TEntity entity)

    {

        foreach (FieldInfo fi in entity.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))

        {

            if (fi.FieldType.ToString().Contains(“EntityRef”))

            {

                var value = fi.GetValue(entity);

                if (value != null)

                {

                    fi.SetValue(entity, null);

                }

            }

            if (fi.FieldType.ToString().Contains(“EntitySet”))

            {

                var value = fi.GetValue(entity);

                if (value != null)

                {

                    MethodInfo mi = value.GetType().GetMethod(“Clear”);

                    if (mi != null)

                    {

                        mi.Invoke(value, null);

                    }

 

                    fi.SetValue(entity, value);

                }

            }

        }

    } 

For EntityRef<T> fields, we may set their values to null by calling the SetValue of FieldInfo to remove the relationship. However, we can’t do EntitySet in the same way because it is a collection. If set to null, it will throw an exception. So, I get the method information of the field and invoke the Clear method to clear all the items in this collection.

For the update operation, we can pass the changed entity and update it. The code snippet is shown below:

    public void Update(TEntity originalEntity, Action<TEntity> update, bool hasRelationship)

    {

        InitDataContext();

        try

        {

            if (hasRelationship)

            {

                //Remove the relationship between the entitis

                Detach(originalEntity);

            }

            m_context.GetTable<TEntity>().Attach(originalEntity);

            update(originalEntity);

 

            m_context.SubmitChanges();

        }

        catch (ChangeConflictException)

        {

            m_context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            m_context.SubmitChanges();

        }

    } 

Notice that the entity which will be updated must have a timestamp, or it will throw an exception.

Don’t worry about the correctness of the final result when we remove the relationship between the entities. The Attach method is just responsible for associating the entity to a new instance of a DataContext to track the changes. When you submit the changes, the DataContext will check the real value in the mapping database and update or delete the record according to the passed entity. Especially, you should take an action such as Cascade in the database if you want to cascade the delete between the foreign key table and the primary key table.

If the entity has no relationship with others, you may pass “false” to the hasrelationship parameter, like this:

accessor.Update(entities[0],true,false);

 

It’s terrible to create the timestamp column for your data table which exists, maybe it will affect your whole system. (I strong recommend you to create the timestamp column for your database, it will improve the performance because it won’t check all columns if they have changed during handling the concurrency.) My solution to this issue is to pass the original entity and update it with the Action<TEntity> delegate, like this:

/// <summary>

/// Update the entity which was passed

/// The changedEntity cann’t have the relationship between the entities

/// </summary>

/// <param name=”originalEntity”>It must be unchanged entity in another data context</param>       

/// <param name=”update”>It is Action<T>delegate, it can accept Lambda Expression.</param>

/// <param name=”hasRelationship”>Has relationship between the entities</param>

public void Update(TEntity originalEntity, Action<TEntity> update, bool hasRelationship)

{

    InitDataContext();

    try

    {

        if (hasRelationship)

        {

            //Remove the relationship between the entitis

            Detach(originalEntity);

        }

 

        m_context.GetTable<TEntity>().Attach(originalEntity);

 

        update(originalEntity);

 

        SubmitChanges(m_context);

    }

    catch (InvalidCastException ex)

    {

        throw ex;

    }

    catch (NotSupportedException ex)

    {

        throw ex;

    }

    catch (Exception ex)

    {

        throw ex;

    }

}

Concurrency Issue

Considering the concurrency issue, I give the default implementation for it by defining a virtual method called SubmitChanges. It will handle concurrency conflicts by the rule of last submit win. This method is as shown below:

/// <summary>

/// It provides the default policy to handle the corrency conflict

/// </summary>

/// <param name=”context”>Data Context</param>

protected virtual void SubmitChanges(TContext context)

{

    try

    {

        context.SubmitChanges(ConflictMode.ContinueOnConflict);

    }

    catch (ChangeConflictException)

    {

        context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

        context.SubmitChanges();

    }

    catch (Exception ex)

    {

        throw ex;

    }

}

 

You may override the method in your subclass if you want to change the policy to handle the concurrency conflicts.

 

Others

Maybe you have noticed that the InitDataContext method is invoked in all methods to access the data. Its implementation is like this:

private TContext m_context = null;

 

private TContext CreateContext()

{

    return Activator.CreateInstance<TContext>() as TContext;

}

 

private void InitDataContext()

{

    m_context = CreateContext();

}

 

Why do we need to create a new instance of DataContext for each method? The reason is the caching policy in the DataContext. If you create a new instance of the DataContext and query the data from the database with it, then change its value and execute the same query with the same instance, the DataContext will return the data stored in the internal cache rather than remap the row to the table. For more information, please refer to LINQ in Action.

So, the best practice is to create a new instance of the DataContext for each operation. Don’t worry about the performance, the DataContext is a lightweight resource.

This article on CodeProject.

 

More details, please visit this article on my blog.

Written by Bruce Zhang

May 19, 2009 at 2:22 pm

Posted in Programming

Tagged with ,

Focus on the Extension of WCF Behavior

leave a comment »

WCF provides the flexible and extensible architecture for the developer. The most common situation is to customize the extension of behavior. It is not complex, but some issues should be noticed. This article is prepare to discuss how to extend the behavior in WCF.

On the service side, if we want to extend the behavior, we need to extend the DispatchRuntime and DispatchOperation. The points of extension include inspecting parameters, messages and invoker of operations. The corresponding interfaces are IParameterInspector (to inspect parameters), IDispatchMessageInspector(to inspect messages) and IOperationInvoker(to invoke the operation). On the client side, we should extend the ClientRuntime and ClientOperation, and the points of extension include inspecting parameters and messages. The corresponding interfaces are IParameterInspector and IClientMessageInspector. All interfaces are placed in System.ServiceModel.Dispatcher namespace. Note please that IParameterInspector can be applied both service side and client side.

It seems like implementation of AOP (Aspect Oriented Programming) to implement these interfaces. We can inject some additional logic before and after invoking the related methods, so we call these extensions “Listener”. For example, There are some methods in IParameterInspector interface as below:

void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState);

object BeforeCall(string operationName, object[] inputs);

 

BeforeCall() method will be invoked before we invoke the target method of the service object, and AfterCall() method will be occured after the target method is invoked. For instance, we can validate if the value of parameter is less than zero before the method is invoked. If yes, it will throw an exception:

public class CalculatorParameterInspector : IParameterInspector

{

    public void BeforeCall(string operationName, object[] inputs)

    {

        int x = inputs[0] as int;

        int y = inputs[1] as int;

        if (x < 0 || y < 0)

        {

            throw new FaultException(“The number can not be less than zero.”);

        }

        return null;

    }

 

    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)

    {

        //empty;

    }

}

 

It distinguishs between the service and client side to inspect the parameter, and the methods of interface are quite converse to the order of messaging(Note: IDispatchMessageInspector interface includes BeforeSendReply() and AfterReceiveRequest(); and IClientMessageInspector interface includes BeforeSendRequest() and AfterReceiveReply()). We might handle the message through by the methods of this interface, for example, printing the message header:

public class PrintMessageInterceptor : IDispatchMessageInspector

{

    #region IDispatchMessageInspector Members

 

    public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext)

    {

        MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);

        request = buffer.CreateMessage();

 

        Console.WriteLine(“After Receive Request:”);

        foreach (MessageHeader header in request.Headers)

        {

            Console.WriteLine(header);

        }

        Console.WriteLine(new string(‘*’, 20));

        return null;

    }

 

    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

    {

        MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);

        reply = buffer.CreateMessage();

 

        Console.WriteLine(“Before Send Request:”);

        foreach (MessageHeader header in reply.Headers)

        {

            Console.WriteLine(header);

        }

        Console.WriteLine(new string(‘*’, 20));

    }

 

    #endregion

}

 

There are four different kinds of behaviors including Service Behavior, Endpoint Behavior, Contract Behavior and Operation Behavior. Their corresponding interfaces are IServiceBehavior, IEndpointBehavior, IContractBehavior and IOperationBehavior. Although they are different interface by nature, but their methods are almost similar including: AddBindingParameters(), ApplyClientBehavior() and ApplyDispatchBehavior().

 

Note: Because IServiceBehavior is only used on the service side, so it has no ApplyClientBehavior() method.

 

We can customize our class to implement these interface, but some key elements should be underlined:

1. The scope of the behavior. Table 1 describes all situations:

Behavior Type

Interface

Scope

Service

Endpoint

Contract

Operation

Service

IServiceBehavior

Y

Y

Y

Y

Endpoint

IEndpointBehavior

 

Y

Y

Y

Contract

IContractBehavior

 

 

Y

Y

Operation

IOperationBehavior

 

 

 

Y

 

2. We can add the extension of service behavior, contract behavior and operation behavior by applying on custom attribute, but can not add the extension of endpoint behavior in this way.  We can add the extension of service behavior and endpoint behavior by using config file, but can not add the extension of contract behavior and operation behavior in this way. All behaviors can be added by ServiceDescription.

 

To add the extended behavior by applying on custom attribute, we can let the custom behavior derived from Attribute class. Then we can apply it on service, contract or operation:

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface)]

public class MyServiceBehavior:Attribute, IServiceBehavior

{}

 

[MyServiceBehavior]

public interface IService

{ }

 

If you want to add the extended behavior by using config file, you must define a class derived from BehaviorExtensionElement (It belongs to System.ServiceModel.Configuration namespace) class, then override the BehaviorType property and CreateBehavior() method. BehaviorType property returns the type of extended behavior, and CreateBehavior() is responsible for creating the instance of the extended behavior:

public class MyBehaviorExtensionElement : BehaviorExtensionElement

{

    public MyBehaviorExtensionElement() { }

    public override Type BehaviorType

    {

        get { return typeof(MyServiceBehavior); }

    }

 

    protected override object CreateBehavior()

    {

        return new MyServiceBehavior();

    }

}

 

If the element which should be configured add the new property, we must apply the ConfigurationPropertyAttribute on this new one:

[ConfigurationProperty("providerName", IsRequired = true)]

public virtual string ProviderName

{

    get

    {

        return this["ProviderName"] as string;

    }

    set

    {

        this["ProviderName"] = value;

    }

}

 

The detail of config file like this:

<configuration>

  <system.serviceModel>

    <services>

      <service name=MessageInspectorDemo.Calculator>

        <endpoint behaviorConfiguration=messageInspectorBehavior

                  address=http://localhost:801/Calculator

                  binding=basicHttpBinding

                  contract=MessageInspectorDemo.ICalculator/>

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior name=messageInspectorBehavior>

          <myBehaviorExtensionElement providerName=Test/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <extensions>

      <behaviorExtensions>

        <add name=myBehaviorExtensionElement

            type=MessageInspectorDemo.MyBehaviorExtensionElement,

            MessageInspectorDemo,

            Version=1.0.0.0,

            Culture=neutral,

            PublicKeyToken=null/>

      </behaviorExtensions>

    </extensions>

  </system.serviceModel>

</configuration>

 

Please notes the contents which font are bold. <myBehaviorExtensionElement> is our extended behavior, and providerName is the new property of MyBehaviorExtensionElement. If you extended IEndpointBehavior, <serviceBehaviors> section should be replaced with <endpointBehaviors>. The extensions of custom behaviors will be placed in the <extensions></extensions> section. The value of name attribute must match the configuration of <behavior> section, both are “myBehaviorExtensionElement”.

 

The value of type inside the <behaviorExtensions> section you want to add must be the full name of type. The first part of the full name is the full type name, and the second part of the name is the namespace. Version, Culture and PublicKeyToken are also indispensable elements. The string of type name use the comma as a splitter. After the comma, it must left a space, otherwise we can not add the configuration of extended behavior normally. Why does it give the awful constraint here? Because the value is prepared for reflect technology. I agree that it is a defect. I hope microsoft will solve this problem in the next release of WCF.

 

3. In the body of related methods, we need to add the extensions of checking parameters, messages and operation invoker. The relationship between the extension of them exists here. For checking parameters, the logic of extensions might be added in ApplyClientBehavior() and ApplyDispatchBehavior() of IOperationBehavior interface. For example, we can define a CalculatorParameterValidation class for CalculatorParameterInspector:

public class CalculatorParameterValidation : Attribute, IOperationBehavior

{

    #region IOperationBehavior Members

    public void AddBindingParameters(OperationDescription operationDescription,

        BindingParameterCollection bindingParameters)

    {

    }

 

    public void ApplyClientBehavior(OperationDescription operationDescription,

        ClientOperation clientOperation)

    {

        CalculatorParameterInspector inspector = new CalculatorParameterInspector();

        clientOperation.ParameterInspectors.Add(inspector);

    }

 

    public void ApplyDispatchBehavior(OperationDescription operationDescription,

        DispatchOperation dispatchOperation)

    {

        CalculatorParameterInspector inspector = new CalculatorParameterInspector();

        dispatchOperation.ParameterInspectors.Add(inspector);

    }

 

    public void Validate(OperationDescription operationDescription)

    {

    }

    #endregion

}

 

If it is not necessary to seperate the inspector from the extended behavior, a better solution is to let a custom class implement both IParameterInspector and IOperationBehavior. For example:

public class CalculatorParameterValidation : Attribute, IParameterInspector, IOperationBehavior

{

    #region IParameterInspector Members

    public void BeforeCall(string operationName, object[] inputs)

    {

        int x = inputs[0] as int;

        int y = inputs[1] as int;

        if (x < 0 || y < 0)

        {

            throw new FaultException(“The number can not be less than zero.”);

        }

        return null;

    }

 

    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)

    {

        //empty;

    }

    #endregion

 

 

    #region IOperationBehavior Members

    public void AddBindingParameters(OperationDescription operationDescription,

        BindingParameterCollection bindingParameters)

    {

    }

 

    public void ApplyClientBehavior(OperationDescription operationDescription,

        ClientOperation clientOperation)

    {

        CalculatorParameterInspector inspector = new CalculatorParameterInspector();

        clientOperation.ParameterInspectors.Add(this);

    }

 

    public void ApplyDispatchBehavior(OperationDescription operationDescription,

        DispatchOperation dispatchOperation)

    {

        CalculatorParameterInspector inspector = new CalculatorParameterInspector();

        dispatchOperation.ParameterInspectors.Add(this);

    }

 

    public void Validate(OperationDescription operationDescription)

    {

    }

    #endregion

}

 

While operation invoker is associated with IOperationBehavior, but in fact, it will do with Invoker property of DispatchOperation. Assume that we have defined a MyOperationInvoker class which implement the IOperationInvoker interface, the solution is:

public class MyOperationInvoker : IOperationInvoker

{

    //some implementation

}

 

public class MyOperationInvokerBehavior : Attribute, IOperationBehavior

{

    #region IOperationBehavior Members

    public void AddBindingParameters(OperationDescription operationDescription,

        BindingParameterCollection bindingParameters)

    {

    }

    public void ApplyClientBehavior(OperationDescription operationDescription,

        ClientOperation clientOperation)

    {

    }

    public void ApplyDispatchBehavior(OperationDescription operationDescription,

        DispatchOperation dispatchOperation)

    {

        dispatchOperation.Invoker = new MyOperationInvoker(dispatchOperation.Invoker);

    }

    public void Validate(OperationDescription operationDescription)

    {

    }

    #endregion

}

 

As far as message inspecting with Dispatch are concerned, we can add it using MessageInspectors property in DispatchRuntime owned by  IServiceBehavior, or IEndpointBehavior, or IContractBehavior. For message inspecting with Client, we can add in using MessageInspectors property in ClientRuntime owned by IEndpointBehavior or IContractBehavior(IServiceBehavior can not be used on the client side, so it’s not IServiceBehavior’s business). For example:

public class PrintMessageInspectorBehavior : IDispatchMessageInspector, IEndpointBehavior

{

    #region IEndpointBehavior Members

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)

    {

        //empty;

    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)

    {

        clientRuntime.MessageInspectors.Add(this);

    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)

    {

        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);

    }

    public void Validate(ServiceEndpoint endpoint)

    {

        //empty;

    }

    #endregion

 

    //The implemenation of DispatchMessageInspector; Omitted

}

 

If our behavior implement the IServiceBehavior, we must iterate the ServiceHostBase object in the ApplyDispatchBehavior() method:

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

{

    foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)

    {

        foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)

        {

            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);

        }

    }

}

 

This article on CSharp Corner.

Written by Bruce Zhang

May 17, 2009 at 1:29 pm

Posted in Programming

Tagged with ,

Dispose() in WCF

leave a comment »

InfoQ posted a news “The problems with WCF and the Using Block” about the disposing client resource in WCF and gave some solutions to this issue. I was looking for some material for this question, and wanted to give my summarization here.

Without doubting, a resource (a unmanaged resource especially) need to implement the IDisposable interface. It’s  a precondition to use the using statement to manage the resources. However, if some exceptions occured in the using block, the resource couldn’t be recyled normally. Some important resouces such as the connection would keep opening and occupy the port and channel if they weren’t disposed. So it would impact on the performance of the system.

The best practice Microsoft recommends is using try/catch/(finally) statement. It requires the developer invoke the Close() in try block, and use the Abort() in catch block. The news provided the biggest difference between the Close() and the Abort:

Close() take a Timeout and has an async version, and also Close() can throw Exceptions. Abort() conversely is not supposed to block (or throw any expected exceptions), and therefore doesn’t have a timeout or an async version.

In a short, Close() will dispose the resoucres friendly and Abort() will do ungracefully. Because Close() may throw some exceptions such as CommunicationException and TimeoutException, so the code snippet on the client side would be like this:

var myClient = new MyClient();

try

{

    //do something

    myClient.Close();

}

catch (CommunicationException)

{

    myClient.Abort();

}

catch (TimeoutException)

{

    myClient.Abort();

}

catch (Exception)

{

    myClient.Abort();

    throw;

}

It is necessary of catching an exception at the end of code lines, because we don’t know if Close() method throws some unexpected exceptions such as OutOfMemoryException. In the news of InfoQ, the author introduced a solution to solve this issue provided by Steve Smith. He encapsulates these tedious code with using extension method. The type it wants to extend is ICommunicationObject, because all client objects implement the ICommunicationObject interface. The code snippet Stevie Smith wrote is as below:

public static class Extensions

{

    public static void CloseConnection(this ICommunicationObject myServiceClient)

    {

        if (myServiceClient.State != CommunicationState.Opened)

        {

            return;

        }

        try

        {

            myServiceClient.Close();

        }

        catch (CommunicationException ex)

        {

            Debug.Print(ex.ToString());

            myServiceClient.Abort();

        }

        catch (TimeoutException ex)

        {

            Debug.Print(ex.ToString());

            myServiceClient.Abort();

        }

        catch (Exception ex)

        {

            Debug.Print(ex.ToString());

            myServiceClient.Abort();

            throw;

        }

    }

}

 

We can replace the Close() with CloseConnection() method to avoid writting the repeated and tedious try/catch/finally statement. The other nice way is to use lambda expression. Its usage looks like using syntax. It defines a static method which accepts a ICommunicationObject object parameter and Action delegate:

public class Util

{

    public static void Using<T>(T client, Action action)

        where T : ICommunicationObject

    {

        try

        {

            action(client);

            client.Close();

        }

        catch (CommunicationException)

        {

            client.Abort();

        }

        catch (TimeoutException)

        {

            client.Abort();

        }

        catch (Exception)

        {

            client.Abort();

            throw;

        }

    }

}

 

We can pass the client implementation as lambda expression to Using() method:

Util.Using(new MyClient(), client =>

{

    client.SomeWCFOperation();

    //Do something;

});

 

In fact, there is another way to solve this issue. We can define a custom ChannelFactory to implement the IDisposable interface and let it as a Wrapper class to ChannelFactory. It also encapsulates the try/catch/finally statement in the Close() method of the custom ChannelFactory:

public class MyChannelFactory : IDisposable

{

    private ChannelFactory m_innerFactory;

    public MyChannelFactory(ChannelFactory factory)

    {

        m_innerFactory = factory;

    }

    ~MyChannelFactory()

    {

        Dispose(false);

    }

    public void Close()

    {

        Close(TimeSpan.FromSeconds(10));

    }

    public void Close(TimeSpan span)

    {

        if (m_innerFactory != null)

        {

            if (m_innerFactory.State != CommunicationState.Opened)

            {

                return;

            }

            try

            {

                m_innerFactory.Close(span);

            }

            catch (CommunicationException)

            {

                m_innerFactory.Abort();

            }

            catch (TimeOutException)

            {

                m_innerFactory.Abort();

            }

            catch (Exception)

            {

                m_innerFactory.Abort();

                throw;

            }

        }

    }

    private void Dispose(booling disposing)

    {

        if (disposing)

        {

            Close();

        }

    }

    void IDisposable.Dispose()

    {

        Dispose(true);

        GC.SuppressFinalize(this);

    }

}

 

Anyway, the essence of these solutions is to encapsulate the repeated logic, and ensure the security, performance and stability of the system.

Written by Bruce Zhang

May 16, 2009 at 1:26 pm

Posted in Programming

Tagged with

Times Reader 2.0

leave a comment »

On May 12th, New York Times announced the Times Reader 2.0 is now available. This new version is powered by Adobe AIR and can run equally well on Windows, Mac, Linux platform. If you are member of New York Times website, you can free download it. Installing it, it becomes more convenient to read the news from New York Times.

There are many columns such as International, National, Opinion, Business, Sport etc in Times Reader. It will help you find the news which you are interested in. It also offers the latest news so that you can obtain the latest information in time. You can choose the news according to the publishing date. In fact, it provides all news in a week. In the Times Reader, you may change the browsed way. Even you can watch the news in video or pictures. It is the extraordinary experience.

timesreader01

Figure 1: Front Page

timesreader02Figure 2: News in Pictrures

timesreader03Figrue 3: Browse Mode

I remember that I had installed the oldest version of Times Reader a couple of years ago. It was developed by WPF which is a technology produced by Microsoft. I have to agree it was amazing experience at that time. It improved the readability and useability for us. If each of publishers of newspaper provided the reader like this, no one doesn’t like to visit the website maybe, I think.

The new version of Times Reader was dropping WPF/Sivlerlight for Adobe AIR. What does it mean? It means Microsoft lost the important customer? It means Adobe AIR is better than WPF/Silverlight? Both are right, maybe. After New York Times announced the new version of Times Reader, InfoQ reported the news which title is “New York Times Dropping WPF/Silverlight for Adobe AIR“. The author wrote: “The biggest hurdle [of WPF]was the lack of cross-platform support.” I agree his opinion. Additionally, the compatibility of WPF/Silverlight is the other issue.

In the field of Rich Client Application, Microsoft lost more and more customers this year. After one year of using Silverlight, MLB swithed back to Flash to show its boradcasted live on the internet on 2009. Now, New York Times choose Adobe instead of Microsoft. What does it happen? Perhaps Microsoft should think about its strategy and improve the quality of service.

Written by Bruce Zhang

May 14, 2009 at 9:23 am

Posted in News

Tagged with

Dragon Boat Festival

leave a comment »

boatDragon Boat Festival is occuring on the fifth day of the fifth lunar month. It’s a significant holiday celebrated in china, and the one with the longest history. The Dragon Boat Festival is celebrated by boat races in the shape of dragon. Competing team rows their boats forward to a drumbeat racing to the finish end first.

The boat races during the Dragon Boat Festival are traditional custom to attempt to rescue the patriotic poet Chu Yuan. Chu Yuan drown on the fifth day of the fifth lunar month in 277 B.C. Chinese citizen now throw bamboo leaves filled with cooked rice into the water. Therefore the fish could eat the rice rather than the hero poet. This later on turned into the custom of eating tzungtzu and rice dumpling.

The celebration’s is a time for protection from evil and disease for the rest of the year. It is done so by the different practices such as Hanging healthy herbs on the front door, drinking the alcohol mixing into realgar. After researched by Chinese Culture researcher, protection from evil and disease is the real and original meaning of this festival. As for tzungtzu, the people in the Xia Dynasty had already this traditional food in fact. So called memorizing the great poet Chu Yuan, it was attached into the festival at the end of the Han Dynasty, and became into the dominant meaning of the Dragon Boat Festival. Since the essence of the Dragon Boat Festival had changed, it is not only a tradional holiday, but also a Chinese culture heritage.

On May 28th this year, let’s celebrate the Dragon Boat Festival!

Written by Bruce Zhang

May 13, 2009 at 11:17 am

Posted in Life

Tagged with

Strategy Pattern and Delegate

leave a comment »

Strategy Pattern will encapsulate a family of algorithm and make them interchangeable. So we can define the unified interface for the algorithm. It represents the polymorphism of OOD. For instance, we will develop a tool to calculate the tax. Assumed that the tax is divided into the personal income tax and enterprise tax. We can apply the Strategy Pattern into it and abstract the calculation of tax into the interface ITaxStrategy:

public interface ITaxStrategy

{

    double Calculate(double income);

}

 

The concrete tax strategies will implement the ITaxStrategy interface:

public class PeronalTaxStrategy : ITaxStrategy

{

    public double Calculate(double income)

    {

        //Implementation

    }

}

public class EnterpriseTaxStrategy : ITaxStrategy

{

    public double Calculate(double income)

    {

        //Implementation

    }

}

 

At the same time, we will define the utility class to provide the clients with convenient.

public class TaxOp

{

    private ITaxStrategy strategy;

    public TaxOp(ITaxStrategy strategy)

    {

        this.strategy = strategy;

    }

    public double GetTax(double income)

    {

        return strategy.Calculate(income);

    }

}

Now, the clients can invoke the related operation of TaxOp class to get the tax according to concrete strategy object which is passed as parameter of constructor.

public class App

{

    public static void Main(string[] args)

    {

        TaxOp op = new TaxOp(new PersonalTaxStrategy());

        Console.WriteLine(“The Personal Tax is :{0}”, op.GetTax(1000));

    }

}

 

It follows the idea of OOD. However, we can make use of the delegate syntax in C# for some simple algorithms. It will simplify our implementation. Maybe it will violate the idea of OOD, but it provides the extensibility also.

 

For the same example given before, we can modify the interface to delagate type:

public delegate double CalculateTax(double income);

 

Of course, we should provide the different implemenation:

public class Tax

{

    public static double CalculatePersonalTax(double income)

    {

        //Implementation

    }

    public static double CalculateEnterpriseTax(double income)

    {

        //Implementation

    }

}

 

Accordingly, we must modify the TaxOp Class:

public class TaxOp

{

    private CalculateTax calDel;

    public TaxOp(Calculate calDel)

    {

        this.calDel = calDel;

    }

    public double GetTax(double income)

    {

        return calDel(income);

    }

}

 

And the implementation of Clients program:

public class App

{

    public static void Main(string[] args)

    {

        TaxOp op = new TaxOp(new CalculateTax(Tax.CalculatePersonalTax));

        Console.WriteLine(“The Personal Tax is :{0}”, op.GetTax(1000));

    }

}

 

Two solutions are more or less the same. The code snippet is also similar. But the idea based on the essence of design is different completely. It’s the difference between OO and OP. The former encapsulates the behavior in an object; the latter handles the method directly, and uses the delegate to provide the extensibility. In fact, the delegate represents the feature of Functional Programming nearly. It seams like a pointer to the function in C++. In other words, the delegate is another ways of abstraction. It is more flexible than interface type. After C# 2.0 introduced the anonymous method, and C# 3.0 introduced the Lambda expression, delegate becomes more and more useful and popular on C# programming. Before C# 2.0, I prefer to interface; now I prefer to delegate. Even we may use the delegate type to provide the brand new implementation of some design patterns such as Strategy Pattern, Command Pattern etc.

Written by Bruce Zhang

May 7, 2009 at 12:49 pm

Posted in Design

Tagged with ,

Microsoft released BizTalk Server 2009

with one comment

biztalkRecently, Microsoft released BizTalk Server 2009 which is the latest version for Biztalk Server. BizTalk Server Team Blog announced this news on April 28. It posted the key improvements in the BizTalk Server 2009 release:

  • New Application Lifecycle Management(ALM) exprience to make development teams more productive
  • New adapters and numerous enhancements that provide increased enterprise connectivity
  • New RFID mobile capabilities that will enable innovative solution to drive business value

The BizTalk Server 2009 release is the globalized product. It is available broadly in nine languages: Chinese simplified, Chinese traditional, English, French, German, Italian, Japanese, Korea and Spanish. Besides, it includes four edtions: Enterprise, Standard, Branch and Developer. The price of the new version is not change. More information about the price and upgrade, please visit “Pricing and licensing” provided by Microsoft.

If you want to update it from BizTalk Server 2006 R2 to 2009,Nick Heppleston had posted a great article on his blog called “A Quick Walkthrough of the BizTalk Server 2006 R2 Upgrade to BizTalk Server 2009 RTM“. It is detail guide and introduces how to upgrade it step by step.

BizTalk Server 2009 is widely concerned in the technology community. Abdul Rafay raise his opinion in his blog:
It supports the Windows Server 2008, VS 2008, .NET Framwork 3.5 and SQL Server 2008 which I think is a major change and will have advantages of the new advanced platform.

He briefly introduced the new adapters in BizTalk Server 2009:
Unlike the release of BizTalk Server R2, BizTalk 2009 comes with two new adapters Oracle E-Business Suites and SQL Server, while there has been an enhancement in the existing adapters which I still have to explore.

Microsoft also provided the roadmap of BizTalk Server. It said:”BizTalk Server 2009 represents the next release in Microsoft’s long-term strategy to enable the connected enterprise. ” The BizTalk Server 2009 continue to build on the investments made to address the concerns of Service Oriented Architecture and Enterprise Connectivity. Especially, the new release of BizTalk Server can take advantage of the latest virtualization improvements included as part of Windows Server 2008 Hyper-V. This capability can reduce the costs through lower hardware, energy and management overhead.

To learn more information about BizTalk Server 2009, Adlai Maschiach summarize some useful matirial on his blog including MSDN Documents, Virtual Labs and BizTalk Server 2009 Solutinos. Of course, you can visit the Official Website of BizTalk Server to learn more.

Written by Bruce Zhang

May 5, 2009 at 6:23 am

Posted in News

Tagged with

VS 2008 Shortcut Key

leave a comment »

visualstudio2008logoThere are many useful shortcut keys in VS 2008. In this post, I’ll write some most useful key which are always used by myself.
Shift&Alt&Enter: Switch to Full-Screen mode;
Ctrl&Tab: Similar with Alt-Tab in Windows OS, it can switch windows that have been open currently in VS;
Ctrl&-: To navigate backward to previous place. For example, if you want to explore some class’s definition, you will select “go to definition” item from context menu to navigate the definition detail. After you view it, in the most case, you want to back the previous place, so you can press this shortcut key. That’s great and convenient for the developer. It seems like “Undo” feature;
Ctrl&Shift&-: To navigate forward to next place.

Written by Bruce Zhang

April 24, 2009 at 10:51 am

Posted in Programming

Tagged with