1

我在一个问题上停留了 2 周。

假设我们有一个 Duplex WCF 服务和一个调用该服务的客户端应用程序。

该应用程序有一个由服务组成的类 MyCallBackClass。我想要实现的是在 MyCallBackClass 客户端应用程序的构造函数中传递实例化的服务(失去耦合)。所以它看起来像一个方法的服务和一个方法的回调:

双重服务合同:

[ServiceContract(SessionMode=SessionMode.Required,CallbackContract=typeof(ICallback))]
public interface IService{

 [OperationContract(IsOneWay = true)]
 void GetDataFromService();

}

双工回调:

public interface ICallback{

[OperationContract(IsOneWay = true)]
void ReceiveMessage(string message);

}

双工服务实施

public class Service : IService{

//... here a reference to the Callback endpoint

void GetDataFromService(){

callBackEndPoint.ReceiveMessage("Service was called.");
}
}

我实现回调的类:

public class MyCallBackClass : ICallback, Widnows.Form
{
IService service;

public MyCallBackClass (){

InstanceContext instanceContext = new InstanceContext(this);

this.service = new ServiceClient(instanceContext);

}

public ReceiveMessage(string message){

this.textBoxMessage.Text = message;
//here I want to stress that I would like my CallBack object to be a Form or WPF Form
//so that I can react on callbacks by modyfing the Controls like TextBox, ListBox directly

}

}

现在在应用程序中,我被迫在实现回调接口的对象的构造函数中实例化服务,假设它是一个表单或 WPF 表单(如下所示):

public void Main(string[] args){

MyCallBackClass myWindow = new MyCallBackClass();

myWindow.GetDataFromService();

}

我想要的是在回调处理程序的构造函数中传递服务,如下所示:

public void Main(string[] args){

Iservice service = new ServiceClient();// but what about the InstanceContext that is the MyCallBackClass object...???

MyCallBackClass myWindow = new MyCallBackClass(service);

myWindow.GetDataFromService();

}

当然,该类的 MyCallBackClass 构造函数会更改为:

public class MyCallBackClass : ICallback, Widnows.Form
{
IService service;

public MyCallBackClass (IService _service){

InstanceContext instanceContext = new InstanceContext(this);

this.service = _service;

...
}

这样我就可以向客户端类注入任何类型的实现 IService 接口的服务,并且通过模拟服务很容易测试客户端类。不幸的是,我遇到了一个依赖循环。InstanceContext 依赖 MyCallBackClass 依赖 IService 依赖 InstanceContext ...

您能否尝试理解并尝试指导我解决此问题的任何方向?

4

1 回答 1

0

你可以试试这个。win.service.Value 是第一次使用服务的时间,它将被实例化(引用原始与委托)。这也可以使用 Windows 上的方法 SetService 来完成,不同之处在于有人可能会在创建 Windows 实例时忘记调用它。所有必需项都必须在 Windows 的构造函数中,即 Contract、Function 以及 Lazy load 使您的 Dependency 生效:)

您绝对应该重构您的代码,尝试阅读有关 SOLID 原则的信息。

public class Service
{
    private int number;
    private Window win;

    public Service(int num, Window win)
    {
        number = num;
        this.win = win;
    }
}

public class Window
{
    public Lazy<Service> service;

    public Window(Func<Service> getService)
    {
        service = new Lazy<Service>(getService);
    }
}


    static void Main(string[] args)
    {
        Service  s = null;

        var win = new Window(() => s);

        s = new Service(1, win);

        Service winS = win.service.Value;
    }
于 2013-09-12T16:27:20.550 回答