How to find Class/Entity complete namespace where it is used in solution/source code with their line number

Saifullah 1 Reputation point
2020-11-27T06:33:32.153+00:00

Hi folks,
I hope you are doing well.

I want to write a program in C# that extract Class/Entity complete namespace where it is used in solution/source code with their line number

I do research from internet I have found some references but it can't me help.

Could anyone one suggest me how i do it or there is any nugget package available for it.

Thank you.

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,277 questions
.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,125 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Karen Payne MVP 35,036 Reputation points
    2020-12-01T01:16:32.737+00:00

    Hello @Saifullah ,

    The following repository contains code that may assist with this task. Code is broken between a windows form and class project. The frontend need not be windows forms, could be web or WPF etc.

    What it doesn't provide

    • Line numbers
    • Graphical representations
    • Does not cover all versions of Entity Framework.
    • No guarantees the presented code will be for you.

    What it does provide, an excellent foundation for getting started with many hidden gems if those interested take time to run the code under the debugger and examine what is available.

    Generics and asynchronous techniques are used.

    Here is an example for getting model names. A ListBox is populated with model names

    public static async Task<List<string>> GeModelNames<TContext>() where TContext : DbContext  
    {  
      
        return await Task.Run(async () =>  
        {  
            await Task.Delay(0);  
            ObjectContext objectContext;  
            using (TContext context = Activator.CreateInstance<TContext>())  
            {  
                objectContext = ((IObjectContextAdapter)context).ObjectContext;  
            }  
      
            var container = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace);  
      
            return container.EntitySets.Select(item => item.Name).OrderBy(x => x).ToList();  
      
        });  
      
    }  
    

    To get navigation properties for example, the code below does this by taking the selected text (model name) from the ListBox and converts the string to a type. Note here I used strings for namespace as the EF code is not in the same project.

    Type type = Type.GetType($"NorthWindForEntityFramework6.{ModelNamesListBox.Text}, NorthWindForEntityFramework6");  
    NavigationListBox.DataSource = EntityCrawler.GetNavigationProperties(type);  
    

    Which uses the following method to get the navigation properties or an empty array if there are none.

    public static string[] GetNavigationProperties(Type entityType)  
    {  
        return entityType.GetProperties()  
            .Where(p => (typeof(IEnumerable).IsAssignableFrom(p.PropertyType) && p.PropertyType != typeof(string)) || p.PropertyType.Namespace == entityType.Namespace)  
            .Select(p => p.Name)  
            .ToArray();  
    }  
    

    Then to get a twist, there is a similar method returning different details.

    public static ReadOnlyMetadataCollection<NavigationProperty> GetNavigationProperties<TEntity, TContext>() where TContext : DbContext  
    {  
        ObjectContext objectContext;  
      
        using (TContext context = Activator.CreateInstance<TContext>())  
        {  
            objectContext = ((IObjectContextAdapter)context).ObjectContext;  
        }  
      
        var container = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace);  
        var navigationProperties = ((EntityType)container.BaseEntitySets.First(bes => bes.ElementType.Name == typeof(TEntity).Name).ElementType).NavigationProperties;  
      
        return navigationProperties;  
    }  
    

    In closing, there is no one perfect solution is my guess and if there are third party libraries you can know that there is a great amount of time put into them.

    Hopefully you can find some use of the code in the repository.


  2. YASER SHADMEHR 781 Reputation points
    2020-12-03T02:10:29.513+00:00

    @Saifullah , I think the best solution for you it’s .Net Code Analysis (code name is Roslyn Analyzers). This tool generates a report that contains all information you need. The good thing about this tool is open source and written with C#.

    Step 1: Learning about the Metrics.exe

    I recommend before making your hand dirty with code, run this tool on one of your projects. By doing this, you will be familiar with this tool and end-result:

    1. Open your C# project by VS Community 2019
    2. Under the Analyze menu --> select Calculate Code Metrics --> For Solution
    3. When Report got generated, click on the Excel icon on the menu bar at top of the Code Metrics Results window.
    4. In the excel file, filter the scope column to Type.
    5. Then you will Line of Source Code and also Line of executable code. (See different here )

      Step 2: Build Metric.exe

      • Clone the dotnet/roslyn-analyzers repo.

        Note: If you don’t have any project with .Net5, I recommend using v3.3.1 branch. This branch is more stable now.

      • Open Solution RoslynAnalyzers.sln as administrator
      • Rebuild Tools\Metrics\ Metrics project.

        Note: roslyn-analyzers is a large project and to build the whole solution you need more configuration.

      • An executable named Metrics.exe is generated in the artifacts\bin\Metrics directory under the repo root.

        Step 3: Metrics.exe usage

    To run Metrics.exe, supply a project or solution and an output XML file as arguments. For example:

    C:\>"C:\roslyn-analyzers\artifacts\bin\Metrics\Debug\net472\Metrics.exe" /solution:"C:\ConsoleApp1\ConsoleApp1.sln" /out:"c:\\report.xml"  
    Loading ConsoleApp1.sln...  
    Computing code metrics for ConsoleApp1.sln...  
    Computing code metrics for ConsoleApp1.csproj...  
    Computing code metrics for WindowsFormsApp1.csproj...  
    Writing output to 'c:\\report.xml'...  
    Completed Successfully.  
    

    Step 4: Parsing XML Report

    Now, you can parse XML to get Line of Code and full type name of Class. For example:

     var filename = "C:\\report.xml";  
     var xml = new XmlDocument();  
     xml.Load(filename);  
    
    var locNodes = xml.SelectNodes("//NamedType/Metrics/Metric[@Name='SourceLines']");  
    foreach (XmlElement node in locNodes)  
    {  
        var typeElement = node.ParentNode.ParentNode as XmlElement;  
        var className = typeElement.GetAttribute("Name");  
        var namespaceElement = typeElement.ParentNode.ParentNode as XmlElement;  
        var nsName = namespaceElement.GetAttribute("Name");  
    
        var lineOfCode = node.GetAttribute("Value");  
        var fullTypeName = nsName + "." + className;  
     }  
    

    Now you need to integrate all steps in your application. Since you have Metrics.exe source code, I don't see any difficult part.

    Let me know in the comment if you have any questions. Mark this as resolve if this solution answers your question.