首页 文章

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

提问于
浏览
2

目前我的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 回答

  • 1

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

    如果您有服务工厂(不是个人粉丝),您应该有一个具有单一方法 public T GetService<T>() 的接口 IBusinessLogicFactory . 然后,您可以从此接口派生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();
        }
      }
    }
    

    您作为 Channels 获得的东西可以转换为IClientChannel,然后传递给此函数 . 如果您的计划适合,您需要自己找出答案 . 如果你不想再进行沟通,可能在它出现故障之后 .

相关问题