Archive for the ‘WCF’ category

Counting objects with Unity

April 30th, 2010

I’m using Unity for the first time on my current project (a WCF service), and the project is now fairly large with a significant amount of container configuration.  I’m taking advantage of lifetime managers to optimise object reuse, with PerThreadLifetimeManager being particularly attractive in a service – less garbage through object reuse but no locking to worry about.

I decided that it might be nice to see counts of the number of objects that Unity is creating for each type, to confirm that my lifetime configuration is optimal.  It turned out to be straightforward to do this with a Unity extension.

Here’s how the extension is used.  First, the extension is added to the container:

    var objectCounterExtension = new ObjectCounterExtension();
    container.AddExtension(objectCounterExtension);

 

At application shutdown a list of types and their associated instance counts can be output like this:

    IDictionary<Type,int> objectCounts = objectCounterExtension.ObjectCounts;

    foreach (var objectCount in objectCounts.OrderBy(oc => oc.Value))
    {
        Type type = objectCount.Key;
        int count = objectCount.Value;
        Console.WriteLine("{0}: {1}", type, count);
    }

 

The extension is quite simple, once you know how:

    class ObjectCounterExtension : UnityContainerExtension
    {
        ObjectCounterStrategy objectCounterStrategy;

        protected override void Initialize()
        {
            objectCounterStrategy = new ObjectCounterStrategy();
            Context.Strategies.Add(objectCounterStrategy, UnityBuildStage.Creation);
        }

        public IDictionary<Type, int> ObjectCounts
        {
            get { return objectCounterStrategy.ObjectCounts; }
        }
    }

    class ObjectCounterStrategy : IBuilderStrategy
    {
        Dictionary<Type, int> objectCounts = new Dictionary<Type,int>();

        public void PostBuildUp(IBuilderContext context)
        {
            IBuildKey buildKey = context.BuildKey as IBuildKey;
            if (buildKey == null)
                return;

            Type type = buildKey.Type;

            lock (objectCounts)
            {
                int count;
                if (objectCounts.TryGetValue(type, out count))
                {
                    objectCounts[type] = count + 1;
                }
                else
                {
                    objectCounts[type] = 1;
                }
            }
        }

        public Dictionary<Type, int> ObjectCounts
        {
            get
            {
                lock (objectCounts)
                {
                    return new Dictionary<Type, int>(objectCounts);
                }
            }
        }

        public void PostTearDown(IBuilderContext context) {}
        public void PreBuildUp(IBuilderContext context) {}
        public void PreTearDown(IBuilderContext context) {}
    }
 

Managed DCOM server

October 24th, 2009

For my current project I have some old unmanaged C++ code that needs to talk to a new .NET server, remotely.   The channel needs to be fast and secure.   There are a lot of options, but I’ve narrowed it down to two:

  1. WWSAPI for the C++ client, WCF for the .NET server, using NetTcpBinding.  (See here for details.)
  2. DCOM

Option 1 was the strong favourite until Microsoft decided to play silly buggers with the redistribution rights for WWSAPI, so I’ve been forced to investigate option 2.

COM interop through loading .NET components into an unmanaged process is well documented and generally works fine, but accessing a .NET server remotely via (D)COM is not so well documented, and indeed it’s not even clear if it’s supported by Microsoft.   But it does seem to work, and it’s surprisingly simple once you discover the RegisterTypeForComClients method on the RegistrationServices class.   This is basically a wrapper for COM’s CoRegisterClassObject.

Here’s the C# server code:

[ComVisible(true)]
public interface ICalculator
{
    int Add(int x, int y);
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Calculator : ICalculator
{
    public int Add(int x, int y) { return x + y; }
}

class Program
{
    [MTAThread]
    static void Main(string[] args)
    {
        var regServices = new RegistrationServices();

        int cookie = regServices.RegisterTypeForComClients(
            typeof(Calculator),
            RegistrationClassContext.LocalServer | RegistrationClassContext.RemoteServer,
            RegistrationConnectionType.MultipleUse);

        Console.WriteLine("Ready"); Console.ReadKey();

        regServices.UnregisterTypeForComClients(cookie);
    }
}

and the C++ client code:

#import "dcomserver.tlb" no_namespace raw_interfaces_only

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitializeEx(0, COINIT_MULTITHREADED);

    {
        CComPtr<ICalculator> spCalc;
        spCalc.CoCreateInstance(__uuidof(Calculator), 0, CLSCTX_LOCAL_SERVER);

        long result = 0;
        spCalc->Add(10, 20, &result);

        cout << result << endl;
    }

    CoUninitialize();
    return 0;
}

(The simplest way to generate the tlb file to #import is to run regasm /tlb DcomServer.exe)

There may well be some gotchas with this approach – I haven’t tested it thoroughly yet – but it seems a promising option if the WWSAPI licensing issues can’t be sorted out.

WCF and abstract types

October 12th, 2009

This seems like a fairly straightforward issue to me, but after googling around I’m left wondering what I’m missing.

Suppose I have a web service that contains a Search() method that takes one of two possible types of query – a simple query or a complex query.   WCF doesn’t support xsd:choice, so I can’t use that, but it does support xsd:extension, so that should do the trick:

    [DataContract]
    [KnownType(typeof(SimpleQuery))]
    [KnownType(typeof(ComplexQuery))]
    class Query { }

    [DataContract]
    class SimpleQuery : Query { }

    [DataContract]
    class ComplexQuery : Query { }

    [ServiceContract]
    interface ISearchService
    {
        Results Search(Query query);
    }

This works ok, but it’s not quite right – the client can pass an instance of Query rather than SimpleQuery or ComplexQuery.   Query really needs to be abstract.   But does XML schema support that?   Yes, it does, through complextype’s abstract attribute.

So, problem solved.  We make Query abstract and WCF’s DataContractSerializer will add the abstract=”true” to the XSD it generates.  Except that it doesn’t.  It just ignores the fact that the Query class is abstract, which means that the client sees the class as non-abstract.  This means that the client can easily pass a Query instance to the server (which of course  causes the serializer on the server to blow up trying to create an instance of the abstract class).   Hmm.

So why doesn’t DataContractSerializer support abstract base classes?  It seems pretty simple, both in concept and implementation.   Presumably it’s deemed too OO-centric … but then why support inheritance (xsd:extension)?  

BTW There’s a StackOverflow question covering the same issue – like the poster I didn’t find any of the answers satisfactory.