Click here to Skip to main content
15,885,365 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi,

I am writing an network traffic analyzer. (using Pcap.Net and LibPcap.)
In my design, I have a top-level class called "Controller", and Controller creates instance (2nd-level classes) of "PacketBuffer", "PacketAnalyzer", "DatabaseWriter".
Like below.

All the classes need to get information from the Controller to coordinate with each other, so in some classes, I pass "this" (as a Controller) to the 2nd-level classes. Does this seem all right?

Most of the classes do their jobs, and store or get results from "sharedResultQueue", which is a private member of the Controller.
And I pass this member to the 2nd-level classes so they can access it.
Does this seem all right?

Thanks!

Class Controller
{
    private PacketBuffer _buffer = new ...;
    private PacketAnalyzer _analyzer;
    private DatabaseWriter _writer;
    private Queue<...> _sharedResultQueue = new Queue<...>;

    public Controller()
    {
        _analyzer = new PacketAnalyzer(this, _buffer, _sharedResultQueue);
        _writer = new DatabaseWriter(this, _sharedResultQueue);
    }
    ...
}

Class PacketBuffer
{
    ...
}

Class PacketAnalyzer
{
    private Controller _controller;
    private PacketBuffer _buffer;
    private Queue<...> _sharedResultQueue;

    public PacketAnalyzer(Controller controller, PacketBuffer buffer, Queue<...> sharedResultQueue)
    {
        _controller = controller;
        _buffer = buffer;
        _sharedResultQueue = shareResultQueue;
    }
    ...
}

Class DatabaseWriter
{
    private Controller _controller;
    private Queue<...> _sharedResultQueue;

    public DatabaseWriter(Controller controller, Queue<...> sharedResultQueue)
    {
        _controller = controller;
        _sharedResultQueue = shareResultQueue;
    }
    ...
}
Posted
Comments
Member 4689633 2-Mar-15 12:46pm    
By the way, is there an example shows a controller class coordinates its various types of worker classes? Thanks!
Member 4689633 2-Mar-15 16:08pm    
Dear all,
Thank you for your solutions! They are valuable to me in each aspect.
I also found the pattern is Mediator in Design Patterns and will do more research.
(Sorry I didn't master those patterns before. Now I need to catch up. : )
Thank you again!

Consider using the delegate concept. Understanding Delegates in C# for Beginners.

It is better not to hard link the classes together, but informing the controller that the job is done and it can get the data. It is better to use native data type or classes of the language as interface so future changes are easy and the code isnt get to some glued spaghetti. ;-)

Watch out for deadlock and reference cycles. Best is transfering data in a own buffer if it is not too much.
 
Share this answer
 
This may help you.
Recently, I implemented a Queue using .Net Concurrent Collection which does the thread handling for you. This uses the producer-consumer pattern.


XML
using System.Collections.Concurrent;
public class DHCP_Queue
    {
        public event EventHandler DataReceived;

        private ConcurrentQueue<DHCP_Packet> packetQueue;

        public DHCP_Queue()
        {
            this.packetQueue = new ConcurrentQueue<DHCP_Packet>();
        }

        protected virtual void OnDataReceived(EventArgs e)
        {
            if(DataReceived!=null)
            {
                DataReceived(this, e);
            }
        }

        public void Produce(DHCP_Packet newPacket)
        {
            this.packetQueue.Enqueue(newPacket);
            OnDataReceived(EventArgs.Empty);
        }

        public List<DHCP_Packet> ConsumeAll()
        {
            List<DHCP_Packet>  latestPackets = new List<DHCP_Packet>();
            DHCP_Packet packet = new DHCP_Packet();
            while(this.packetQueue.TryDequeue(out packet))
            {
                latestPackets.Add(packet);
            }
            return latestPackets;
        }
    }
 
Share this answer
 
Instead of passing a reference to the class, consider using the "ref" keyword in the signature of the methods that modify the "sharedResultQueue". More info https://msdn.microsoft.com/en-us/library/14akc2c7.aspx[^]

Each class that needs to modify the results queue should have a method with a signature similar to :
void addResultsTo(ref Queue<...> sharedResultQueue)
{

}

A best practice would be to create a interface that contains this methods signature, which will be implemented by all classes that need to modify the "sharedResultQueue".

Update: Also, you should understand the SOLID principles, particularly the Liskov substitution principle & the Dependency inversion principle, before deciding on your design.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900