Open feO2x opened 3 weeks ago
Indeed it would be a useful feature, but a challenging one, because a namespace dependency cycle is a global feature of the codebase (project or solution), so we need to find all type/namespace dependencies, which is challenging both in terms of performance and also to implement it as a Roslyn analyzer.
See also issue #37 , where this feature was briefly discussed.
Your contribution would be more than welcome!
I would recommend an approach where the different challenges can be tackled step-by-step.
Implementing cycle detection as a standalone command line tool. 1.1 The tool's parameter would be a csproj or an sln file. 1.2 Using NsDepCop's ITypeDependencyEnumerator.GetTypeDependencies to find all type/namespace dependencies within a project. Calling it multiple times to handle a whole solution. 1.3 Using a graph library to build a graph of all dependencies, e.g.: https://www.nuget.org/packages/QuikGraph 1.4 Find a suitable cycle detection algorithm in the chosen graph library, or write our own, using eg. depth-first search. 1.5 Dumping all cycles to the output.
Implementing cycle detection as a Roslyn analyzer. 2.1 Either building it into NsDepCop, or as a standalone Nuget package. 2.2. Finding out how can we use the Roslyn analyzer hooks/callbacks to analyze a global feature of the codebase. 2.3. Caching and updating the dependency graph. 2.4 Reporting the found cycles as Roslyn Diagnostics.
Any thoughts on this approach?
Thank you for your insights. Indeed, my greatest concern regarding this task is the performance overhead, especially for projects that contain many namespaces. Of course, we should incorporate caching of namespace dependencies, but we might need to persist these at a certain threshold to not take up too much memory.
Maybe it's best if I start simple and make it a standalone command line tool first - it's easier to implement. I would then start benchmarking and see if I can integrate this algorithm as a Roslyn Analyzer and Code Fix. I'm currently working on another feature in another framework, so I'll probably start working on this in about 1 to 2 weeks. Will get back at you when I have something to share.
I just stumbled upon this project and really like what you have implemented so far. Great work!
I have a question: as far as I understand, there is currently no analyzer that is able to detect cyclic dependencies between namespaces, correct? When cleaning up projects, I often see that I cannot move parts of a code base easily to a reusable library project when there are cyclic dependencies between namespaces (I often have to untangle these by introducing new namespaces instead of just copying files of one namespace over to the library).
What do you think about detecting such cyclic dependencies between namespaces? Simple scenarios like N1 -> N2 and N2 -> N1 are trivial, but of course there could be transitive dependencies like N1 -> N2, N2 -> N3, and then N3 -> N1. Detecting these cycles might take some processing time and should be carefully crafted.
Anyway, I'm interested in your opinion on this? I would be happy to contribute this feature.