Author Archives: jkang

Example of binary DataContract serialization

By   February 28, 2014
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace ConsoleApplication13
{
    public class MyClass
    {
        public int MyProperty { get; set; }

        public string MyProperty2 { get; set; }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            // create an object
            var data = new MyClass()
            {
                MyProperty = 5,
                MyProperty2 = "abc"
            };

            // create serailizer
            var serializer = new DataContractSerializer(typeof(MyClass));

            // serialization
            string path = @"C:\Temp\test.bin";
            using (var fs = File.OpenWrite(path))
            using (var writer = XmlDictionaryWriter.CreateBinaryWriter(fs))
            {
                serializer.WriteObject(writer, data);
            }

            // deserialization
            MyClass data2;
            using (var fs = File.OpenRead(path))
            using (var reader = XmlDictionaryReader.CreateBinaryReader(fs, XmlDictionaryReaderQuotas.Max))
            {
                data2 = (MyClass)serializer.ReadObject(reader);
            }
        }
    }
}

Ensure initialization of IIS hosted web application for both HTTP and non-HTTP request

By   February 21, 2014

Web application developper usually put initialization codes in Global.Application_Start method, which is called when the web application receives the first HTTP request.

But if the application contains a WCF service who expose an non-HTTP endpoint (ex: net.tcp), Application_Start may not be called before a non-HTTP request is processed.

How to ensure that an application is initialized correctly before processing any HTTP or non-HTTP request? Here is a solution:

  1. Create a static class who manage application initialization/finilization
    
    using System;
    
    namespace MyWebApplication
    {
        public static class AppManager
        {
            private static object _locker = new object();
            private static bool _isInitialized = false;
            private static bool _isFinalized = false;
    
            public static void Initialize()
            {
                // Ensure that initialization is executed only once
                lock (_locker)
                {
                    if (_isInitialized)
                        return;
                    _isInitialized = true;
                }
    
                // Put initialization code here...
            }
    
            public static void Finalize()
            {
                lock (_locker)
                {
                    if (!_isInitialized || _isFinalized)
                        return;
                    _isFinalized = true;
                }
    
                // Put finalization codes here...
            }
        }
    }
    
    
  2. Call Initialize() and Finalize() in Global.asax.cs
    
    using System;
    
    namespace MyWebApplication
    {
        public class Global : System.Web.HttpApplication
        {
            protected void Application_Start(object sender, EventArgs e)
            {
                AppManager.Initialize();
            }
    
            protected void Application_End(object sender, EventArgs e)
            {
                AppManager.Finalize();
            }
        }
    }
    
    
  3. Create a custom service host factory who creates WCF service host with “Opened” and “Closed” events.
    
    using System;
    using System.ServiceModel.Activation;
    
    namespace MyWebApplication
    {
        public class MyServiceHostFactory : ServiceHostFactory
        {
            protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
            {
                var host = base.CreateServiceHost(serviceType, baseAddresses);
                host.Opened += host_Opened;
                host.Closed += host_Closed;
                return host;
            }
    
            private void host_Opened(object sender, EventArgs e)
            {
                AppManager.Initialize();
            }
    
            private void host_Closed(object sender, EventArgs e)
            {
                AppManager.Finalize();
            }
        }
    }
    
    
  4. Modify the markup of *.svc file by specifying the custom factory
    
    <%@ ServiceHost Language="C#" Debug="true" Service="MyWebApplication.Service" CodeBehind="Service.svc.cs" 
        Factory="MyWebApplication.MyServiceHostFactory" %>
    
    

Code Snippet examples

By   January 23, 2014
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>log4net</Title>
      <Author>Jia KANG</Author>
      <Description>Code snippet for an log4net logger</Description>
      <Shortcut>log4net</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="false">
          <ID>class_name</ID>
          <Function>ClassName()</Function>
        </Literal>
        <Literal Editable="false">
          <ID>ilog</ID>
          <Function>SimpleTypeName(global::log4net.ILog)</Function>
        </Literal>
        <Literal Editable="false">
          <ID>log_man</ID>
          <Function>SimpleTypeName(global::log4net.LogManager)</Function>
        </Literal>
        <Literal Editable="true">
          <ID>_log</ID>
          <Type />
          <ToolTip />
          <Default>_log</Default>
          <Function />
        </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[private static readonly $ilog$ $_log$ = $log_man$  .GetLogger(typeof($class_name$).Name);]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>propgo</Title>
      <Author>Jia KANG</Author>
      <Description>Code snippet for get-only property and backing private readonly field</Description>
      <HelpUrl></HelpUrl>
      <SnippetTypes />
      <Keywords />
      <Shortcut>propgo</Shortcut>
    </Header>
    <Snippet>
      <References />
      <Imports />
      <Declarations>
        <Literal Editable="true">
          <ID>_myAttribute</ID>
          <Type></Type>
          <ToolTip></ToolTip>
          <Default>_myAttribute</Default>
          <Function></Function>
        </Literal>
        <Literal Editable="true">
          <ID>int</ID>
          <Type></Type>
          <ToolTip></ToolTip>
          <Default>int</Default>
          <Function></Function>
        </Literal>
        <Literal Editable="true">
          <ID>MyAttribute</ID>
          <Type></Type>
          <ToolTip></ToolTip>
          <Default>MyAttribute</Default>
          <Function></Function>
        </Literal>
      </Declarations>
      <Code Language="csharp" Kind="method decl" Delimiter="$"><![CDATA[private readonly $int$ $_myAttribute$;

public $int$ $MyAttribute$
{
    get { return $_myAttribute$; }
}]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

IDisposable implementation example

By   January 23, 2014

    public class MyClass : IDisposable
    {
        private readonly Timer _timer;

        public MyClass()
        {
            _timer = new Timer(Timer_OnElapsed, null, 0, 1000);
        }

        private void Timer_OnElapsed(object sender)
        {
        }

        #region IDisposable members

        private bool _disposed = false;

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

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _timer.Dispose();
                }
                _disposed = true;
            }
        }

        ~MyClass()
        {
            Dispose(false);
        }

        #endregion IDisposable members
    }