Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect cyclic namespace dependencies #79

Open
feO2x opened this issue Oct 28, 2024 · 2 comments
Open

Detect cyclic namespace dependencies #79

feO2x opened this issue Oct 28, 2024 · 2 comments

Comments

@feO2x
Copy link

feO2x commented Oct 28, 2024

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.

@realvizu
Copy link
Owner

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.

  1. 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.

  2. 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?

@feO2x
Copy link
Author

feO2x commented Oct 31, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants