views:

30

answers:

2

Hi all, it concerns following: I have two projects which should exists more or less independently from each other. Project one is a kind File System Watcher. The other one cosnists of my UI. The file watcher raises an event, if there is a new file. After that, the data from the file should be added to a database. That's coarsely the background story. The actual problem is that after the file watcher raised an event, I want to notify the UI to update the view of the data. That means, the event should be raised by the file watcher and the event should be registered in the implementation of the UI. The main problem ist now that I need instances of classes from both projects. Obviuosly this results in the circular dependency problem. Of course there is the solution of interfaces for the CP problem, but this won't solve the problem, that I need the same object for data creation and event registration. Hopefully you can help me with this problem. Thanks.

A: 

I'm not sure I understand why the FileWatcher would have any dependency on you UI, but since you say it does you could add a third project to work as an event aggregator between the two. This would give both projects a dependency on the aggregator, but will remove the dependencies on each other.

Martin Harris
Sorry my fault, I didn't explained it well enough. The UI doesn't need any dependency: perhaps I can clarify my Problem in a few lines of code:FileWatcher:Recording rec = new Recording();rec.NotifyUI();UI:Recording pat = new Recording;pat.RecordingStarted += listview.UpdateList;Recording is a class in the FW project, RecordingStarted is the event, UpdateList is the method which should be executed whenever the event is raised. After that UpdateList should retrieves the new data from the Recording class, like GetNewData().
Kai Krupka
A: 

Why do you think you need an UI instance in the business logic assembly?

To register an event handler, you usually need only the instance from the calling assembly (observer, already contained in the calling assembly) and an instance of the referenced assembly (your assembly containing the filesystem watcher).

Then you have e.g. the following structure:

Assembly with logic

public class MyCustomWatcher
{   
    public event EventHandler Event;

    private void RaiseEventForWhateverReason()
    {
        if (Event != null)
        {
            Event(this, new Args());
        }
    }
   public Data GetData()
   {
    //return the data
   }
}

Assembly with UI: - both form and the controller types are declared here.

class Form : System.Windows.Forms.Form
{
 public void DisplayNotification(Data data)
 {
   //actual code here
 }
}

class Controller 
{
    private Form form;
    private MyCustomWatcher watcher;

    public void Init()
    {
      this.watcher = CreateWatcher();
      RegisterEvents();
      ShowForm();
    }
    void ShowForm()
    {
     //show
    }
    void RegisterEvents()
    {
        this.watcher.Event += HandleChange;
    }

    void HandleChange(object sender /*this will be the instance that raised the event*/, SomeEventArgs e)
    {
        //BTW: this.watcher == sender; //the same instance

        form.DisplayNotification(this.watcher.GetData());
    }
}

Assembly with UI references the assembly with logic. No circular dependency here.

Marek
Thanks for the example. I already realised your solution, but the problem lies, like before, in this line: this.watcher = CreateWatcher();How is it possible to create an instance of watcher, which is the same after I registered the evnet in RegisterEvents() and as I call watcher.RaiseEventForWhateverReason(). That is my main problem. Additionally the instances should be differentiated in any way because the watcher can receive many events in short time.
Kai Krupka
watcher is a field. You assign it and it will remain pointing to the same instance. As I have indicated in the sample, the sender parameter will be the instance that raised the event - you just need to cast it and assign to a local variable: Watcher theSender = (Watcher)sender. This will help you the if you have multiple instances.
Marek