Private Void
Private Void

Reputation: 11

Software Design: DI - multiple assemblies + non public types

My first post here so hello all :)

I'm using stairway pattern e.g. I have Assembly A (entry point - composition root) which depends on Assembly B (containing interfaces) and Assembly C which contains implementations of interfaces defined in Assembly B:

A --> B <-- C

I'm developing in C# and I'm using Castle Windsor for IoC.

I'm also utilizing Windsor's ability to register non public types (https://github.com/castleproject/Windsor/blob/master/docs/registering-components-by-conventions.md -> Registering Non Public Types). I found it useful as I can define classes in assembly C to be internal which means that no one would create direct dependency on C from A. This way both A and C only depend on Assembly B which contains only abstractions which sounds right to me.

I'm wondering though if this is a good design choice. As far as I'm aware only Windsor allows to register non public types and they also warn to not expose non public types, hence my question. Also, I don't think this considerations is limited to .NET world so I'll appreciate insight into this problem regardless of technology you use :)

Upvotes: 1

Views: 156

Answers (1)

Steven
Steven

Reputation: 172666

Is there any reason to shield classes of C from accessing from the outside? This only makes sense when you have third parties use this assembly (i.e. you publish it as NuGet package for others to use). In case the only consumers of this library is inside your own team, hiding the internals only complicates things, because:

  • Testing becomes harder, because you will have to mark stuff with [InternalsVisibleTo].
  • Composition becomes harder, because you can reference your components directly from within your composition root. Referencing them directly is needed when you register them one by one, which is sometimes required, or you wish to new them up by hand instead of letting them auto-wire by the container.
  • Since the Composition Root (assembly A) is the only assembly who takes a dependency on assembly B, you are basically only hiding the dependencies from the composition root, which makes little sense, because by definition, the composition root depends on all assemblies in your application.

On the other hand, making classes internal makes a lot of sense from perspective of a reusable library. Take a look at the .NET framework itself and how much of it is internal. Making stuff internal makes it easier to change stuff without introducing breaking changes.

Upvotes: 1

Related Questions