Generic Interfaces and Type Parsing - c#

I am trying to pass messages between several classes that communicate through interface. However, as I like to go as generic as possible, I ran into problems because the message type of incoming messages may be different from the outgoing type. I pasted some code to make it clearer.
The code below does not compile because the interface implementation passes a different type than the type of the blocking collection to which it is supposed to add incoming messages. I want to be able to send types potentially different from incoming types (incoming types obviously always match the type of the elements in the blocking collection). Can I somehow get around any sort of casting or parsing even if that means I need to redesign my interface or class?
I am still quite fresh when it comes to working with interfaces and struggled with recursions, stack overflow errors, and the like. So, if you have suggestions what I can improve design wise or just a quick fix then please help me to learn. Am very eager to understand how to implement a better pattern.
Thanks
public interface IClientMessaging
{
void MessagePassing<U>(U message);
}
public class InProcessMessaging<T> : IClientMessaging
{
private Dictionary<Type, List<IClientMessaging>> Subscriptions;
public BlockingCollection<T> MessageBuffer;
public InProcessMessaging(Dictionary<Type, List<IClientMessaging>> subscriptions)
{
//Setup Message Buffer
MessageBuffer = new BlockingCollection<T>();
//Subscribe
Type type = typeof(T);
if (subscriptions.Keys.Contains(type))
{
subscriptions[type].Add(this);
}
else
{
subscriptions.Add(type, new List<IClientMessaging>());
subscriptions[type].Add(this);
}
Subscriptions = subscriptions;
}
public void SendMessage<U>(U message)
{
//Send message to each subscribed Client
List<IClientMessaging> typeSubscriptions = Subscriptions[typeof(U)];
foreach (IClientMessaging subscriber in typeSubscriptions)
{
subscriber.MessagePassing<U>(message);
}
}
public T ReceiveMessage()
{
return MessageBuffer.Take();
}
public bool ReceiveMessage(out T item)
{
return MessageBuffer.TryTake(out item);
}
//Interface Implementation
public void MessagePassing<U>(U message)
{
MessageBuffer.Add(message); //<-"Cannot convert from U to T" [this is because I want
//to send messages of a different type than the receiving type]
}
}

I'm struggling to understand your goal here, but perhaps MessagePassing<U>(U message) should be MessagePassing(U message) and interface IClientMessaging should be interface IClientMessaging<U>.
Then InProcessMessaging<T, U> : IClientMessaging<U> - but I don't see why InProcessMessaging implements IClientMessaging AND manages subscriber lists of IClientMessaging. Seems to me that one class would manage the subscribers and another IS a subscriber (IClientMessaging).
You say U and T are different types. Well - are they related? Is one wrapper for the other? Sounds like maybe U is either a wrapper for T, a generic class itself that contains the T but adds extra info. In that case, void MessagePassing<T>(Wrapper<T> message);
UPDATES
Based on the comments so far ...
interface IClientMessage {}
interface IClientMessage<U> : IClientMessage { /* ... */ }
But rename those to:
interface IConsumer {} // (Or ISubscriber?)
interface IConsumer<TConsumed> : IConsumer{ /* ... */ }
and add:
interface IGenerator { }
interface IGenerator <TGenerated> : IGenerator {
event EventHandler<TGenerated> ItemGenerated;
}
Then:
class Manager
{
Dictionary<TConsumed, IConsumer> consumers = new ...
/* Code for attaching ItemGenerated event handlers to clients */
}
class MyClient : IGenerator<string>, IConsumer<Foo>, IConsumer<Bar>
{
event IGenerator<string>.ItemGenerated ...
void IConsumer<Foo>.Consume(...) ...
void IConsumer<Bar>.Consume(...) ...
}
Yes, this would use reflection to invoke IConsumer<TConsumed>.Consume(). Or you can leave off the generics and just use object as your types. Better yet, IClientMessage can have a Consume(object message) which in your implementation can ensure that object is a TConsumed before attempting to process it.
You could otherwise create direct client-to-client links through C# events, but you seem intent on a central dispatcher. It is the central dispatchers need to keep track of these different and unbounded number of types that is either going to require reflection OR be unaware of the types being passed (as described in the previous paragraph)
You should look at Reactive Extensions and the Observer pattern for ideas as well.
I removed my comments because it was getting too chatty.

Related

Construct generic class of concrete class from interface

I have a WCF service which accepts any entity which implements an interface. When it receives one of these entities I would like to publish an event i.e.
public void Receive(IFruit fruit)
{
messageHub.Publish(new FruitReceived<IFruit>(fruit));
}
However I would like to reify the interface so instead of everything that handles fruit subscribing to the event FruitReceived<IFruit> they can subscribe to only the type they're interested in such as FruitReceived<Apple>.
Currently I can do this through some lengthy reflection:
var fruitType = fruit.GetType();
var evt = typeof(FruitReceived<>)
.MakeGenericType(fruitType)
.GetConstructor(fruitType)
.Invoke(fruit);
This is a bit of a performance hit (even with caching the constructors) and also hard to read.
I was hoping that there's a simpler way to achieve this? I have spent so much time thinking about this solution that it's the only one I can come up with.
For reference the publish method simplifies to something like this:
public void Publish<TEvent>(TEvent evt)
{
if(_subscriptions.ContainsKey(typeof(TEvent))
{
IEnumerable<IEventHandler<TEvent>> handlers = _subscriptions[typeof(TEvent)];
foreach(var handler in handlers)
{
handler.HandleEvent(evt);
}
}
}
The underlying problem seems to be that you're receiving an instance of IFruit but downstream you want to distinguish between different concrete types.
The benefit of casting a class as an interface it implements is that consumers only need to know what the declared type is. They know it's an IFruit and that's all they need to know. As soon as they need to know more than that the benefit is reduced.
In other words, if you care at all about the difference between an Apple and an Orange then why cast it as an IFruit? Of course there are differences between implementations, but those differences - even the existence of different implementations - should be transparent to anything that depends on an IFruit.
There's no perfectly neat way to handle this. If you're not creating the generic type (as in your post) then you're doing this:
if(fruit is Apple)
There's going to be type creation or type inspection no matter what.
You could move the problem. Have a single event handler that handles FruitReceived<IFruit>. Then that event handler creates the more specific event type and re-raises it so that the more specific event handler can catch it. That way you can have event handlers specific to Apple, Orange, etc.
It's not perfect but it moves the problem from where the event is getting raised to another class that facilitates raising the more specific event type.
Another reason why this is beneficial is that your design allows for multiple event handlers. So conceivably you could raise FruitEvent<IFruit> where the concrete type is an Apple, so you want an apple-specific event handler, but you also want a generic IFruit event handler to execute. If you convert your event to FruitEvent<Apple> before raising it then you won't execute the generic event handler.
This can usually be solved with the visitor pattern. But it requires some extensive changes, starting with IFruit:
interface IFruitVisitor {
void Visit(Apple apple);
void Visit(Banana banana);
// ... you need a method for each fruit
}
interface IFruit {
Accept(IFruitVisitor visitor);
}
Then your fruits must implement that method:
class Apple : IFruit {
public void Accept(IFruitVisitor visitor) => visitor.Visit(this);
}
class Banana : IFruit {
public void Accept(IFruitVisitor visitor) => visitor.Visit(this);
}
And you can have a special visitor for your case:
class CreateFruitReceivedFruitVisitor : IFruitVisitor {
public object FruitReceived { get; private set; }
public void Visit(Banana banana) => FruitReceived = new FruitReceived<Banana>(banana);
public void Visit(Apple apple) => FruitReceived = new FruitReceived<Apple>(apple);
}
Then, just use it in your original method:
public void Receive(IFruit fruit)
{
var visitor = new CreateFruitReceivedFruitVisitor();
fruit.Accept(visitor);
messageHub.Publish(visitor.FruitReceived);
}
You need to weight in the benefits and costs of this solution. Even though it can be faster than the reflection version you showed, I believe it's much more unwieldy.

Pass object into method without adding argument to method?

I have a simple interface called IEvent and it just contains this one method:
void Execute();
I have several derived classes from this interface and one of them needs access to an object that the caller of the method owns. The object is used in this fashion:
using (MyObject object = new MyObject(this.MessageService)
{
foreach (IEvent myEvent in eventList)
{
myEvent.Execute(); // <--- I need to pass object without adding argument here if possible?
}
}
I would add the object as a field in the derived class that needs access to it, but by the time I get to this part of the code, the IEvent objects are already constructed and running on a background thread. Currently, the only way I can think of is to add a setter in the IEvent interface for this object, but then I am exposing a field that most derived classes won't care about and doesn't seem like a clean solution.
I would add it as an argument to Execute(), but the problem is that the object belongs to an assembly that the assembly that contains IEvent doesn't know about (and don't want it to know about) and again 99% of the events don't care about this object anyway. Is there a better way to accomplish what I am trying to do here?
"If a class that implements IEvent does not/can not implement all the methods specified by IEvent the same way as they are declared in IEvent, that class should not implement IEvent in the first place." - Sweeper
So there's probably something wrong with your design of the whole program. I think you better revise your design a little bit and change some relationships between the classes and interfaces.
If you don't want to do that, there is another (not recommended) way to solve this problem.
Suppose your method caller is of type MethodCaller. You just change the declaration of Execute in the interface to this:
void Execute(MethodCaller obj = null);
And all the classes that implement IEvent can ignore the parameter except the class you mentioned in your question.
I'm going to piggyback on Jon Skeet's amazing knowledge of C#, .NET, CLR, IL and everything that surrounds any of those topics. You can't get to the instance of the calling object and especially the local varaible in the calling method. You can get its type, you can get the calling method through StackTrace, for example (StackTrace.GetFrames()), but none of those are going to do you any good in this situation. What you're trying to accomplish would require some heavy dive into the debugging API. As far as walking the stack, here's a quick sample I created to try see if I can figure something out for you (I made assumptions in regards to how your program is structured... obviously it's not a one to one sample):
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace SampleApp
{
class Program
{
static void Main(string[] args)
{
var eventList = new List<IEvent> { new SomeClass() };
using (MyObject obj = new MyObject(new MessageService()))
{
foreach (IEvent myEvent in eventList)
{
myEvent.Execute();
}
}
}
}
public interface IEvent
{
void Execute();
}
public class SomeClass : IEvent
{
public void Execute()
{
var stackTrace = new StackTrace();
var stackFrames = stackTrace.GetFrames();
var callingMethod = stackFrames[1].GetMethod();
var callingType = callingMethod.DeclaringType;
}
}
public class MyObject : IDisposable
{
public MessageService Service { get; }
public MyObject(MessageService service)
{
Service = service;
}
public void Dispose()
{
Service.Stop();
}
}
public class MessageService
{
public void Start() { }
public void Stop() { }
}
}
I like your question, because it presents an interesting and an unusual situation, but I'm afraid that you won't be able to accomplish your task without going outside of conventional routines that C# has in its arsenal. You may be able to pull something off with unmanaged code, but that's a different topic altogether.
However, aside from it being an interesting question... look at what you're trying to do. You have MyObject, which obviously implements IDisposable and will call Dispose() at the end of that using statement, and you're trying to grab its reference from a different assembly. I don't think this is a good idea.
I suggest revisiting your design and make use of things such as an optional parameter. May not be the "perfect" solution for your situation, as you'll pass it to every Execute in that foreach loop, but it's better than jumping through a thousand fiery hoops of debug API's.

How to find all the interfaces that extend a base interface on a given object?

I'm trying to create a crude/basic event Subscribe/Publish system just to experiment.
I created a base IEventListener interface, then a generic IEventListener<T> : IEventListener interface on top of that, which has a function OnEvent(T eventParam)
I then created a test class that implemented IEventListener<string> and IEventListener<int>
I thought that by passing it through the following:
Dictionary<Type, List<object>> _listenersByType = new Dictionary<Type, List<object>>();
foreach(Type interfaceType in listener.GetType().GetInterfaces())
{
if(interfaceType is IEventListener)
{
AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener);
}
}
I could create a look up of Event Types to Objects to cast and publish the events to. However, when stepping through. I see it loop all the interfaces, I can see the type name is "IEventListener" but the condition is never true, and never adds my listener to the dictionary.
Pastebin of full code
Through means of which I am unsure (I poked around in the debugger), this fixes it:
foreach(Type interfaceType in listener.GetType().GetInterfaces())
{
if(interfaceType.GetInterfaces().Contains(typeof(IEventListener)))
{
AddSubscriber(interfaceType.GetGenericArguments()[0], listener);
}
}
But I cannot tell you why I have to check the interfaces, of the interface. Or why I have to call interfaceType.GetGenericArguments()[0] instead of interfaceType.GetGenericTypeDefinition().
Part of me feels like this code is bad and I've got a design issue here. I would never expect the solution to be so... Ugly.
You could just ask the object itself if it implemets interface. For exampl i have created fake class:
public class SListener<T> : IEventListener<T>
{
public void OnEvent(T eventParam)
{
}
}
and object of it
var s = new SListener<string>();
if i ask
bool t = (s is IEventListener);
it is true.
So your subscribe mthod could be like :
public void Subscribe(object listener)
{
if(listener is IEventListener)
{
AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener);
}
}

Reusable non generic method for generic methods

I have the following base interface
public interface IHandler{
void Handle(IMessage message);
}
and an generic interface inheriting the base interface
public interface IHandler<TMessage> : IHandler where TMessage : IMessage{
void Handle(TMessage message);
}
My classes can implement the interface IHandler<TMessage> mutiple times. IMessage is an base interface for messages and isn´t relevant here. Currently i´m implementing the interfaces as follows.
public class ExampleHandler : IHandler<ExampleMessage>, IHandler<OtherExampleMessag>{
void IHandler.Handle(IMessage message){
ExampleMessage example = message as ExampleMessage;
if (example != null) {
Handle(example);
}
else {
OtherExampleMessage otherExample = message as OtherExampleMessage;
if (otherExample != null) {
Handle(otherExample);
}
}
public void Handle(ExampleMessage) {
//handle message;
}
public void Handle(OtherExampleMessage) {
//handle message;
}
}
What bothers me is the way i have to implement the Handle(IMessage) method, cause in my opinion its many redundant code, and i have to extend the method each time when i implement a new IHandler<TMessage> interface on my class.
What i´m looking for is a more generic way to implement the Handle(IMessage) method (maybe in a base class for Handlers), but i´m currently stuck how to do that.
You can use the new dynamic keyword to move the overload resolution to the DLR:
void IHandler.Handle(IMessage message)
{
dynamic d = message;
Handle(d);
}
Please note that this will fail at runtime with a RuntimeBinderException if the message passed in is not valid for your class.
To avoid this exception you can add a Handler for all unknown message types:
private void Handle(object unknownMessage)
{
// Handle unknown message types here.
}
To implement IHandler.Handle in a base class, you need to do a little bit more work:
public class BaseHandler : IHandler
{
void IHandler.Handle(IMessage message)
{
dynamic d = message;
Handle(d);
}
private void Handle<TMessage>(TMessage message) where TMessage : IMessage
{
var handler = this as IHandler<TMessage>;
if(handler == null)
HandleUnknownMessage(message);
else
handler.Handle(message);
}
protected virtual void HandleUnknownMessage(IMessage unknownMessage)
{
// Handle unknown message types here.
}
}
Your specific handler would than look like this:
public class ExampleHandler : BaseHandler,
IHandler<ExampleMessage>,
IHandler<OtherExampleMessage>
{
public void Handle(ExampleMessage message)
{
// handle ExampleMessage here
}
public void Handle(OtherExampleMessage message)
{
// handle OtherExampleMessage here
}
}
This code now works like this:
The DLR calls the generic BaseHandler.Handle<TMessage> method with the real message type, i.e. TMessage will not be IMessage but the concrete message class like ExampleMessage.
In this geneirc handler method, the base class tries to case itself to a handler for the specific message.
If that is not successful, it calls HandleUnknownMessage to handle the unknown message type.
If the cast is successful, it calls the Handle method on the specific message handler, effectifly delegating the call to the concrete Handler implementation.
A reasonable way would be some judicious use of reflection:
var method = this.GetType().GetMethod("Handle", new[] { message.GetType() });
if (method != null) {
method.Invoke(this, new[] { message });
}
If you are doing this so much that performance is a problem you could cache the results of the test for a massive improvement.
You stuck because your class (in the question) does more than one thing. It deals with ExampleMessage and OtherExampleMessage. I suggest you create one class to handle one thing.
Example:
public class ExampleHandler : IHandler<ExampleMessage>
and
public class OtherExampleHandler : IHandler<OtherExampleMessag>
From my understanding, you want to have a class to handle some kind of events. In this case, you may have to use Observer pattern to notify each Handler when something happen and let they do their work.
The interfaces are saying that you have an instance that provides N services. Sure the services are similar but as they are for different types they are independent services. So your detecting a 'code smell'. The smell is 'why a common method for different services?'.
So are the services different enough to justify the generic interface declarations? The fundamental here is 'duplication'. Refactor out the duplication. Duplication is BAD. Once you move the duplicate stuff out then the answer will be self evident.
To put this another way, get rid of the common method and handle each in its own method ... the duplication is what you want to move out to another class. If so, think injection.
Love your smell detection!

Design pattern for loading multiple message types

As I was looking through SO I came across a question about handling multiple message types. My concern is - how do I load such a message in a neat way? I decided to have a separate class with a method which loads one message each time it's invoked. This method should create a new instance of a concrete message type (say AlphaMessage, BetaMessage, GammaMessage, etc.) and return it as a Message.
class MessageLoader
{
public Message Load()
{
// ...
}
}
The code inside the method is something which looks really awful to me and I would very much like to refactor it/get rid of it:
Message msg = Message.Load(...); // load yourself from whatever source
if (msg.Type == MessageType.Alpha) return new AlphaMessage(msg);
if (msg.Type == MessageType.Beta) return new BetaMessage(msg);
// ...
In fact, if the whole design looks just too messy and you guys have a better solution, I'm ready to restructure the whole thing.
If my description is too chaotic, please let me know what it's missing and I shall edit the question. Thank you all.
Edit:
What I don't like about this code is that I have to create an instance of a Message (cause it knows how to load itself) and then have to decorate it with a concrete message type (cause decorators know how to interpret msg's Data property). Maybe this will make the question slightly more clear.
I agree with CkH in that Factory pattern will solve it. I wrote a silly example as a proof of concept. Not meant to show good class design, just that a simple Factory pattern works. Even if you are using multiple message types and handlers, you should only need to modify this pattern slightly.
class Class12
{
public static void Main()
{
Message m = new Message(1, "Hello world");
IMessageHandler msgHandler = Factory.GetMessageHandler(m.MessageType);
msgHandler.HandleMessage(m);
Message m2 = new Message(2, "Adios world");
IMessageHandler msgHandler2 = Factory.GetMessageHandler(m2.MessageType);
msgHandler2.HandleMessage(m2);
}
}
public class Factory
{
public static IMessageHandler GetMessageHandler(int msgType)
{
IMessageHandler msgHandler = null;
switch(msgType)
{
case 1:
msgHandler = new MessageHandler1();
break;
case 2:
msgHandler = new MessageHandler2();
break;
default:
msgHandler = new MessageHandler1();
break;
}
return msgHandler;
}
}
public class Message
{
public int MessageType { get; set; }
public string AMessage { get; set; }
public Message(int messageType, string message)
{
this.MessageType = messageType;
this.AMessage = message;
}
}
public interface IMessageHandler
{
void HandleMessage(Message m);
}
class MessageHandler1 : IMessageHandler
{
#region IMessageHandler Members
public void HandleMessage(Message m)
{
string message = m.AMessage;
Console.WriteLine(message);
}
#endregion
}
class MessageHandler2 : IMessageHandler
{
#region IMessageHandler Members
public void HandleMessage(Message m)
{
string message = m.AMessage;
Console.WriteLine("Hey there " + message);
}
#endregion
}
The next level of abstraction is to make Message discovery and instantiation dynamic. This is often accomplished by associating a string name with each Message or by using the name of the class as an identifier. You can use Reflection to discover available Message types, store them in a Dictionary and provide instantiation by name. This can be further extended to bring in Messages from dynamically loaded 'plugin' assemblies, with appropriate meta-data and interfaces to allow for loosely coupled composition between different Messages and Message Consumers. Once you get to that level, I recommend looking into frameworks like MEF which automate the discovery and instance injection process.
For your simple application, I think your approach is already quite clean. A series of if statements or a switch works just fine and is easy to understand/maintain, as long as you have a relatively small and stable set of cases.
Summarizing the further discussion in the comments:
The main design concern creating uneasiness was the fact that the different specific messages inherited from Message and yet a base Message had to be instantiated before the more specific messages could perform further analysis. This muddied up whether the Message is intended to contain raw information or to act as a base type for interpreted messages. A better design is to separate the RawMessage functionality into its own class, clearly separating concerns and resolving the feeling of 'instantiating twice'.
As for refactoring with DTOs and a mapper class:
I actually prefer your approach for an app-specific message encoding/decoding. If I want to track down why FactoryTakenOverByRobotsMessage contains invalid data, it makes sense to me that the parser method for the message is contained with the decoded data for the message. Where things get more dicey if when you want to support different encodings, as now you start wanting to specify the DTO declaratively (such as with attributes) and allow your different transport layers to decide how to serialize/deserialize. In most cases where I'm using your pattern, however, it's for a very app-specific case, with often somewhat inconsistent message formats and various proprietary encodings that don't map well in any automatic way. I can always still use the declarative encoding in parallel with the proprietary, in-class encoding and do things like serialize my messages to XML for debugging purposes.
With C# you'll probably need something like what you've written because C# is a strongly-typed language. Basically, you have to get the concrete classes somewhere in your code.
What you have looks fine. It's unambiguous. If your AlphaMessage and BetaMessage objects are children of Message then instead of creating a new object, just return the object casted.
if (msg.Type == MessageType.Alpha) return msg as AlphaMessage;
else if (msg.Type == MessageType.Beta) return msg as BetaMessage;
Consumer code will have to handle the case where the cast fails (as returns null).

Categories