How to inject WCF services using interfaces in client?

currently my UI code is depend on business logic (binary dll) interface, where instance is injected using unity container.

Future plan is, business logic might be hosted as WCF services with same interfaces. as client code is depend on interface there should not be any changes. Instance should be injected from WCF. Is the below approach is right practice, or is there any best practice available?

public interface MyServiceContract
{
    string GetData(int value);
}

public class Service1 : MyServiceContract
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }
}

public class ServiceFactory
{
    //Get instance from WCF
    public T GetWCFService<T>()
    {
        ChannelFactory<T> factory = null;

        var binding = new BasicHttpBinding();
        var address = new EndpointAddress("uri");
        factory = new ChannelFactory<T>(binding, address);
        var channel = factory.CreateChannel();
        return channel;
    }

    //Get instance from Binary Reference
    public T GetService<T>()
    {
        return UnityContainer.Resolve<T>();
    }
}

public class Test
{
     //calls binary reference method
    private void Test()
    {
        var mysvc = new ServiceFactory().GetService<MyServiceContract>();

        var resturnmessage = mysvc.GetData(9);
        Console.WriteLine(resturnmessage);
    }

    //calls wcf  method
    private void Test2()
    {
        var mysvc = new ServiceFactory().GetWCFService<MyServiceContract>();

        var resturnmessage = mysvc.GetData(9);
        Console.WriteLine(resturnmessage);
    }
}

Answers


This approach will work but it is not perfect. You will never close your connections. You need a proxy class that conforms to your interface so you can inject it. That class can have a channel of your interface and pass through all calls. But it also needs to make sure that this channel is closed when it needs to be closed.

If you have a service factory (not a fan personally), you should have an interface IBusinessLogicFactory that has a single method public T GetService<T>(). Then you can derive a UnityInjectorFactory and a WCFServiceFactory from this interface. If your code knows what it gets because you need to call different methods then your abstraction is broken.

Your test case should look like this:

public class Test
{
    private void RunTests()
    {
        Test(new WcfFactory());

        Test(new UnityContainerFactory());
    }

    private void Test(IMyServiceFactory factory)
    {
        var mysvc = factory.GetService<MyServiceContract>();

        var returnmessage = mysvc.GetData(9);
        Console.WriteLine(returnmessage);
    }
}

Closing channels is more complex than it has to be. It's acknolegded to be a bug, but Microsoft said that now that people rely on this behaviour, they cannot fix it. Anyway:

Closing any CommunicationObject:

public static void DisposeCommunicationObject(ICommunicationObject communicationObject)
{
  if (communicationObject != null)
  {
    try
    {
      communicationObject.Close();
    }
    catch
    {
      communicationObject.Abort();
    }
    finally
    {
      ((IDisposable)communicationObject).Dispose();
    }
  }
}

The thing you get as channel can be cast to IClientChannel and then passed to this function. You will need to find out for yourself when this is appropriate in your program. If you no longer want to communicate and probably after it has faulted once.


Need Your Help

Django template language - remove item from a list

python django django-templates

Just a quick question: is there a way to remove an item from a list in the Django template language?

Bootstrap background full width divs displaying incorrectly

html css twitter-bootstrap-3 mobile-safari

I have a built a site for a New Zealand non-profit. It's based on Bootstrap 3 with responsive features disabled. It's working well... except for the way that the background images for outer divs di...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.