【问题标题】:How to inject WCF services using interfaces in client?如何在客户端使用接口注入 WCF 服务?
【发布时间】:2014-06-06 16:56:55
【问题描述】:

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

未来的计划是,业务逻辑可能托管为具有相同接口的 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);
    }
}

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

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

    如果你有一个服务工厂(个人不是粉丝),你应该有一个接口IBusinessLogicFactory,它有一个方法public T GetService&lt;T&gt;()。然后你可以从这个接口派生一个 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,然后传递给这个函数。您需要自己找出适合您的程序的时间。如果您不想再进行通信,并且可能在它出现过一次故障之后。

    【讨论】:

    • 您能否为您提议的关闭频道提供一些代码 sn-ps?
    • @user3713722 添加了一些细节
    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    相关资源
    最近更新 更多