Can dependency injection prevent a circular dependency?

后端 未结 3 490
无人及你
无人及你 2020-12-06 04:01

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 circ

3条回答
  •  一向
    一向 (楼主)
    2020-12-06 04:06

    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.

提交回复
热议问题