Can dependency injection prevent a circular dependency?

后端 未结 3 488
无人及你
无人及你 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.

    0 讨论(0)
  • 2020-12-06 04:09

    You can often resolve circular dependency issues with Dependency Injection (DI) using an Abstract Factory. See here for an example.

    However, although you may be able to solve the problem with DI, it would be better to redesign the API to make the circular dependency go away.

    You can often break a circular dependency by changing one of the ends from a query-based API to an event-based API.

    0 讨论(0)
  • 2020-12-06 04:12

    As long as you are only using classes and interfaces from Project 1 in Project 1 code, you will be fine. (I'm assuming that the configuration for the dependency injection is done outside of the codebase of Project 1.)

    But I have to also say, the presence of any circular dependency should lead you to question why it exists, and prompt thought on other ways to solve the problem that removes it.

    0 讨论(0)
提交回复
热议问题