CRM Development

Solutionist has designed the architecture for a new CRM system for use in the medical imaging industry.
Showing posts with label Architecture. Show all posts
Showing posts with label Architecture. Show all posts

Monday, 16 July 2012

Asynchronous WCF using the generated service interface

Using Asynchronous WCF in an IoC style presents an interesting challenge.


Normal examples show that you can call async WCF something like this...
      Service1Client iService1 = new Service1Client();
      iService1.GetDataCompleted += iService1_GetDataCompleted;
      iService1.GetDataAsync();



i.e. you declare the service client implementation, specify the callback and make the async call.


But... what if you want to inject the client reference, for example (using Ninject):
[Inject]
IService1 iService1 {get; set;}

where Service1 is the interface.
Well, you find that the xxxCompleted event and xxxAsync method are not available on the interface. Ouch!
But, all is not lost...
You do have two other methods... Beginxxxx and Endxxxx and you can use them as in the example below. In the Beginxxxx method you specify the callback and in the callback you can get hold of the result by calling Endxxxx


Note that in the example below, I haven't injected the Service client, but I am using the interface, IService1. The code produces the following output (with the "Waited" appearing after the calling thread has slept for 5 seconds) :

    Making call
   Got result
   You entered: 200
   Waited

    public class Program
    {
        private static void Main(string[] args)
        {
            MakeAsynchronousCall(200);
        }
 
        private static void MakeAsynchronousCall(int value)
        {
            IService1 iService1 = new Service1Client();
 
            AsyncCallback aSyncCallBack =
                delegate(IAsyncResult result)
                    {
                        try
                        {
                            Console.WriteLine("Got result");
                            var i = iService1.EndGetData(result);
 
                            Console.WriteLine(i);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    };
 
            try
            {
                Console.WriteLine("Making call");
                iService1.BeginGetData(value, aSyncCallBack, iService1);
 
                Thread.Sleep(5000);
 
                Console.WriteLine("Waited");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

The Server-side code is :
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

Thursday, 23 February 2012

Primary Keys in Entity Framework and Sync Framework - Part 2

In Part 1 we considered various options when it came to using Microsoft Sync Framework with Entity Framework.

After a certain amount of pain we seem to have got to something approaching a settled condition.
  1. We didn't want IDs that were GUIDs as this would make them unreadable. So, we are keeping Primary keys as simple ID columns.
  2. Because of this, we went for a solution that would reseed the local tables on each client to a known range. After each synchronisation, the tables would be reseeded to the correct value. That way entries created on the client/server would have different IDs and wouldn't clash
  3. We had to use SQL Server Express on the clients.
Number (3) above is a long story...

  • SQL Compact 4 won't play nicely with Entity Framework or the Sync Framework (Link here and here )
  • SQL Compact 3.5 wouldn't play nicely with the various items - follow this link and see the section "Limitations of SQL Server compact" - basically it can't:
    • "support entities with server-generated keys or values when it is used with the Entity Framework ".
There's a lot of other things that SQL server compact can't do - including supporting stored procedures. So that's how we ended up back at SQL Server Express.

I hope this gives you a flavour of the sort of things to consider when looking at data replication on SQL Server.

You're going to ask why didn't we use SQL Server Merge Replication - that's another story and another post...

Wednesday, 22 February 2012

Architecture Note

A short note on architectures for WCF-based solutions - we've found this works for us.


All classes that are being passed across the wire must be serialisable and each property must be annotated.

The WCF service is nothing more than a thin facade on top of a call to Business Logic. 
In fact it's a one-to-one relationship to the Business Logic calls... The Service layer just exposes the business logic so that it can be used in creating bindings, etc.


Business Logic - as they say, it "does the business" and calls the data access.layer.
Data Access Layer - we're using Repository pattern with Entity Framework.

Throughout, we've using IoC (Ninject) to hook data access repositories into the Business Layer and Business Logic into the Service Layer. This has meant inserting Ninject into the WCF factory pipeline - see this post.

OK, you may ask why create a WCF facade on top of the business logic?

Well, doing this lets you create clean classes and "unit" tests for the business logic without  bothered about annotations, etc for WCF.
It also means that the Business Logic layer becomes a re-usable component - where you don't have to include WCF-related annotations and dlls.