realvizu/NsDepCop

Enhanced wildcards to ensure modules segregation

molinch opened this issue · 4 comments

Given a solution like:

  • MyCompany.GeologyModule
  • MyCompany.HistoryModule

We would like to ensure that a given module never references another module.

We could have the rule implemented as:

<Disallowed From="MyCompany.*Module.*" To="MyCompany.*Module.*" ExceptFrom="!" />

Which would rely on 3 new features in NsDepCop:

  • the wildcard * within a namespace part, so that it means any number of any characters. Like: MyCompany.*Module to mean any direct subnamespaces of MyCompany ending with Module
  • the wildcard ! (or another if you have a better character in mind) which would mean the current assembly name.
  • the ExceptFrom keyword so we could have an exception for a given rule (potentially we could allow more than one ExceptFrom)

I would be happy to submit such a PR. What do you think about this idea?

I'd like to be careful with adding new features which may complicate the configs and which may have a performance impact, so let's discuss it a bit.
The default behavior (allowlisting) already denies different modules to reference each other, unless they are explicitly allowed. What is your approach (or existing config) that would make such a disallowed rule necessary?

Basically we follow deny listing rather than allow listing. The reason is that we only want to deny relationships between our assemblies. Anything coming from nuget, or the runtime, isn't of our concern.
Thus we have few rules which allow us to ensure that our architecture isn't misused.
This approach allows us to be very concise but also reuse the configuration for all our projects, since they all have the same architecture. The only thing we cannot do yet is guarantee that some projects aren't able to reference some other projects.

I see.
Regarding the "current assembly name wildcard": does it mean that assembly name must exactly match the root namespace name in that assembly, or do you have some other logic in mind? And I guess it should add a .* at the end of the namespace name to match all sub-namespaces too?
Regarding performance: do you have any concrete implementation idea in mind for efficiently matching a *Module-like pattern? Would it work only for a leading * wildcard in the name or could the * be anywhere in the name?

Thanks for your time and the feedback @realvizu. After working more with NsDepCop I realized that what we need is different so now we use an alternative which works fine for us so far.