Reputation: 329
Scenario written by C# language, three principal projects in my solution: Remote, Event and Model.
Remote: manages a socket from a remote system. Remote has two handlers: to notify the connection status, send the message from the remote system.
Event: publish messages around all the solution
Model: businnes logic.
I want Remote would be isolated from the rest of the system, I mean to build a manager in Model which intercepts the notifications from Remote and uses Event to spread the message. I want every other managers in model know only Model, no the Remote implementation of the message.
I have already made custom messages to publish by Event the connection status from Remote, my problem is the follow: How can I send message without who intercept the message know the implementation? Every messages have different properties.
I tried to made a Message in model which has the same interface of the message in remote.
But in this case everyone can register mode to get the message have to know the implementation of the message to get properties.
The message which send around the Model by Event
MessageEvent: IEvent
public const string Name="MessageEvent"
// The message implemented in Remote
public IRemoteMessage RemoteMessage {get; private set;}
public void MessageEvent(IRemoteMessage rm)
{
// I want to avoid make a copy of the original message, too much classes to have same information
RemoteMessage = rm;
}
Handlers from Remote in CommunicationManager in Model
RemoteService.ReceivedData += OnReceiveData;
OnReceiveData(object sender, DataArgs e)
{
var remoteMessage = e as IRemoteMessage;
EventService.Publish(new MessageEvent(remoteMessage))
}
Everyone can register the Event (Observer) in the Model as:
EventService.Register(OnManageData, MessageEvent.Name)
\\..
private void OnManageData(EvtData arg)
{
if (arg is MessageEvent)
{
var me = arg as MessageEvent;
// I have the problem here, I can cast remoteMessage by its impementation in Remote to get the properties but I don't want it!!!
var remoteMessage = me.RemoteMessage;
}
}
Everything works in my real scenario, but I repeat my self:
Every suggestions will be appreciate
Upvotes: 0
Views: 131
Reputation: 1373
I recommend using the "Bridge Design Pattern". The Bridge is a structural design pattern that divides business logic or huge class into separate class hierarchies that can be developed independently.
here a sample to send multiple types of messages with multiple input parameter:
/// <summary>
/// The 'Abstraction' class
/// </summary>
public abstract class Message
{
public IMessageSender MessageSender { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public abstract void Send();
}
/// <summary>
/// The 'RefinedAbstraction' class
/// </summary>
public class SystemMessage : Message
{
public override void Send()
{
MessageSender.SendMessage(Subject, Body);
}
}
/// <summary>
/// The 'RefinedAbstraction' class
/// </summary>
public class UserMessage : Message
{
public string UserComments { get; set; }
public override void Send()
{
string fullBody = string.Format("{0}\nUser Comments: {1}", Body, UserComments);
MessageSender.SendMessage(Subject, fullBody);
}
}
/// <summary>
/// The 'Bridge/Implementor' interface
/// </summary>
public interface IMessageSender
{
void SendMessage(string subject, string body);
}
/// <summary>
/// The 'ConcreteImplementor' class
/// </summary>
public class EmailSender : IMessageSender
{
public void SendMessage(string subject, string body)
{
Console.WriteLine("Email\n{0}\n{1}\n", subject, body);
}
}
/// <summary>
/// The 'ConcreteImplementor' class
/// </summary>
public class MSMQSender : IMessageSender
{
public void SendMessage(string subject, string body)
{
Console.WriteLine("MSMQ\n{0}\n{1}\n", subject, body);
}
}
/// <summary>
/// The 'ConcreteImplementor' class
/// </summary>
public class WebServiceSender : IMessageSender
{
public void SendMessage(string subject, string body)
{
Console.WriteLine("Web Service\n{0}\n{1}\n", subject, body);
}
}
/// <summary>
/// Bridge Design Pattern Demo
/// </summary>
class Program
{
static void Main(string[] args)
{
IMessageSender email = new EmailSender();
IMessageSender queue = new MSMQSender();
IMessageSender web = new WebServiceSender();
Message message = new SystemMessage();
message.Subject = "Test Message";
message.Body = "Hi, This is a Test Message";
message.MessageSender = email;
message.Send();
message.MessageSender = queue;
message.Send();
message.MessageSender = web;
message.Send();
UserMessage usermsg = new UserMessage();
usermsg.Subject = "Test Message";
usermsg.Body = "Hi, This is a Test Message";
usermsg.UserComments = "I hope you are well";
usermsg.MessageSender = email;
usermsg.Send();
Console.ReadKey();
}
}
For more information see the following link:
Upvotes: 1