如何使用客户端中的接口注入WCF服务?

时间:2014-06-06 07:12:52

标签: c# wcf

目前我的UI代码依赖于业务逻辑(二进制dll)接口,其中实例是使用unity容器注入的。

未来计划是,业务逻辑可以作为具有相同接口的WCF服务托管。由于客户端代码依赖于接口,因此不应进行任何更改。应该从WCF注入实例。以下方法是正确的做法,还是有任何最佳做法?

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);
    }
}

1 个答案:

答案 0 :(得分:1)

这种方法将工作,但并不完美。你永远不会关闭你的联系。您需要一个符合您的界面的代理类,以便您可以注入它。该类可以拥有接口的通道并通过所有调用。但它还需要确保在需要关闭时关闭此通道。

如果您有服务工厂(不是个人粉丝),您应该有一个具有单一方法IBusinessLogicFactory的界面public T GetService<T>()。然后,您可以从此接口派生UnityInjectorFactory和WCFServiceFactory。如果您的代码知道它得到了什么,因为您需要调用不同的方法,那么您的抽象就会被破坏。

您的测试用例应如下所示:

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);
    }
}

关闭渠道比以前更加复杂。它被认为是一个错误,但微软表示,现在人们依赖这种行为,他们无法修复它。无论如何:

关闭任何CommunicationObject:

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

您作为频道获得的内容可以转换为IClientChannel,然后传递给此函数。如果您的计划适合,您需要自己找出答案。如果您不想再进行沟通,可能在发生故障之后再进行沟通。