Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
211 views
in Technique[技术] by (71.8m points)

c# - Can dependency injection prevent a circular dependency?

Project#1 has some interfaces and classes that project#2 references.

Now I want to use the implementation of Project#2 in Project#1 but vs.net complains about a circular dependency.

If I was to use dependancy injection in Project#1 and bind to the implementation in Project#2 (since it adheres to the interface contract), will this work or I will still get the circular dependency error message at runtime?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You probably could solve this with DI, but you shouldn't.

If I understand correctly, you have something like this:

  + Assembly A           + Assembly B
  |                      |
  +-- Interface IFoo     +-- Class ConcreteFoo : IFoo
  |                                   ^
  +-- Class MyClass -->------->-------|

In other words, you're trying to get MyClass to reference ConcreteFoo, but you can't because assembly B, which ConcreteFoo resides in, already depends on IFoo in A.

This is a design error. If you declare the interface IFoo in Assembly A, but no concrete implementations, then any other interfaces/classes in assembly A should only reference IFoo, never a concrete class that implements it.

There are three ways to eliminate the circular dependency:

  1. Make MyClass dependent on IFoo instead of ConcreteFoo. This is probably the best option if you can do it. If the issue is that you need a physical instance of IFoo for use in MyClass and don't know where to get one from, then have it take an IFoo in the constructor - let whoever uses MyClass figure out what IFoo to use.

  2. Move the interfaces to their own assembly. This is still a reasonably good practice. Your design will look like this:

      + Assembly App       + Assembly Interfaces      + Assembly Concrete
      |                    |                          |
      |                    +-- Interface IFoo         |
      |                    |                         |
      +-- Class MyClass    |                   ------+-- Class ConcreteFoo
      |                    |                          |           ^
      +---- Member Foo ->--------------------->-------------------|
    
  3. Move MyClass to its own assembly. Effectively your dependency tree will look the same as in #2 above, but if assembly A is much smaller than B then this would require less effort.

Hope that helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...