简体   繁体   English

wcf双工服务失去与客户端的耦合

[英]wcf duplex service lose coupling with client

I have been stuck on an issue for 2 weeks. 我在一个问题上停留了两个星期。

Let's assume we have a Duplex WCF Service and a Client application that calls the service. 假设我们有一个Duplex WCF服务和一个调用该服务的客户端应用程序。

The app has a class MyCallBackClass that is composed of the service. 该应用程序具有由服务组成的类MyCallBackClass。 What I would like to achieve is to pass the instantiated service in the constructor of the MyCallBackClass client app (lose coupling). 我想要实现的是在MyCallBackClass客户端应用程序的构造函数中传递实例化的服务(丢失耦合)。 So it would look something like service with one method and callback with one method: 因此,它看起来像是一种方法的服务和一种方法的回调:

DUPLEX SERVICE CONTRACT: 双工服务合同:

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

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

}

DUPLEX CALLBACK: 双重回调:

public interface ICallback{

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

}

DUPLEX SERVICE Implementation DUPLEX SERVICE实施

public class Service : IService{

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

void GetDataFromService(){

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

MY CLASS THAT IMPLEMENTS CALLBACK: 造成回调的我的班级:

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

}

}

Now in the application I am forced to instantiate the service in the constructor of the object that implements callback interface, lets assume it is a Form, or WPF Form (as follows): 现在在应用程序中,我被迫在实现回调接口的对象的构造函数中实例化服务,假设它是Form或WPF Form(如下所示):

public void Main(string[] args){

MyCallBackClass myWindow = new MyCallBackClass();

myWindow.GetDataFromService();

}

What I would like to have is to PASS THE SERVICE in Constructor of the callback handler, as follows: 我想拥有的是通过回调处理程序的构造函数中的服务通过,如下所示:

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

}

And ofcourse the class's MyCallBackClass constructor would change to this: 当然,该类的MyCallBackClass构造函数将更改为:

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

public MyCallBackClass (IService _service){

InstanceContext instanceContext = new InstanceContext(this);

this.service = _service;

...
}

So that I can inject any type of service that implements IService interface to the client class and it is easy to test the client class by mocking the Service. 这样我就可以向客户端类注入实现IService接口的任何类型的服务,并且可以通过模拟Service来轻松测试客户端类。 Unfortunately I come across a DEPENDENCY LOOP. 不幸的是,我遇到了依赖循环。 The InstanceContext dependson MyCallBackClass that dependson IService that dependson InstanceContext... InstanceContext依赖MyCallBackClass依赖IService依赖InstanceContext ...

Could you please try to understand and try to guide me to any direction that would solve this issue? 您能否尝试理解并尝试指导我解决该问题的任何方向?

You could try this. 你可以试试看。 win.service.Value is time when Service is first time used that it will be instanciated (referenced original with delegate). win.service.Value是首次使用Service的时间(实例将引用原始的委托)。 This could be done as well with method SetService on Windows, the difference is that someone might forget to call it when Windows instance is created. 也可以使用Windows上的SetService方法来完成此操作,区别在于创建Windows实例时可能会忘记调用它。 All mandatory items must be in the constructor of Windows, that is Contract, Function as well as Lazy load makes your Dependency live :) 所有必需项都必须位于Windows的构造函数中,即Contract,Function和Lazy load使您的依赖关系生效:)

You should definitely refactor your code, try to read about SOLID principles. 您绝对应该重构代码,尝试阅读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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM