views:

190

answers:

4

Hello,

I was experimenting a little bit with Castle winforms in a winforms project. I wanted to register all my form dependencies with Castle windsor. This way I would have a single instance for all my forms. Now I have some problem though. I'm in a situation that form x has a dependency on form y and form y has a dependency on form x. Practical example maybe:

form x is used to create an order, form y is the screen that has a list of customers. From form x there is a button to select a customer for the order. This will open form y where ou can search the customer. There is a button that lets you add the found customer to the order. It will call a method on form x and passes the selected customer object. I could do this with events. Raise an event in form y and listen for that in form x. But isn't there a way around the circular dependency in Castle Windsor, lazy registration or something?

Can anyone help me out?

Thanks in advance

+1  A: 

You could use the EventWiring facility to break the tight coupling and route your events from one form to another.

Mauricio Scheffer
That is indeed a good way to route my events and not be tight coupled, don't know if I want to switch to eventing just yet. Is it a good architectural decision of using events in my scenario. Don't I end up with a lot of different events. If I would find a way to overcome my deadlock situation and would call a method like formX.AddCustomerToOrder(Customer C) I would be more tightly coupled again...
Sven
+1  A: 

I think that what you want is a forward reference to your form

Guessing by what you said, your project would not compile because of header precedence

How you write it exactly depends on your programming language

If your problem arise during runtime because of a null pointer reference, you can try to initialise every form during load, then wire everything and register to your for manager.

Eric
What do you mean with header precedence? Do you mean that if I register one component before another it would solve my issue. (because that's not working, tried it) Or do you mean register a certain form at a later point in time. If so, where and when would be the right place?
Sven
+3  A: 

Given it is very hard to look at a form class anyway and know how to call/use it; I think having an interface for each form may be helpful anyway. Or using factory methods to create/show/get_results for each form.

Using interfaces is afterall a normal way of coping with Circular dependencies.

Ian Ringrose
I don't fully understand what you mean. Are you suggesting using something like the MVP pattern or am I totally off? Thanks for replying
Sven
He is suggesting that instead of having FormA reference FromB, have FormA reference IFormB where IFormB contains only the methods and properties that you actually need.
George Mauer
+1  A: 

I did the following to solve my issue. Don't know if it can be seen as clean design. Can anyone give me comments on my method?

public static class FormManager
{
    private static IWindsorContainer container;
    public static void Init()
    {
        container = new WindsorContainer()
            .Install(Configuration.FromXmlFile("windsor.config"));

        IoC.Initialize(container);
    }

    public  static T GetInstance<T>()
    {
        return container.Resolve<T>();
    }
}

Now every form that needs a dependency on a form will get an instance like this:

FormManger.GetInstance<FormX>();

This solved my circular dependency issue.

Is this clean?

Sven
This seems to be alright. At least somebody, who seems to know what he is doing, does it the same way: http://tinyurl.com/ygd2wb5 (scroll down to "Service Locator / Facade").
dummy