Question

Suppose that we have three layers; UI, Business, Data. We are using DI. I don't wan't Data layer to be accessible from UI.

enter image description here

The problem is about DI registration of Data layer. Composition root is in UI and I don't wan't to have any reference to Data there. I've found this answer. As I understand, we should reference to all layers and think they are libraries not layers. This way I can specify that my Business layer use Data layer or anything else that I want. After all this is why DI is around.

It's correct, but there is a problem! We shouldn't use Data layer at UI. But once a developer accidentally referenced from UI to Data, and another one injected something from Data layer to a UI class directly. So he skipped the Business layer that I never want.

How can I handle such situations? I'd like to have some limitations, but on the other hand I want the DI flexibility.

Of course some folks believe that we can have a separate library just for dependency registration.

enter image description here

What is the best pattern here?

Was it helpful?

Solution

The answer you linked to has two answers that explain that having the composition root and the UI layer in the same assembly is not a problem:

  • You're mistaking logical layers with physical boundaries: assemblies are deployment units and can contain multiple logical layers. Layers can even be spread across assemblies. Think about the 4+1 view. The composition root might be in the same assembly as your UI, but it is not in the UI layer and although the Composition Root depends on the Data Access Layer, the UI layer does not (although its assembly does).
  • Having code reviews is important for the quality or your software and the sharing of knowledge within the team. If you're not doing code reviews right now, you should definitely start doing them. Those code reviews can include checks for architectural guidelines, such as the rule you described in your question.
  • While assembly separation gives you compile-time support, most architectural rules can't be checked by the compiler. Besides, the compiler will not complain when a developer adds a reference to the DAL assembly. Developers will always find ways to break the rules. Again, code reviews help a lot. And additionally, as an architect, you can start using tools such as NDepend to automate verifying some architectural rules. But when you apply constructor injection, unit tests can be used as well, since dependencies can be found by simply reflecting over the constructors of types in your UI layer.

But if you think this is a problem, why don't you just move the UI layer in its own assembly? The startup assembly doesn't need to have the UI layer! If you create a Windows Forms application, move all the Forms to their own assembly. If you're creating a ASP.NET MVC application, move the Controllers and views to their own assembly. Depending on the type of application you're building, you will have to apply certain tricks to get this working, but for most project types in .NET this is possible.

The real question is, is this worth the trouble? If you want this in order to prevent having to do code reviews, you are fooling yourself.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top