I'm trying to design a client / server solution. Currently it contains three projects. The client, the server, and a library that each use (because they both require a lot of the same stuff).
For example, both the client and the server (in this case) read incoming data in the exact same way. Because of this, both the client and the server have their own MessageReader object. The MessageReader will first read the first 4 bytes of incoming stream data to determine the length of the data and then read the rest. This is all performed asynchronously. When all the data is read the class raises its own MessageRead event or if there was an IOException while reading it raises its own ConnectionLost event.
So this all works fine. What's the problem? Well, the client and the server are a bit different. For example, while they may read data in the same way, they do not write data in the same way. The server has a Dictionary of clients and has a Broadcast method to write to all clients. The client only has a single TcpClient and can only Write to the server. Currently all this behavior is within each respective WinForm and I want to move it to a Client and Server class but I'm having some problems.
For example, remember earlier when I was talking about the MessageReader and how it can raise both a MessageRead event and a ConnectionLost event? Well, now there's a bit of a problem because in designing the Client class I have to capture these two events and re-raise them because the client form should not have access to the MessageReader class. It's a bit ugly and looks like this:
class Client
{
private MessageReader messageReader = new MessageReader();
public delegate void MessageReceivedHandler(string message);
public delegate void ConnectionLostHandler(string message);
public event ConnectionLostHandler ConnectionLost;
public event MessageReceivedHandler MessageReceived;
public Client()
{
messageReader.ConnectionLost += messageReader_ConnectionLost;
messageReader.MessageReceived += messageReader_MessageReceived;
}
private void messageReader_MessageReceived(string message)
{
if (ConnectionLost != null)
{
ConnectionLost(message);
}
}
private void messageReader_ConnectionLost(string message)
{
if (MessageReceived != null)
{
MessageReceived(message);
}
}
}
This code is ugly because its basically duplicate code. When the MessageReader raises the MessageReceieved handler the Client has to capture it and basically re-raise its own version (duplicate code) because the client form should not have access to the message reader.
Not really of a good way to solve it. I suppose both Client and Server could derive from an abstract DataReader but I don't think a client is a data reader, nor is the server. I feel like composition makes more logical sense but I can't figure out a way to do this without a lot of code duplication and confusing event handlers.
Ouch, this question is getting a bit long.. I hope I don't scare anyone away with the length. It's probably a simple question but I'm not really sure what to do.
Thanks for reading.
Composition.
I didn't even read your code or text. I find that the average developer (almost) never needs inheritance but they like to use it quite a bit.
Inheritance is fragile. Inheritance is hard to get correct. It's harder to keep it in check with SOLID.
Composition is easy to understand, easy to change, and easy to DI, Mock, and test.
SOLID
I ended up using inheritance for this even though the relationship wasn't strong. The code duplication it got rid of was worth it. Was able to place all the events both classes shared in to the base class.
Related
as for my understanding, part of writing (unit-)testable code, a constructor should not do real work in constructor and only assigning fields. This worked pretty well so far. But I came across with a problem and I'm not sure what is the best way to solve it. See the code sample below.
class SomeClass
{
private IClassWithEvent classWithEvent;
public SomeClass(IClassWithEvent classWithEvent)
{
this.classWithEvent = classWithEvent;
// (1) attach event handler in ctor.
this.classWithEvent.Event += OnEvent;
}
public void ActivateEventHandling()
{
// (2) attach event handler in method
this.classWithEvent.Event += OnEvent;
}
private void OnEvent(object sender, EventArgs args)
{
}
}
For me option (1) sounds fine, but it the constructor should only assign fields. Option (2) feels a bit "too much".
Any help is appreciated.
A unit test would test SomeClass at most. Therefore you would typically mock classWithEvent. Using some kind of injection for classWithEvent in ctor is fine.
Just as Thomas Weller said wiring is field assignment.
Option 2 is actually bad IMHO. As if you omit a call to ActivateEventHandling you end up with a improperly initialized class and need to transport knowledge of the requirement to call ActivateEventHandling in comments or somehow else, which make the class harder to use and probably results in a class-usage that was not even tested by you, as you have called ActivateEventHandling and tested it but an uninformed user omitting the activation didn't, and you have certainly not tested your class when ActivateEventHandling was not called, right? :)
Edit: There may be alternative approaches here which are worth mentioning it
Depending on the paradigm it may be wise to avoid wiring events in the class at all. I need to relativize my comment on Stephen Byrne's answer.
Wiring can be regarded as context knowledge. The single responsibility principle says a class should do only one task. Furthermore a class can be used more versatile if it does not have a dependency to something else. A very loosely coupled system would provide many classes witch have events and handlers and do not know other classes.
The environment is then responsible for wiring all the classes together to connect events properly with handlers.
The environment would create the context in which the classes interact with each-other in a meaningful way.
A class in this case does therefore not know to whom it will be bound and it actually does not care. If it requires a value, it asks for it, whom it asks should be unknown to it. In that case there wouldn't even be an interface injected into the ctor to avoid a dependency. This concept is similar to neurons in a brain as they also emit messages to the environment and expect answer not knowing neighbouring neurons.
However I regard a dependency to an interface, if it is injected by some means of a dependency injection container just another paradigm and not less wrong.
The non trivial task of the environment to wire up all classes on start may lead to runtime errors (which are mitigated by a very good test coverage of functional and integration tests, which may be a hard task for large projects) and it gets very annoying if you need to wire dozens of classes and probably hundreds of events on startup manually.
While I agree that wiring in an environment and not in the class itself can be nice, it is not practical for large scale code.
Ralf Westphal (one of the founders of the clean code developer initiative (sorry german only)) has written a software that performs the wiring automatically in a concept called "event based components" (not necessarily coined by himself). It uses naming conventions and signature matching with reflection to bind events and handlers together.
Wiring events is field assignment (because delegates are nothing but simple reference variables that point to methods).
So option(1) is fine.
The point of constructor is not to "assign fields". It is to establish invariants of your object, i. e. something that never changes during its lifetime.
So if in other methods of class you depend on being always subscribed to some object, you'd better do it in the constructor.
On the other hand, if subscriptions come and go (probably not the case here), you can move this code to another method.
The single responsibility principle dictates that that wiring should be avoided. Your class should not care how, or where from it receives data. It would make sense to rename OnEvent method to something more meaningful, and make it public.
Then some other class (bootstrapper, configurator, whatever) should be responsible for the wiring. Your class should only be responsible for what happens when a new data come's in.
Pseudo code:
public interface IEventProvider //your IClassWithEvent
{
Event MyEvent...
}
public class EventResponder : IEventResponder
{
public void OnEvent(object sender, EventArgs args){...}
}
public class Boostrapper
{
public void WireEvent(IEventProvider eventProvider, IEventResponder eventResponder)
{
eventProvider>event += eventResponder.OnEvent;
}
}
Note, the above is pseudo code, and it's only for the purpose to describe the idea.
How your bootstrapper actually is implemented depends on many things. It can be your "main" method, or your global.asax, or whatever you have in place to actually configure and prepare your application.
The idea is, that whatever is responsible to prepare the application to run, should compose it, not the classes themselves, as they should be as single purpose as possible, and should not care too much about how and where they are used.
I am writing an application in C#. Now i am thinking over and over again about its design. Have already changed my mind 3 or 4 times but thankfully for the good.
After few iterations i come up with a solution but i am still wondering what is the best way to achieve that with C#.
Basically i will have a class lets call it MessageManager, and after each action different classes will send a message to MessageManager and MessageManager will send the message depending on the response. Then i will have another manager call it UIManager it will perform all the UI switching or inform the MessageManager in case of any core/helper operation is required.
Now the thing is messages could make up to like 50-60 types each will have different type of arguments. And i want to design it in a way if i have new messages in future it can accommodate that as well.
What is the best way to accomplish that in C# like what will be the best for such case delegates, events. Flexibility is the most important thing.
I believe that combining the Observer pattern (publish/subscribe logic) along side with the Mediator one can be a good solution to your problem. Your Mediator class will act as an Event Manager (most of your classes will depend on it as a mediator rather than depending on each others) :
public class MessageManager{
private Dictionary<string,List<MessageListener>> listeners;
public void sendMessage(Message m){
//loop over listeners of m
}
public void addMessageListener(MessageListener ml){
//add a listener
}
public void removeMessageListener(MessageListener ml){
//remove a listener
}
}
Message would be the parent interface, having a generic abstraction at this level is very important as it avoids the MessageManager from distinguishing between your 50-60 types of messages and thus becoming a nightmare to maintain. The specificity of depending on a particular sub-type of Message should be moved to a lower level: the direct consumers.
I'm currently assigned to a task to develop a software module to communicate with a stepper motor controller. The project is written in C#, I have a C++ dll to communicate with the controller. The communication runs via the Serial port. I'm planning to write the whole piece in C# by importing the necessary methods by DllImport. The key method looks something like :
ComSendReceive(pHandle, bufferIn,sizeBufferIn,bufferOut,ref bufferOut)
There are several types of messages :
You send message and expect confirmation (not the same for every message, sometimes it's OK, sometimes it's COMPLETE etc..
You send message and receive message - you can receive an error or data (for instance GET_CONTROLLER_ID)
Several other types
Of course I need to control the communication for time-outs.
My question is: Is there any "design pattern" to use for that kind of problem? I'm sure this is quite a common problem many developers have solved already.
To contribute a little - I dealt with similar problem in my last job and I solved it this way :
I had a class to communicate with the Com port and a class AT_message with bunch of overloaded constructors :
class AT_Message
{
public bool DoResponseCheck;
public string ExpectedResponse;
public AT_COMMAND command;
public string data;
public bool AddCarriageReturn;
...
//Plenty of ctors
}
class UnfriendlyInterface
{
Response SendMessage(AT_Message msg)
{
//Communicates directly with C++ dll, send message, check timeouts etc....
}
}
And I had a class the main application was communicating with, it had human friendly methods like
class FriendlyInterface
{
bool AutodetectPortAndOpenComm();
Result AnalyzeSignal(byte[] buffer)
{
Response response = UnfriendlyInterface.SendMessage(new Message(AT_Command.PrepareForSignal, (doResponseCheck)true, ExpectedResponse.Ok,Timeout.short);
Response response = UnfriendlyInterface.SendMessage(new Message(buffer,(doResponseCheck)false,Timeout.long);
//.... Other steps
}
//... other methods
}
Since last time I was really in a big hurry, I implemented first solution that came to my mind. But is there a way to do it better? Now the device I'm communicate with is more complex than the previous one so if there's a way how to do it better, I'd like to do it that way.
This seems like a textbook facade pattern. The answer to all of this is to encapsulate your variation. For example, try to create a generic interface for commands that give an acknowledgement, and write client code to use that interface. Then concrete types can decide how to interpret various acknowledgements into a uniform signal (Ok = Complete = Good, or whatever)
Here's a good article on the facade pattern. Also see the wikipedia article.
my Problem are the events from the WCF client. I hand the client object to some classes. And in this classes i created the events. If i created in different classes the same event it's fires many times. I want that only the event fires in the class where i call the WCF.
How can i solve the Problem? Only Remove each event after complete?
Sry for my english ;)
Thanks....
Hi
I don't understand your question quite well, but I'll try to answer the way I did.
When you reference a WCF service, as you know proxy classes will be generated in client project. This proxy classes share the same data member's Interface which is on the server-side, but not the behavior. So for instance, all properties will be accessible from the client, but not events, methods and so on. Maybe you can write what you are trying to accomplish and we may help?
Update
Ok, now I think I understand. Well that's a solution to remove each event which shouldn't fire before you execute AddNumber method. Another solution is to keep track of calling classes. for example
public static ArrayList eventObjects = new ArrayList(); //Declare a global array list which will be accessible from all classes
eventObjects.Add(this); //Before calling AddNumber method
_client.AddNumber += new EventHandler<AddNumberCompletedEventArgs>(_client_AddNumberCompleted);
void _client_AddNumberCompleted(object sender, AddNumberCompletedEventArgs e)
{
if(ar.Contains(this))
{
//Do what you want to do here. Other classes will receive this event too, but they will not react.
eventObjects.Remove(this);
}
}
However I must warn you that this is not a best approach. I can't suggest you a better way because I don't know what you are trying to accomplish.
okay sorry.
I added the WCF to the Service References in the client project.
Then i created a instance from the Webservice Client:
private WServiceClient _client = new WService.WServiceClient();
I hand this object to several classes. In this classes i create the complete events from some Methodes from the WCF (asyc calls). Like this:
_client.AddNumber += new EventHandler<AddNumberCompletedEventArgs>(_client_AddNumberCompleted);
void _client_AddNumberCompleted(object sender, AddNumberCompletedEventArgs e)
{
}
The problem is that i use some methods multiple in different classes, i create more than one complete event. If the Complete Event fires, all event fires in all classes. I want that it only the event fires who was in the class where the call was made.
I hope you understand my description.
Update:
i solve my Problem with remove the event from the eventhandler in the Complete Event.
Whenever i feel hungry i will publish i am hungry.This will be notified to the service providers say (MealsService,FruitService,JuiceService ).(These service providers know what to serve).
But the serving priority is the concern. Priority here means my first choice is MealsService when there are enough meal is available my need is end with MealsService.To verify the enough meal is availabe the MealsService raises the event "updateMeTheStockStatus" to the "MealsServiceStockUpdateListener" .
The "MealsServiceStockUpdateListener" will only reply back to "MealsService" . No other Service providers ( FruitService,JuiceService ) will be notified by the "MealsServiceStockUpdateListener" .If there is no sufficient stock then only the MealsService passes notification to the JuiceService (as it is the second priority).As usual it checks the stock.If stock is not sufficient it passes message to FruitService,so the flow continues like this.
How can i technically implement this?
Any implemention like priority based delagates and delegate chaining make sense ?
(Somebody! Please reframe it for good readability ).
Update : In this model there is no direct communication between "StackUpdateListener" and "me".Only The "Service Providers" will communicate me.
Like other answerers, I'm not entirely convinced that an event is the way forward, but let's go along with it for the moment.
It seems to me that the business with the MealsServiceStockUpdateListener is a red herring really - you're just trying to execute some event handlers but not others. This sort of thing crops up elsewhere when you have a "BeforeXXX" event which allows cancellation, or perhaps some sort of exception handling event.
Basically you need to get at each of your handlers separately. There are two different ways of doing that - either you can use a normal multicast delegate and call GetInvocationList() or you can change your event declaration to explicitly keep a list of handlers:
private List<EventHandler> handlers = new List<EventHandler>();
public event EventHandler MealRequired
{
add { handlers.Add(value); }
remove
{
int index = handlers.LastIndexOf(value);
if (index != -1)
{
handlers.RemoveAt(index);
}
}
}
These two approaches are not quite equivalent - if you subscribe with a delegate instance which is already a compound delegate, GetInvocationList will flatten it but the List approach won't. I'd probably go with GetInvocationList myself.
Now, the second issue is how to detect when the meal has provided. Again, there are two approaches. The first is to use the normal event handler pattern, making the EventArgs subclass in question mutable. This is the approach that HandledEventArgs takes. The second is to break the normal event pattern, and use a delegate that returns a value which can be used to indicate success or failure (and possibly other information). This is the approach that ResolveEventHandler takes. Either way, you execute the delegates in turn until one of them satistfies your requirements. Here's a short example (not using events per se, but using a compound delegate):
using System;
public class Test
{
static void Main(string[] args)
{
Func<bool> x = FirstProvider;
x += SecondProvider;
x += ThirdProvider;
Execute(x);
}
static void Execute(Func<bool> providers)
{
foreach (Func<bool> provider in providers.GetInvocationList())
{
if (provider())
{
Console.WriteLine("Done!");
return;
}
}
Console.WriteLine("No provider succeeded");
}
static bool FirstProvider()
{
Console.WriteLine("First provider returning false");
return false;
}
static bool SecondProvider()
{
Console.WriteLine("Second provider returning true");
return true;
}
static bool ThirdProvider()
{
Console.WriteLine("Third provider returning false");
return false;
}
}
Rather than publish a message "I'm hungry" to the providers, publish "I need to know current stock available". Then listen until you have enough information to make a request to the correct food service for what you need. This way the logic of what-makes-me-full is not spread amongst the food services... It seems cleaner to me.
Message passing isn't baked into .NET directly, you need to implement your own message forwarding by hand. Fortunately, the "chain of responsiblity design pattern" is designed specifically for the problem you're trying to solve, namely forwarding a message down a chain until someone can handle it.
Useful resources:
Chain of Responsibility on Wikipedia
C# implementation on DoFactory.com
I'm not sure if you really need a priority event. Anyways, let's suppose we want to code that just for fun.
The .NET Framework has no support for such a peculiar construct. Let me show one possible approach to implement it.
The first step would be to create custom store for event delegates (like described here);
Internally, the custom event store could work like a priority queue;
The specific EventArgs used would be HandledEventArgs (or a subclass of it). This would allow the event provider to stop calling handlers after one of them sets the event as Handled;
The next step is the hardest. How to say to tell the event provider what is the priority of the event handler that is being added?
Let me clarify the problem. Usually, the adding of a handler is like this:
eater.GotHungry += mealsService.Someone_GotHungry;
eater.GotHungry += juiceService.Someone_GotHungry;
eater.GotHungry += fruitService.Someone_GotHungry;
The += operator will only receive an delegate. It's not possible to pass a second priority parameter. There might be several possible solutions for this problem. One would be to define the priority in a custom attribute set at the event handler method. A scond approach is discussed in the question.
Compared to the chain of responsibility implementation at dofactory.com, this approach has some advantages. First, the handlers (your food services) do not need to know each other. Also, handlers can be added and remove at any time dynamically. Of course, you could implement a variation of a chain of responsibility that has this advantages too.
I don't think delegates are the proper solution to your problem. Delegates are a low-level service provided by C# for relatively tightly coupled events between components. If I understand your question properly (It is worded a little oddly, so I am not sure I clearly understand your problem), then I think what you need is a mediated consumer/provider.
Rather than having your consumers directly consume the meal, juice, and fruit providers, have them request a food item from a central mediator. The mediator would then be responsible for determining what is available and what should be provided to the consumer. The mediator would be a subscriber to events published by all three services. Whenever stock is added/updated in the Meal, Juice, or Fruit services, they would publish their current stock to all subscribers. The mediator, being a subscriber, would track current stock reductions on its own, and be able to determine for itself whether to send a meal, juice, or fruit to a food consumer when a get food request is made.
For example:
|---------- (GetFoodResponse) ----------------
V |
FoodConsumer ---- (GetFoodRequest) ------> FoodProvider <-----> [ Local Stock Data ]
^
|
|
MealService ---- (PublishStockMessage) ----------|
^
JuiceService --- (PublishStockMessage) ----------|
^
FruitService --- (PublishStockMessage) ----------|
The benefits of such a solution are that you reduce coupling, properly segregate responsibility, and solve your problem. For one, your consumers only need to consume a single service...the FoodProvider. The FoodProvider subscribes to publications from the other three services, and is responsible for determining what food to provide to a consumer. The three food services are not responsible for anything related to the hunger of your food consumers, they are only responsible for providing food and tracking the stock of the food they provide. You also gain the ability to distribute the various components. Your consumers, the food provider, and each of the three food services can all be hosted on different physical machines if required.
However, to achieve the above benefits, your solution becomes more complex. You have more parts, and they need to be connected to each other properly. You have to publish and subscribe to messages, which requires some kind of supporting infrastructure (WCF, MSMQ, some third party ESB, custom solution, etc.) You also have duplication of data, since the food provider tracks stock on its own in addition to each of the food services, which could lead to discontinuity in available stock. This can be mitigated if you manage stock updated properly, but that would also increase complexity.
If you can handle the additional complexity, ultimately, a solution like this would more flexible and adaptable than a more tightly connected solution that uses components and C# events in a local-deployment-only scenario (as in your original example.)
I am having a bit of trouble understanding your analogy here, which sounds like you're obscuring the actual intent of the software, but I think I have done something like what you are describing.
In my case the software was telemarketing software and each of the telemarketers had a calling queue. When that queue raises the event signifying that it is nearing empty, the program will grab a list of available people to call, and then pass them through a chain of responsibility which pushes the available call into the telemarketer's queue like so:
Each element in the chain acts as a priority filter: the first link in the chain will grab all of the people who have never been called before, and if it finishes (ie. went through all of the people who have never been called) without filling up the queue, it will pass the remaining list of people to call to the next link in the chain - which will apply another filter/search. This continues until the last link in the chain which just fires off an e-mail to an administrator indicating that there are no available people to be called and a human needs to intervene quickly before the telemarketers have no work to do.