3

I am using unity in a Winforms app by injecting the dependency into the constructor of the form (I know this is not best practice) but it does work but I am getting a stackoverflowexception when I am trying to load the mdi form.

is there any way to trace what unity is trying to resolve and somehow find out what is happening?

I have a working example that I know works using this 'design'.

I know this is not an ideal design and I plan on introducing a Presenter down the line but for now this should work and I don't know why it is not

EDIT: I know I have services that reference each other for example

public class Service1(IService2, IService3, IService4):IService1

public class Service2(IService1, IService5):IService2

will this cause an exception?

EDIT2: yes I just created an quick app with this circular reference as listed in my first edit and I got a StackOverflowException - obviously not allowed.

1
  • "into the constructor of the form". This actually is the best practice. Ctor injection works fine in win forms and is ctor injection is best practice when it comes to dependency injection. Commented Oct 13, 2015 at 11:14

1 Answer 1

7

When you catch the exception in VS go inside it and follow InnerException. Unity should print all registered types and you can see which is missing.

Also look at stack trace. Usually StackOverflow appears when you have circular dependecies like this:

class A { A(B b) { ... } }
class B { B(A a) { ... } }

A depends on B and vice versa. Unity will try to inject in ctor of A a B instance but a B instance needs an A instance which, again, needs a B and so on.

This example is a trivial one but in real work the circularity is harder to spot as there might be a more complex graph of dependencies, between different libraries, like A -> B -> C -> D -> A (where "->" means "depends on").

EDIT Yes, that cross-references services can lead you to a stackoverflow exception if at the moment you're resolving IService1, IService1 itself is not registered yet;

Solution 1 You can bypass this problem if types registration and resolving happens in two steps (rough idea):

  1. Registration register both IService1 and its type and IService2 and its type. This step is doing only registration code and do not process any other things (UI, startup logic, unity resolving, http comms, etc).

  2. Actual application logic starts; now you can resolve anything.

Solution 2

Use empty ctors and doing the resolve inside Service class. You can use RegisterType method to specify that the empty ctor must be called:

container.RegisterType<IServiceProvider, ServiceContainer>(new InjectionConstructor());

Here are more details about circular references with dependency injection using Unity.

Solution 3

Use Lazy<IService> for resolving. Using this the actual resolving will happen on demand, more specific when the first time Lazy.Value property is called first time.

Sign up to request clarification or add additional context in comments.

4 Comments

see my edit..is that what you mean for inthat case I will then have circular refs
Edited with more comments and some possible solutions.
The URL to more info in solution2 is empty
@kurasa you're right, I edited the link again and it works now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.